taxtank-core 2.1.0 → 2.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4899,6 +4899,10 @@ var ServicePromoCodeDurationEnum;
4899
4899
  })(ServicePromoCodeDurationEnum || (ServicePromoCodeDurationEnum = {}));
4900
4900
 
4901
4901
  class ServicePromoCode extends AbstractModel {
4902
+ /**
4903
+ * default application discounts (depends on number of purchased tanks)
4904
+ */
4905
+ static { this.qtyIds = [200, 201, 202, 203]; }
4902
4906
  getProductsIds() {
4903
4907
  return this.products.map(product => product.id);
4904
4908
  }
@@ -4938,14 +4942,75 @@ __decorate([
4938
4942
  Type(() => ServiceProduct)
4939
4943
  ], ServicePromoCode.prototype, "products", void 0);
4940
4944
 
4945
+ /**
4946
+ * @TODO refactor with Map or Record
4947
+ * List of objects grouped by passed property
4948
+ */
4949
+ class Dictionary {
4950
+ constructor(items = [], path = 'id') {
4951
+ this.items = {};
4952
+ if (!items.length) {
4953
+ return;
4954
+ }
4955
+ this.groupItems(items, path);
4956
+ }
4957
+ add(key, value) {
4958
+ this.items[key] = value;
4959
+ return this;
4960
+ }
4961
+ get(key) {
4962
+ return this.items[key] !== undefined ? this.items[key] : null;
4963
+ }
4964
+ sum(keys) {
4965
+ return round(keys.reduce((sum, key) => sum + (+this.get(key)), 0), 2);
4966
+ }
4967
+ avg(keys) {
4968
+ return round(this.sum(keys) / keys.length, 2);
4969
+ }
4970
+ merge(dictionary) {
4971
+ Object.assign(this.items, dictionary.items);
4972
+ return this;
4973
+ }
4974
+ toArray() {
4975
+ return Object.values(this.items);
4976
+ }
4977
+ groupItems(items, path) {
4978
+ // Do nothing if provided path was not found in the 1st item
4979
+ if (!hasIn(items[0], path.split('.')[0])) {
4980
+ return;
4981
+ }
4982
+ items.forEach((item) => {
4983
+ let key = get(item, path);
4984
+ // if object does not have property for grouping it will be grouped as 'other'
4985
+ if (key === undefined) {
4986
+ key = 'other';
4987
+ }
4988
+ this.items[key] = item;
4989
+ });
4990
+ }
4991
+ get keys() {
4992
+ return Object.keys(this.items);
4993
+ }
4994
+ get length() {
4995
+ return this.keys.length;
4996
+ }
4997
+ }
4998
+
4941
4999
  class ServiceSubscription extends ServiceSubscription$1 {
4942
5000
  constructor() {
4943
5001
  super(...arguments);
4944
5002
  this.items = [];
5003
+ this.promoCodes = [];
4945
5004
  }
4946
5005
  get promoCodeId() {
4947
5006
  return this.promoCode?.id || null;
4948
5007
  }
5008
+ /**
5009
+ * @TODO Vik rename to userPromoCode?
5010
+ */
5011
+ get promoCode() {
5012
+ return this.promoCodes.find(promoCode => !ServicePromoCode.qtyIds.includes(promoCode.id)) ?? null;
5013
+ }
4949
5014
  get frequency() {
4950
5015
  return this.isAnnual() ? 'year' : 'month';
4951
5016
  }
@@ -4958,21 +5023,47 @@ class ServiceSubscription extends ServiceSubscription$1 {
4958
5023
  get initialPrice() {
4959
5024
  return this.items.reduce((sum, item) => sum + item.total, 0);
4960
5025
  }
5026
+ getDiscountPriceByProduct(prices) {
5027
+ // quantity discount
5028
+ const qtyRatio = 1 - PRODUCT_QUANTITY_DISCOUNT_PERCENT[this.items.length] / 100;
5029
+ const priceByProduct = new Dictionary([]);
5030
+ prices.forEach(price => {
5031
+ priceByProduct.add(price.product.id, price.amount * qtyRatio);
5032
+ });
5033
+ if (!this.promoCode || this.promoCode.amountOff) {
5034
+ return priceByProduct;
5035
+ }
5036
+ // promo discount
5037
+ const promoRatio = 1 - (this.promoCode.percentOff) / 100;
5038
+ if (this.promoCode.products.length) {
5039
+ prices = prices.filter(price => this.promoCode.getProductsIds().includes(price.product.id));
5040
+ }
5041
+ prices.forEach(price => {
5042
+ priceByProduct.items[price.product.id] *= promoRatio;
5043
+ });
5044
+ return priceByProduct;
5045
+ }
4961
5046
  get discountAmount() {
5047
+ // quantity discount
5048
+ const qtyPercent = PRODUCT_QUANTITY_DISCOUNT_PERCENT[this.items.length] / 100;
5049
+ const qtyDiscount = this.initialPrice * qtyPercent;
4962
5050
  if (!this.promoCode) {
4963
- return this.initialPrice * PRODUCT_QUANTITY_DISCOUNT_PERCENT[this.items.length] / 100;
5051
+ return qtyDiscount;
4964
5052
  }
4965
- let discountApplicable = this.initialPrice;
5053
+ // promo applicable price
5054
+ let promoApplicable = this.initialPrice;
4966
5055
  if (this.promoCode.products.length) {
4967
- discountApplicable = this.items
5056
+ promoApplicable = this.items
4968
5057
  .map(item => item.price)
4969
5058
  .filter(price => this.promoCode.getProductsIds().includes(price.product.id))
4970
5059
  .reduce((sum, price) => sum + price.amount, 0);
4971
5060
  }
4972
- if (this.promoCode.amountOff) {
4973
- return Math.min(discountApplicable, this.promoCode.amountOff);
4974
- }
4975
- return discountApplicable * (this.promoCode.percentOff / 100);
5061
+ promoApplicable *= (1 - qtyPercent);
5062
+ // promo discount
5063
+ const promoDiscount = this.promoCode.amountOff
5064
+ ? Math.min(promoApplicable, this.promoCode.amountOff)
5065
+ : promoApplicable * (this.promoCode.percentOff / 100);
5066
+ return qtyDiscount + promoDiscount;
4976
5067
  }
4977
5068
  get price() {
4978
5069
  return this.initialPrice - this.discountAmount;
@@ -5013,7 +5104,7 @@ class ServiceSubscription extends ServiceSubscription$1 {
5013
5104
  return this.items.find((item) => item.price.product.isProperties());
5014
5105
  }
5015
5106
  hasPropertyTank() {
5016
- return !!this.items.find((subscriptionItem) => subscriptionItem.price.product.role.includes(UserRolesEnum$1.PROPERTY_TANK));
5107
+ return !!this.items.find(item => [ServiceProductIdEnum.PROPERTY_OLD, ServiceProductIdEnum.PROPERTIES].includes(item.price.product.id));
5017
5108
  }
5018
5109
  hasWorkTank() {
5019
5110
  return !!this.items.find((subscriptionItem) => subscriptionItem.price.product.role.includes(UserRolesEnum$1.WORK_TANK));
@@ -5068,11 +5159,11 @@ class ServiceSubscription extends ServiceSubscription$1 {
5068
5159
  * apply promocode if applicable
5069
5160
  */
5070
5161
  applyPromoCode(promoCode) {
5071
- this.promoCode = null;
5162
+ this.promoCodes = [];
5072
5163
  if (this.isAnnual() && !promoCode?.isAnnualApplicable()) {
5073
5164
  return false;
5074
5165
  }
5075
- this.promoCode = promoCode;
5166
+ this.promoCodes.push(promoCode);
5076
5167
  return true;
5077
5168
  }
5078
5169
  }
@@ -5090,7 +5181,7 @@ __decorate([
5090
5181
  ], ServiceSubscription.prototype, "items", void 0);
5091
5182
  __decorate([
5092
5183
  Type(() => ServicePromoCode)
5093
- ], ServiceSubscription.prototype, "promoCode", void 0);
5184
+ ], ServiceSubscription.prototype, "promoCodes", void 0);
5094
5185
  __decorate([
5095
5186
  Expose()
5096
5187
  ], ServiceSubscription.prototype, "promoCodeId", null);
@@ -11146,60 +11237,6 @@ __decorate([
11146
11237
  Expose()
11147
11238
  ], Message.prototype, "documents", void 0);
11148
11239
 
11149
- /**
11150
- * @TODO refactor with Map or Record
11151
- * List of objects grouped by passed property
11152
- */
11153
- class Dictionary {
11154
- constructor(items = [], path = 'id') {
11155
- this.items = {};
11156
- if (!items.length) {
11157
- return;
11158
- }
11159
- this.groupItems(items, path);
11160
- }
11161
- add(key, value) {
11162
- this.items[key] = value;
11163
- return this;
11164
- }
11165
- get(key) {
11166
- return this.items[key] !== undefined ? this.items[key] : null;
11167
- }
11168
- sum(keys) {
11169
- return round(keys.reduce((sum, key) => sum + (+this.get(key)), 0), 2);
11170
- }
11171
- avg(keys) {
11172
- return round(this.sum(keys) / keys.length, 2);
11173
- }
11174
- merge(dictionary) {
11175
- Object.assign(this.items, dictionary.items);
11176
- return this;
11177
- }
11178
- toArray() {
11179
- return Object.values(this.items);
11180
- }
11181
- groupItems(items, path) {
11182
- // Do nothing if provided path was not found in the 1st item
11183
- if (!hasIn(items[0], path.split('.')[0])) {
11184
- return;
11185
- }
11186
- items.forEach((item) => {
11187
- let key = get(item, path);
11188
- // if object does not have property for grouping it will be grouped as 'other'
11189
- if (key === undefined) {
11190
- key = 'other';
11191
- }
11192
- this.items[key] = item;
11193
- });
11194
- }
11195
- get keys() {
11196
- return Object.keys(this.items);
11197
- }
11198
- get length() {
11199
- return this.keys.length;
11200
- }
11201
- }
11202
-
11203
11240
  /**
11204
11241
  * @TODO Alex remove
11205
11242
  */