@snabcentr/client-core 2.65.3 → 2.66.1

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.
Files changed (143) hide show
  1. package/banners/dto/sc-banner.d.ts +2 -2
  2. package/cart/classes/index.d.ts +1 -0
  3. package/cart/{dto → classes}/sc-cart.d.ts +7 -7
  4. package/cart/classes/sc-sum.d.ts +1 -1
  5. package/cart/index.d.ts +0 -1
  6. package/cart/internal/index.d.ts +1 -2
  7. package/cart/internal/{sc-i-cart-dto.d.ts → sc-i-cart.d.ts} +4 -6
  8. package/cart/services/sc-cart.service.d.ts +32 -30
  9. package/catalog/classes/sc-cached-item.d.ts +25 -5
  10. package/catalog/dto/sc-product.d.ts +2 -2
  11. package/catalog/interfaces/sc-i-category-product-params.d.ts +2 -10
  12. package/catalog/interfaces/sc-property-filters.d.ts +2 -4
  13. package/config/sc-route-keys.d.ts +122 -2
  14. package/esm2022/banners/dto/sc-banner.mjs +12 -12
  15. package/esm2022/cart/classes/index.mjs +2 -1
  16. package/esm2022/cart/classes/sc-cart.mjs +18 -0
  17. package/esm2022/cart/classes/sc-sum.mjs +2 -2
  18. package/esm2022/cart/index.mjs +1 -2
  19. package/esm2022/cart/internal/index.mjs +2 -3
  20. package/esm2022/cart/internal/sc-i-cart.mjs +2 -0
  21. package/esm2022/cart/services/sc-cart.service.mjs +50 -52
  22. package/esm2022/catalog/classes/sc-cached-item.mjs +31 -6
  23. package/esm2022/catalog/dto/sc-product.mjs +1 -1
  24. package/esm2022/catalog/interfaces/sc-i-category-product-params.mjs +1 -1
  25. package/esm2022/catalog/interfaces/sc-property-filters.mjs +1 -1
  26. package/esm2022/catalog/services/sc-catalog.service.mjs +6 -6
  27. package/esm2022/catalog/services/sc-recommendation.service.mjs +8 -7
  28. package/esm2022/config/sc-route-keys.mjs +122 -2
  29. package/esm2022/contragent/services/sc-contragent.service.mjs +3 -3
  30. package/esm2022/delivery-address/services/sc-delivery-address.service.mjs +4 -2
  31. package/esm2022/order/classes/index.mjs +11 -0
  32. package/esm2022/order/classes/sc-delivery-cost.mjs +19 -0
  33. package/esm2022/order/classes/sc-order-base.mjs +28 -0
  34. package/esm2022/order/classes/sc-order-delivery.mjs +2 -0
  35. package/esm2022/order/classes/sc-order-draft-short.mjs +17 -0
  36. package/esm2022/order/classes/sc-order-draft.mjs +59 -0
  37. package/esm2022/order/classes/sc-order-history.mjs +2 -0
  38. package/esm2022/order/classes/sc-order-item.mjs +60 -0
  39. package/esm2022/order/classes/sc-order-payment.mjs +2 -0
  40. package/esm2022/order/classes/sc-order-short.mjs +30 -0
  41. package/esm2022/order/classes/sc-order.mjs +100 -0
  42. package/esm2022/order/enums/index.mjs +2 -1
  43. package/esm2022/order/enums/sc-order-draft-type.mjs +16 -0
  44. package/esm2022/order/index.mjs +5 -3
  45. package/esm2022/order/internal/index.mjs +14 -3
  46. package/esm2022/order/internal/sc-i-delivery-cost-dto.mjs +1 -1
  47. package/esm2022/order/internal/sc-i-new-order-draft-request.mjs +2 -0
  48. package/esm2022/order/internal/sc-i-new-order-item-base.mjs +2 -0
  49. package/esm2022/order/internal/sc-i-new-order-item-measured.mjs +2 -0
  50. package/esm2022/order/internal/sc-i-new-order.mjs +2 -0
  51. package/esm2022/order/internal/sc-i-order-base.mjs +2 -0
  52. package/esm2022/order/internal/sc-i-order-draft-list-params.mjs +2 -0
  53. package/esm2022/order/internal/sc-i-order-draft-short.mjs +2 -0
  54. package/esm2022/order/internal/sc-i-order-draft.mjs +2 -0
  55. package/esm2022/order/internal/sc-i-order-item.mjs +2 -0
  56. package/esm2022/order/internal/sc-i-order-loader.mjs +2 -0
  57. package/esm2022/order/internal/sc-i-order-short.mjs +2 -0
  58. package/esm2022/order/internal/sc-i-order.mjs +2 -0
  59. package/esm2022/order/internal/sc-i-update-order-order-request.mjs +2 -0
  60. package/esm2022/order/services/index.mjs +3 -0
  61. package/esm2022/order/services/sc-order-drafts.service.mjs +195 -0
  62. package/esm2022/order/services/sc-orders.service.mjs +33 -54
  63. package/esm2022/order/tokens/index.mjs +2 -0
  64. package/esm2022/order/tokens/sc-order-loader.token.mjs +25 -0
  65. package/esm2022/pagination/dto/index.mjs +3 -1
  66. package/esm2022/pagination/dto/sc-i-range-filter.mjs +2 -0
  67. package/esm2022/pagination/dto/sc-i-sort-order.mjs +2 -0
  68. package/esm2022/reclamation/interfaces/sc-i-pagination-params.mjs +1 -1
  69. package/esm2022/references/enums/sc-order-state-status.mjs +1 -5
  70. package/esm2022/ui/services/sc-ui.service.mjs +1 -1
  71. package/esm2022/user/dto/sc-user-metadata.mjs +1 -1
  72. package/esm2022/user-metrika/enums/sc-user-metrika-goals-enum.mjs +27 -1
  73. package/fesm2022/snabcentr-client-core.mjs +1129 -735
  74. package/fesm2022/snabcentr-client-core.mjs.map +1 -1
  75. package/order/{dto → classes}/index.d.ts +5 -3
  76. package/order/{dto → classes}/sc-delivery-cost.d.ts +2 -2
  77. package/order/classes/sc-order-base.d.ts +32 -0
  78. package/order/classes/sc-order-draft-short.d.ts +22 -0
  79. package/order/classes/sc-order-draft.d.ts +63 -0
  80. package/order/{dto → classes}/sc-order-history.d.ts +1 -1
  81. package/order/classes/sc-order-item.d.ts +98 -0
  82. package/order/{dto → classes}/sc-order-payment.d.ts +1 -1
  83. package/order/classes/sc-order-short.d.ts +44 -0
  84. package/order/classes/sc-order.d.ts +102 -0
  85. package/order/enums/index.d.ts +1 -0
  86. package/order/enums/sc-order-draft-type.d.ts +13 -0
  87. package/order/index.d.ts +4 -2
  88. package/order/internal/index.d.ts +13 -2
  89. package/order/internal/sc-i-delivery-cost-dto.d.ts +1 -1
  90. package/order/internal/sc-i-new-order-draft-request.d.ts +13 -0
  91. package/{cart/dto/sc-i-new-cart-item-base.d.ts → order/internal/sc-i-new-order-item-base.d.ts} +2 -2
  92. package/order/internal/sc-i-new-order-item-measured.d.ts +10 -0
  93. package/order/{dto → internal}/sc-i-new-order.d.ts +1 -5
  94. package/order/internal/sc-i-order-base.d.ts +25 -0
  95. package/order/internal/sc-i-order-draft-list-params.d.ts +32 -0
  96. package/order/internal/sc-i-order-draft-short.d.ts +15 -0
  97. package/order/internal/sc-i-order-draft.d.ts +43 -0
  98. package/{cart/dto/sc-cart-item.d.ts → order/internal/sc-i-order-item.d.ts} +6 -13
  99. package/order/internal/sc-i-order-loader.d.ts +51 -0
  100. package/order/internal/{sc-i-order-short-dto.d.ts → sc-i-order-short.d.ts} +14 -16
  101. package/order/{dto/sc-order.d.ts → internal/sc-i-order.d.ts} +15 -67
  102. package/order/internal/sc-i-update-order-order-request.d.ts +9 -0
  103. package/order/services/index.d.ts +2 -0
  104. package/order/services/sc-order-drafts.service.d.ts +118 -0
  105. package/order/services/sc-orders.service.d.ts +19 -20
  106. package/order/tokens/index.d.ts +1 -0
  107. package/order/tokens/sc-order-loader.token.d.ts +26 -0
  108. package/package.json +1 -1
  109. package/pagination/dto/index.d.ts +2 -0
  110. package/pagination/dto/sc-i-range-filter.d.ts +15 -0
  111. package/pagination/dto/sc-i-sort-order.d.ts +15 -0
  112. package/reclamation/interfaces/sc-i-pagination-params.d.ts +3 -21
  113. package/references/enums/sc-order-state-status.d.ts +0 -4
  114. package/ui/services/sc-ui.service.d.ts +1 -1
  115. package/user/dto/sc-user-metadata.d.ts +1 -1
  116. package/user-metrika/enums/sc-user-metrika-goals-enum.d.ts +26 -0
  117. package/cart/dto/index.d.ts +0 -5
  118. package/cart/dto/sc-i-new-cart-item-measured.d.ts +0 -10
  119. package/cart/dto/sc-i-sales-direction-cart.d.ts +0 -37
  120. package/cart/internal/sc-i-cart-item-dto.d.ts +0 -73
  121. package/esm2022/cart/dto/index.mjs +0 -6
  122. package/esm2022/cart/dto/sc-cart-item.mjs +0 -60
  123. package/esm2022/cart/dto/sc-cart.mjs +0 -18
  124. package/esm2022/cart/dto/sc-i-new-cart-item-base.mjs +0 -2
  125. package/esm2022/cart/dto/sc-i-new-cart-item-measured.mjs +0 -2
  126. package/esm2022/cart/dto/sc-i-sales-direction-cart.mjs +0 -21
  127. package/esm2022/cart/internal/sc-i-cart-dto.mjs +0 -2
  128. package/esm2022/cart/internal/sc-i-cart-item-dto.mjs +0 -2
  129. package/esm2022/order/dto/index.mjs +0 -9
  130. package/esm2022/order/dto/sc-delivery-cost.mjs +0 -19
  131. package/esm2022/order/dto/sc-i-new-order-from-draft.mjs +0 -2
  132. package/esm2022/order/dto/sc-i-new-order.mjs +0 -2
  133. package/esm2022/order/dto/sc-order-delivery.mjs +0 -2
  134. package/esm2022/order/dto/sc-order-history.mjs +0 -2
  135. package/esm2022/order/dto/sc-order-payment.mjs +0 -2
  136. package/esm2022/order/dto/sc-order-short.mjs +0 -46
  137. package/esm2022/order/dto/sc-order.mjs +0 -134
  138. package/esm2022/order/internal/sc-i-order-dto.mjs +0 -2
  139. package/esm2022/order/internal/sc-i-order-short-dto.mjs +0 -2
  140. package/order/dto/sc-i-new-order-from-draft.d.ts +0 -10
  141. package/order/dto/sc-order-short.d.ts +0 -65
  142. package/order/internal/sc-i-order-dto.d.ts +0 -94
  143. /package/order/{dto → classes}/sc-order-delivery.d.ts +0 -0
@@ -1,11 +1,11 @@
1
1
  import { parseISO, parse, isValid, format } from 'date-fns';
2
- import { isString, isMatch, isArray } from 'lodash-es';
2
+ import { isString, isNil, isMatch, isArray } from 'lodash-es';
3
3
  import * as i0 from '@angular/core';
4
4
  import { InjectionToken, inject, PLATFORM_ID, Injectable, Inject, Optional, EventEmitter, LOCALE_ID, Pipe, RendererFactory2 } from '@angular/core';
5
5
  import { WA_LOCAL_STORAGE, WA_USER_AGENT, WA_WINDOW } from '@ng-web-apis/common';
6
6
  import { filterByKey, toValue, WA_STORAGE_EVENT, StorageService } from '@ng-web-apis/storage';
7
7
  import * as i1 from 'rxjs';
8
- import { startWith, Subject, ReplaySubject, partition, combineLatest, map, debounceTime, switchMap, of, tap, filter, shareReplay, distinctUntilChanged, distinctUntilKeyChanged, skip, first, BehaviorSubject, materialize, dematerialize, expand, takeWhile, toArray, catchError, EMPTY, throwError, concatMap, finalize, takeUntil, interval, share, scan } from 'rxjs';
8
+ import { startWith, Subject, ReplaySubject, partition, combineLatest, map, debounceTime, switchMap, of, tap, filter, shareReplay, distinctUntilChanged, BehaviorSubject, materialize, dematerialize, merge, distinctUntilKeyChanged, skip, first, expand, takeWhile, toArray, catchError, EMPTY, throwError, concatMap, finalize, takeUntil, interval, share, scan } from 'rxjs';
9
9
  import { isPlatformBrowser, isPlatformServer, DOCUMENT, formatDate } from '@angular/common';
10
10
  import * as i1$1 from '@angular/common/http';
11
11
  import { HttpContextToken, HttpContext, HttpHeaders, HttpClient, HttpParams, HttpErrorResponse, HttpResponse } from '@angular/common/http';
@@ -615,6 +615,10 @@ var ScUserMetrikaGoalsEnum;
615
615
  * Открыто диалоговое окно/страница с уведомлениями.
616
616
  */
617
617
  ScUserMetrikaGoalsEnum["notificationsShow"] = "NOTIFICATIONS_SHOW";
618
+ /**
619
+ * Открыто диалоговое окно/страница заказа.
620
+ */
621
+ ScUserMetrikaGoalsEnum["orderShow"] = "ORDER_SHOW";
618
622
  /**
619
623
  * Заказ отменён.
620
624
  *
@@ -656,6 +660,28 @@ var ScUserMetrikaGoalsEnum;
656
660
  * - стоимость заказа (параметр "cost").
657
661
  */
658
662
  ScUserMetrikaGoalsEnum["orderDeleted"] = "ORDER_DELETED";
663
+ /**
664
+ * Открыто диалоговое окно/страница черновика заказа.
665
+ */
666
+ ScUserMetrikaGoalsEnum["orderDraftShow"] = "ORDER_DRAFT_SHOW";
667
+ /**
668
+ * Коммерческое предложение/черновик заказа создано.
669
+ *
670
+ * В качестве параметра должен быть указан идентификатор КП/черновика (параметр "offer_id").
671
+ */
672
+ ScUserMetrikaGoalsEnum["orderDraftCreated"] = "ORDER_DRAFT_CREATED";
673
+ /**
674
+ * Коммерческое предложение/черновик заказа обновлено.
675
+ *
676
+ * В качестве параметра должен быть указан идентификатор КП/черновика (параметр "offer_id").
677
+ */
678
+ ScUserMetrikaGoalsEnum["orderDraftUpdated"] = "ORDER_DRAFT_UPDATED";
679
+ /**
680
+ * Коммерческое предложение/черновик заказа удалено.
681
+ *
682
+ * В качестве параметра должен быть указан идентификатор КП/черновика (параметр "offer_id").
683
+ */
684
+ ScUserMetrikaGoalsEnum["orderDraftDeleted"] = "ORDER_DRAFT_DELETED";
659
685
  /**
660
686
  * Открыто диалоговое окно/страница конфигуратора товара.
661
687
  *
@@ -1071,18 +1097,18 @@ class ScBanner {
1071
1097
  /**
1072
1098
  * Инициализирует экземпляр класса {@link ScBanner}.
1073
1099
  *
1074
- * @param bannerDTO Данные для инициализации.
1100
+ * @param data Данные для инициализации.
1075
1101
  */
1076
- constructor(bannerDTO) {
1077
- this.id = bannerDTO.id;
1078
- this.location = bannerDTO.location;
1079
- this.mediaType = bannerDTO.mediaType;
1080
- this.mediaFile = bannerDTO.mediaFile;
1081
- this.mediaFileWebp = bannerDTO.mediaFileWebp;
1082
- this.title = bannerDTO.title;
1083
- this.url = bannerDTO.url;
1084
- this.width = bannerDTO.width;
1085
- this.height = bannerDTO.height;
1102
+ constructor(data) {
1103
+ this.id = data.id;
1104
+ this.location = data.location;
1105
+ this.mediaType = data.mediaType;
1106
+ this.mediaFile = data.mediaFile;
1107
+ this.mediaFileWebp = data.mediaFileWebp;
1108
+ this.title = data.title;
1109
+ this.url = data.url;
1110
+ this.width = data.width;
1111
+ this.height = data.height;
1086
1112
  }
1087
1113
  /**
1088
1114
  * Возвращает признак того, что баннер является изображением.
@@ -1385,7 +1411,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1385
1411
  const EMPTY_CART = { items: [], result_sum: { rub: 0 }, directions_sum: {} };
1386
1412
 
1387
1413
  /**
1388
- * Модель данных итоговой суммы.
1414
+ * Данные об итоговой сумме.
1389
1415
  */
1390
1416
  class ScSum {
1391
1417
  /**
@@ -1752,58 +1778,58 @@ class ScProduct extends ScCatalogItem {
1752
1778
  }
1753
1779
 
1754
1780
  /**
1755
- * Единичная позиция товара/услуги в корзине.
1781
+ * Данные о единичной позиции товара/услуги в заказе (корзине / черновике).
1756
1782
  */
1757
- class ScCartItem {
1783
+ class ScOrderItem {
1758
1784
  /**
1759
- * Инициализирует экземпляр класса {@link ScCartItem}.
1785
+ * Инициализирует экземпляр класса {@link ScOrderItem}.
1760
1786
  *
1761
- * @param cartItemDTO DTO единичной позиции товара/услуги в корзине.
1787
+ * @param data Данные для первоначальной инициализации.
1762
1788
  */
1763
- constructor(cartItemDTO) {
1764
- this.id = cartItemDTO.id;
1765
- this.product = new ScProduct(cartItemDTO.product);
1766
- this.quantity = cartItemDTO.quantity;
1767
- this.cost = cartItemDTO.cost;
1768
- this.costOne = cartItemDTO.costOne;
1769
- this.costRub = cartItemDTO.costRub;
1770
- this.costOneRub = cartItemDTO.costOneRub;
1771
- this.marker = cartItemDTO.marker;
1772
- this.height = cartItemDTO.height;
1773
- this.length = cartItemDTO.length;
1774
- this.width = cartItemDTO.width;
1775
- this.logicGroupId = cartItemDTO.logicGroupId;
1776
- this.salesDirection = cartItemDTO.salesDirection;
1777
- this.specificationImgUrl = cartItemDTO.specificationImgUrl;
1778
- this.configurator = cartItemDTO.configurator;
1779
- this.configuratorParams = cartItemDTO.configuratorParams;
1780
- }
1781
- /**
1782
- * Возвращает стоимость единицы товара (включая валюту). Если стоимость отсутствует, то вернёт '-'.
1789
+ constructor(data) {
1790
+ this.id = data.id;
1791
+ this.product = new ScProduct(data.product);
1792
+ this.quantity = data.quantity;
1793
+ this.cost = data.cost;
1794
+ this.costOne = data.costOne;
1795
+ this.costRub = data.costRub;
1796
+ this.costOneRub = data.costOneRub;
1797
+ this.marker = data.marker;
1798
+ this.height = data.height;
1799
+ this.length = data.length;
1800
+ this.width = data.width;
1801
+ this.logicGroupId = data.logicGroupId;
1802
+ this.salesDirection = data.salesDirection;
1803
+ this.specificationImgUrl = data.specificationImgUrl;
1804
+ this.configurator = data.configurator;
1805
+ this.configuratorParams = data.configuratorParams;
1806
+ }
1807
+ /**
1808
+ * @inheritDoc
1783
1809
  */
1784
1810
  getCostPerItem() {
1785
1811
  return this.costOne > 0 ? `${this.costOne.toLocaleString()} ${this.product.currency.symbol}` : '-';
1786
1812
  }
1787
1813
  /**
1788
- * Возвращает строковое представление стоимости единицы товара (включая единицу измерения) в валюте. Если стоимость отсутствует, то вернёт '-'.
1814
+ * @inheritDoc
1789
1815
  */
1790
1816
  getCostInCurrencyDescPerItem() {
1791
1817
  return this.costOne > 0 ? `${this.costOne.toLocaleString()} ${this.product.currency.symbol} / ${this.product.unit.name}` : '-';
1792
1818
  }
1793
1819
  /**
1794
- * Возвращает строковое представление стоимости единицы товара (включая единицу измерения) в рублях. Если стоимость отсутствует, то вернёт '-'.
1820
+ * @inheritDoc
1795
1821
  */
1796
1822
  getCostInRubDescPerItem() {
1797
1823
  return this.costOneRub > 0 ? `${this.costOneRub.toLocaleString()} ₽ / ${this.product.unit.name}` : '-';
1798
1824
  }
1799
1825
  /**
1800
- * Возвращает стоимость товара в виде строки. Если стоимость отсутствует, то вернёт '-'.
1826
+ * @inheritDoc
1801
1827
  */
1802
1828
  getCostRubStr() {
1803
1829
  return this.costRub > 0 ? `${this.costRub.toLocaleString()} ₽` : '-';
1804
1830
  }
1805
1831
  /**
1806
- * Возвращает сообщение о необходимости уточнить цену или пустую строку.
1832
+ * @inheritDoc
1807
1833
  */
1808
1834
  getCostMessage() {
1809
1835
  return this.costRub === 0 ? 'Цена требует уточнения' : '';
@@ -1811,174 +1837,103 @@ class ScCartItem {
1811
1837
  }
1812
1838
 
1813
1839
  /**
1814
- * Модель данных информация о содержимом корзины.
1840
+ * Данные о содержимом корзины.
1815
1841
  */
1816
1842
  class ScCart {
1817
1843
  /**
1818
1844
  * Инициализирует экземпляр класса {@link ScCart}.
1819
1845
  *
1820
- * @param cartDTO DTO с информацией о содержимом корзины.
1846
+ * @param data Данные для первоначальной инициализации.
1821
1847
  */
1822
1848
  // eslint-disable-next-line unicorn/no-object-as-default-parameter
1823
- constructor(cartDTO = { items: [], resultSum: { rub: 0 }, directionsSum: {} }) {
1824
- this.items = cartDTO.items.map((item) => new ScCartItem(item));
1825
- this.resultSum = cartDTO.resultSum;
1826
- this.directionsSum = cartDTO.directionsSum;
1827
- }
1828
- }
1829
-
1830
- /**
1831
- * Корзина по направлению продаж.
1832
- */
1833
- class ScISalesDirectionCart {
1834
- /**
1835
- * Инициализирует экземпляр класса {@link ScISalesDirectionCart}.
1836
- *
1837
- * @param salesDirection Данные о направлении продаж.
1838
- * @param items Список позиций товаров/услуг в корзине.
1839
- * @param directionSum Данные итоговой суммы.
1840
- * @param warehouseId Идентификатор выбранного склада.
1841
- */
1842
- constructor(salesDirection, items, directionSum, warehouseId) {
1843
- this.salesDirection = salesDirection;
1844
- this.items = items.filter((item) => item.product.isWarehouseStockExist(warehouseId) && !item.product.onOrder);
1845
- this.itemsOnOrder = items.filter((item) => item.product.onOrder);
1846
- this.itemsNotInWarehouseStock = items.filter((item) => !item.product.isWarehouseStockExist(warehouseId) && !item.product.onOrder);
1847
- this.directionSum = directionSum;
1849
+ constructor(data = { items: [], resultSum: { rub: 0 }, directionsSum: {} }) {
1850
+ this.items = data.items.map((item) => new ScOrderItem(item));
1851
+ this.resultSum = data.resultSum;
1852
+ this.directionsSum = data.directionsSum;
1848
1853
  }
1849
1854
  }
1850
1855
 
1851
- /* eslint-disable security/detect-object-injection,no-param-reassign */
1852
1856
  /**
1853
- * Сервис конвертации данных.
1857
+ * Модель кэшированных данных.
1854
1858
  */
1855
- class ScConvertersService {
1856
- /**
1857
- * Инициализирует экземпляр класса {@link ScConvertersService}.
1858
- *
1859
- * @param locale Язык приложения из поставщика.
1860
- */
1861
- constructor(locale) {
1862
- this.locale = locale;
1863
- }
1864
- /**
1865
- * Конвертирует объект в {@link HttpParams}.
1866
- *
1867
- * @param object Объект, которые нужно перевести в {@link HttpParams}.
1868
- * @param options Параметры конвертации объекта.
1869
- */
1870
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1871
- toHttpParams(object, options) {
1872
- object = this.toSimpleObjectRecursive(object);
1873
- object = this.convertDateToString(object);
1874
- if (options?.nonNullable) {
1875
- object = tuiCleanObject(object);
1876
- }
1877
- if (options?.minLength) {
1878
- object = this.removeByStrLength(object, options.minLength);
1879
- }
1880
- return new HttpParams().appendAll(object);
1881
- }
1859
+ class ScCachedItem {
1882
1860
  /**
1883
- * Возвращает {@link T} объект из которого удалены свойства со значением null.
1861
+ * Инициализирует экземпляр класса {@link ScCachedItem}.
1884
1862
  *
1885
- * @param object Объект, в котором необходимо удалить свойства со значением null.
1863
+ * @param lifeTime Время жизни записи в ms.
1864
+ * @param item$ {@link Observable} запроса кэшируемых данных.
1865
+ * @param initialValue Начальное значение данных.
1886
1866
  */
1887
- // eslint-disable-next-line class-methods-use-this
1888
- removeNull(object) {
1889
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1890
- return Object.fromEntries(Object.entries(object).filter(([_, v]) => v !== null && v !== ''));
1867
+ constructor(lifeTime, item$, initialValue) {
1868
+ /**
1869
+ * {@link Observable} обновления данных.
1870
+ */
1871
+ this.update$ = new BehaviorSubject(undefined);
1872
+ /**
1873
+ * Текущее значение данных, установленное напрямую.
1874
+ */
1875
+ this.currentValue$ = new Subject();
1876
+ this.lifeTime = lifeTime;
1877
+ const requestData$ = this.update$.pipe(switchMap(() => item$.pipe(tap(() => {
1878
+ this.updateCacheTime();
1879
+ }), startWith((initialValue ?? null)))), materialize(), shareReplay(1), dematerialize());
1880
+ this.item$ = merge(this.currentValue$, requestData$).pipe(shareReplay());
1891
1881
  }
1892
1882
  /**
1893
- * Возвращает {@link T} объект из которого рекурсивно удалены свойства со значением null.
1894
- *
1895
- * @param object Объект, в котором необходимо удалить свойства со значением null.
1883
+ * Обновляет время кэширования данных.
1896
1884
  */
1897
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1898
- removeNullRecursive(object) {
1899
- // eslint-disable-next-line no-restricted-syntax
1900
- for (const k of Object.keys(object)) {
1901
- if (object[k] === null) {
1902
- if (Array.isArray(object)) {
1903
- object.splice(+k, 1);
1904
- }
1905
- else {
1906
- // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
1907
- delete object[k];
1908
- }
1909
- this.removeNullRecursive(object);
1910
- }
1911
- else if (typeof object[k] === 'object') {
1912
- this.removeNullRecursive(object[k]);
1913
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1914
- if (Array.isArray(object) && Object.keys(object[k]).length === 0) {
1915
- object.splice(+k, 1);
1916
- }
1917
- }
1918
- }
1919
- return object;
1885
+ updateCacheTime() {
1886
+ this.cachedUntil = Date.now() + this.lifeTime;
1920
1887
  }
1921
1888
  /**
1922
- * Возвращает {@link T} объект из которого удалены свойства меньшей длины, чем {@link minLength}.
1923
- *
1924
- * @param object ООбъект, в котором необходимо удалить свойства меньшей длины, чем {@link minLength}.
1925
- * @param minLength Минимально допустимая длина строковых свойств объекта.
1889
+ * Возвращает признак того, что кэшированные данные актуальны.
1926
1890
  */
1927
- // eslint-disable-next-line class-methods-use-this
1928
- removeByStrLength(object, minLength) {
1929
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1930
- return Object.fromEntries(Object.entries(object).filter(([_, v]) => (typeof v === 'string' && v.length > minLength) || typeof v !== 'string'));
1891
+ cachedDataIsActual() {
1892
+ return !this.cachedUntil || this.cachedUntil > Date.now();
1931
1893
  }
1932
1894
  /**
1933
- * Конвертирует поля, имеющие тип {@link Date}, в {@link object}, и возвращает как новый объект.
1934
- *
1935
- * @param object Объект, в котором необходимо преобразовать поля Date в string.
1895
+ * Выполняет обновления {@link Observable} запроса кэшируемых данных.
1936
1896
  */
1937
- convertDateToString(object) {
1938
- return Object.fromEntries(Object.entries(object).map(([_, v]) => (v instanceof Date ? [_, v.toLocaleDateString(this.locale)] : [_, v])));
1939
- }
1940
- // eslint-disable-next-line class-methods-use-this
1941
- createParamKeyString(keys) {
1942
- // eslint-disable-next-line unicorn/no-array-reduce
1943
- return keys.reduce((result, current, index) => (index === 0 ? current : `${result}[${current}]`), '');
1897
+ update() {
1898
+ this.cachedUntil = undefined;
1899
+ this.update$.next();
1944
1900
  }
1945
1901
  /**
1946
- * Возвращает новое представление объекта в котором рекурсивно поля преобразованы в формат <patent_properties>[<child_properties>]... .
1902
+ * Устанавливает значение данных напрямую без провоцирования запроса через {@link Observable}.
1947
1903
  *
1948
- * @param object Объект, в котором необходимо преобразовать поля в формат <patent_properties>[<child_properties>]... .
1949
- * @param keys Список ключей до объекта {@link object} в исходном объекте.
1950
- * @param resultObject Итоговый объект.
1904
+ * @param value Новое значение данных.
1905
+ * @param updateCacheTime Обновить время кэширования. По умолчанию true.
1951
1906
  */
1952
- toSimpleObjectRecursive(
1953
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1954
- object, keys = [],
1955
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
1956
- resultObject = {}) {
1957
- // eslint-disable-next-line no-restricted-syntax
1958
- for (const key in object) {
1959
- if (object.hasOwnProperty.call(object, key)) {
1960
- if (typeof object[key] === 'object' && object[key] !== null && !(object[key] instanceof Date)) {
1961
- this.toSimpleObjectRecursive(object[key], [...keys, key], resultObject);
1962
- }
1963
- else {
1964
- resultObject[this.createParamKeyString([...keys, key])] = object[key];
1965
- }
1966
- }
1907
+ setValue(value, updateCacheTime = true) {
1908
+ if (updateCacheTime) {
1909
+ this.updateCacheTime();
1967
1910
  }
1968
- return resultObject;
1911
+ this.currentValue$.next(value);
1969
1912
  }
1970
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScConvertersService, deps: [{ token: LOCALE_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
1971
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScConvertersService, providedIn: 'root' }); }
1972
1913
  }
1973
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScConvertersService, decorators: [{
1974
- type: Injectable,
1975
- args: [{
1976
- providedIn: 'root',
1977
- }]
1978
- }], ctorParameters: () => [{ type: undefined, decorators: [{
1979
- type: Inject,
1980
- args: [LOCALE_ID]
1981
- }] }] });
1914
+
1915
+ /**
1916
+ * Плейсхолдер загрузки данных заказа (корзины / черновика).
1917
+ */
1918
+ const loadingPlaceholder = {};
1919
+ /**
1920
+ * Проверяет, что объект заказа (корзины / черновика) загружен, а не является плейсхолдером загрузки.
1921
+ *
1922
+ * @param value Значение (загруженные данные или плейсхолдер загрузки).
1923
+ */
1924
+ function scOrderIsLoaded(value) {
1925
+ return !isNil(value) && value !== loadingPlaceholder;
1926
+ }
1927
+ /**
1928
+ * Токен инъекции сервиса списка товаров заказа.
1929
+ * Предоставляется в корне компонента корзины, заказа или черновика — в зависимости от контекста
1930
+ * внедряется соответствующая реализация (корзина, заказ, черновик = заказ).
1931
+ */
1932
+ const SC_ORDER_LOADER = new InjectionToken('ScOrderLoader (order / cart / draft)');
1933
+ /**
1934
+ * Плейсхолдер загрузки данных заказа (корзины / черновика).
1935
+ */
1936
+ const SC_ORDER_LOADING = new InjectionToken('ScOrderLoading', { factory: () => loadingPlaceholder });
1982
1937
 
1983
1938
  /**
1984
1939
  * Формат отображения каталога.
@@ -2042,40 +1997,280 @@ class ScUserMetadata {
2042
1997
  }
2043
1998
  }
2044
1999
 
2000
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2045
2001
  /**
2046
- * Перечисление названий справочников.
2002
+ * Возвращает фильтр для {@link Observable} изменений метаданных пользователя.
2003
+ *
2004
+ * @param target Свойство для которого отслеживается изменение.
2005
+ * @returns Функция {@link distinctUntilKeyChanged} для отслеживания изменения {@link Observable} {@link ScUserMetadata}.
2047
2006
  */
2048
- // eslint-disable-next-line no-shadow
2049
- var ScReferenceName;
2050
- (function (ScReferenceName) {
2007
+ function filterChangedByKey(target) {
2008
+ return distinctUntilKeyChanged(target, (previous, current) => previous === current);
2009
+ }
2010
+
2011
+ /* eslint-disable security/detect-object-injection */
2012
+ /**
2013
+ * Сервис для работы с UI.
2014
+ */
2015
+ class ScUIService {
2051
2016
  /**
2052
- * Тип канала сообщений чата.
2017
+ * Инициализирует экземпляр класса {@link ScUIService}.
2018
+ *
2019
+ * @param userService Сервис информации о пользователе.
2053
2020
  */
2054
- ScReferenceName["chatChannel"] = "chat-channel";
2021
+ constructor(userService) {
2022
+ this.userService = userService;
2023
+ /**
2024
+ * {@link ReplaySubject} метаданных пользователя.
2025
+ */
2026
+ this.userMetadataSubject = new ReplaySubject(1);
2027
+ userService.getUserChange$().subscribe((user) => {
2028
+ if (this.metadataSubjectSubscription) {
2029
+ this.metadataSubjectSubscription.unsubscribe();
2030
+ }
2031
+ this.userMetadataSubject.next(new ScUserMetadata(user.metadata));
2032
+ this.metadataSubjectSubscription = this.userMetadataSubject
2033
+ .pipe(skip(1), // Не нужно обновлять данные пользователя при его смене.
2034
+ switchMap((metadata) => user.userType === ScUserType.guest ? this.userService.updateGuestInfo$({ metadata: metadata }) : this.userService.updateUserInfo$({ metadata: metadata })))
2035
+ .subscribe();
2036
+ });
2037
+ }
2055
2038
  /**
2056
- * Город.
2039
+ * Возвращает {@link Observable} метаданных, когда изменяется значение переданного свойства.
2040
+ *
2041
+ * @param target Свойство для которого отслеживается изменение.
2057
2042
  */
2058
- ScReferenceName["city"] = "city";
2043
+ getMetadataChangeByKey$(target) {
2044
+ return this.userMetadataSubject.pipe(filterChangedByKey(target), map((metadata) => metadata[target]));
2045
+ }
2059
2046
  /**
2060
- * Город с информацией о регионе и стране.
2047
+ * Возвращает {@link Observable} метаданных, когда изменяется значение переданного свойства.
2048
+ * TODO: Доработать функцию, чтобы она возвращала Observable.
2049
+ *
2050
+ * @param target Свойство, значение которого необходимо изменить.
2051
+ * @param value Новое значение.
2061
2052
  */
2062
- ScReferenceName["cityWithRegionAndCountry"] = "city-with-region-and-country";
2053
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
2054
+ setMetadataByKey(target, value) {
2055
+ this.userMetadataSubject.pipe(first()).subscribe((metadata) => {
2056
+ const newMetadata = new ScUserMetadata(metadata);
2057
+ newMetadata[target] = value;
2058
+ this.userMetadataSubject.next(newMetadata);
2059
+ });
2060
+ }
2063
2061
  /**
2064
- * Город с информацией о регионе.
2062
+ * Возвращает {@link Observable} списка категорий, которые необходимо скрыть.
2065
2063
  */
2066
- ScReferenceName["cityWithRegion"] = "city-with-region";
2064
+ getHiddenCategoriesList$() {
2065
+ return this.getMetadataChangeByKey$('hiddenCategories');
2066
+ }
2067
2067
  /**
2068
- * Страна.
2068
+ * Устанавливает список категорий, которые необходимо скрыть.
2069
+ *
2070
+ * @param categoryIds Список идентификаторов категорий, которые необходимо скрыть.
2069
2071
  */
2070
- ScReferenceName["country"] = "country";
2072
+ setHiddenCategoriesList(categoryIds) {
2073
+ this.setMetadataByKey('hiddenCategories', categoryIds);
2074
+ }
2071
2075
  /**
2072
- * Тип доставки.
2076
+ * Возвращает {@link Observable} вида представления товара в списке.
2073
2077
  */
2074
- ScReferenceName["deliveryType"] = "delivery-type";
2078
+ getProductTileType$() {
2079
+ return this.getMetadataChangeByKey$('productTileType');
2080
+ }
2075
2081
  /**
2076
- * Статус оплаты заказа.
2082
+ * Устанавливает вид представления товара в списке.
2083
+ *
2084
+ * @param productTileType Вид представления товара в списке.
2077
2085
  */
2078
- ScReferenceName["orderPaymentStatus"] = "order-payment-status";
2086
+ setProductTileType(productTileType) {
2087
+ this.setMetadataByKey('productTileType', productTileType);
2088
+ }
2089
+ /**
2090
+ * Возвращает {@link Observable} количества элементов на странице пагинации.
2091
+ */
2092
+ getPaginatePageSize$() {
2093
+ return this.getMetadataChangeByKey$('paginatePageSize');
2094
+ }
2095
+ /**
2096
+ * Устанавливает количество элементов на странице пагинации.
2097
+ *
2098
+ * @param paginatePageSize Количество элементов на странице пагинации.
2099
+ */
2100
+ setPaginatePageSize(paginatePageSize) {
2101
+ this.setMetadataByKey('paginatePageSize', paginatePageSize);
2102
+ }
2103
+ /**
2104
+ * Возвращает {@link Observable} метаданных неоформленного заказа по направлению продаж.
2105
+ *
2106
+ * @param directionsId Идентификатор направления продаж.
2107
+ */
2108
+ getNewOrderMetadata$(directionsId) {
2109
+ // Данные представлены массивом объектов, поэтому не используется getMetadataChangeByKey$().
2110
+ return this.userMetadataSubject.pipe(map((metadata) => metadata.newOrdersMetadata), distinctUntilChanged(), map((ordersMetadata) => ordersMetadata[directionsId]), distinctUntilChanged());
2111
+ }
2112
+ /**
2113
+ * Устанавливает метаданные неоформленного заказа по направлению продаж.
2114
+ *
2115
+ * @param directionsId Идентификатор направления продаж.
2116
+ * @param newOrderMetadata Данные нового неоформленного заказа.
2117
+ */
2118
+ setNewOrderMetadata(directionsId, newOrderMetadata) {
2119
+ // При сохранении изображения выдаёт ошибку 500 'Произошла ошибка при работе с базой данных'.
2120
+ // TODO: TASK[#6370]: Доработать после решения задачи.
2121
+ if (newOrderMetadata.image) {
2122
+ // eslint-disable-next-line no-param-reassign
2123
+ delete newOrderMetadata.image;
2124
+ }
2125
+ this.getMetadataChangeByKey$('newOrdersMetadata')
2126
+ .pipe(first())
2127
+ .subscribe((ordersMetadata) => {
2128
+ // eslint-disable-next-line no-param-reassign
2129
+ ordersMetadata[directionsId] = newOrderMetadata;
2130
+ this.setMetadataByKey('newOrdersMetadata', structuredClone(ordersMetadata));
2131
+ });
2132
+ }
2133
+ /**
2134
+ * Удаляет метаданные неоформленного заказа по направлению продаж.
2135
+ *
2136
+ * @param directionsId Идентификатор направления продаж.
2137
+ */
2138
+ removeNewOrderMetadata(directionsId) {
2139
+ this.getMetadataChangeByKey$('newOrdersMetadata')
2140
+ .pipe(first())
2141
+ .subscribe((ordersMetadata) => {
2142
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete,no-param-reassign
2143
+ delete ordersMetadata[directionsId];
2144
+ this.setMetadataByKey('newOrdersMetadata', structuredClone(ordersMetadata));
2145
+ });
2146
+ }
2147
+ /**
2148
+ * Удаляет метаданные не оформленных заказов по всем направлениям продаж.
2149
+ */
2150
+ removeAllNewOrdersMetadata() {
2151
+ this.setMetadataByKey('newOrdersMetadata', []);
2152
+ }
2153
+ /**
2154
+ * Возвращает дату последнего открытия опросников.
2155
+ */
2156
+ getLastOpenQuestionnaireTime$() {
2157
+ return this.getMetadataChangeByKey$('lastOpenQuestionnaireTime');
2158
+ }
2159
+ /**
2160
+ * Устанавливает дату последнего открытия опросников.
2161
+ *
2162
+ * @param lastOpenQuestionnaireTime Дата последнего открытия опросников.
2163
+ */
2164
+ setLastOpenQuestionnaireTime(lastOpenQuestionnaireTime) {
2165
+ this.setMetadataByKey('lastOpenQuestionnaireTime', lastOpenQuestionnaireTime);
2166
+ }
2167
+ /**
2168
+ * Возвращает формат отображения каталога.
2169
+ */
2170
+ getCatalogFormat$() {
2171
+ return this.getMetadataChangeByKey$('catalogFormat');
2172
+ }
2173
+ /**
2174
+ * Устанавливает формат отображения каталога.
2175
+ *
2176
+ * @param catalogFormat Формат отображения каталога.
2177
+ */
2178
+ setCatalogFormat(catalogFormat) {
2179
+ this.setMetadataByKey('catalogFormat', catalogFormat);
2180
+ }
2181
+ /**
2182
+ * Устанавливает идентификатор выбранного склада.
2183
+ *
2184
+ * @param selectedWarehouseId Идентификатор выбранного склада.
2185
+ */
2186
+ setSelectedWarehouseId(selectedWarehouseId) {
2187
+ this.setMetadataByKey('selectedWarehouseId', selectedWarehouseId);
2188
+ }
2189
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, deps: [{ token: ScUserService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2190
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, providedIn: 'root' }); }
2191
+ }
2192
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, decorators: [{
2193
+ type: Injectable,
2194
+ args: [{
2195
+ providedIn: 'root',
2196
+ }]
2197
+ }], ctorParameters: () => [{ type: ScUserService }] });
2198
+
2199
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access,security/detect-non-literal-regexp */
2200
+ /**
2201
+ * Токен признака запущено ли приложение на терминале.
2202
+ */
2203
+ const IS_RUNNING_ON_TERMINAL = new InjectionToken('IS_RUNNING_ON_TERMINAL');
2204
+ /**
2205
+ * Возвращает признак, что приложение запущено на терминале, а также код склада который обслуживает этот терминал (вернет null если не идентификатор склада отсутствует).
2206
+ *
2207
+ * @param userAgentTerminal Регулярное выражение агента пользователя для терминала.
2208
+ *
2209
+ * @returns Если приложение запущено на терминале, возвращает признак этого
2210
+ * и возвращает идентификатор склада привязанного к терминалу в случае его извлечения и, null в случае если склад не удалось извлечь.
2211
+ */
2212
+ function runningOnTerminalFactory(userAgentTerminal) {
2213
+ const isRunningOnTerminal = userAgentTerminal.test(inject(WA_USER_AGENT));
2214
+ if (isRunningOnTerminal) {
2215
+ const matchResult = new RegExp(`${userAgentTerminal.source}(\\w+)`, 'i').exec(inject(WA_USER_AGENT));
2216
+ if (matchResult && matchResult.length > 1) {
2217
+ return { isRunningOnTerminal: isRunningOnTerminal, warehouseId: Number.parseInt(matchResult[1], 10) };
2218
+ }
2219
+ }
2220
+ return { isRunningOnTerminal: isRunningOnTerminal, warehouseId: null };
2221
+ }
2222
+ /**
2223
+ * Токен агента пользователя для терминала.
2224
+ */
2225
+ const USER_AGENT_TERMINAL = new InjectionToken('USER_AGENT_TERMINAL', {
2226
+ providedIn: 'root',
2227
+ factory: () => /sc_terminal_w/i,
2228
+ });
2229
+ /**
2230
+ * Провайдеры данных о терминале.
2231
+ */
2232
+ const TERMINAL_PROVIDERS = [
2233
+ {
2234
+ provide: IS_RUNNING_ON_TERMINAL,
2235
+ deps: [USER_AGENT_TERMINAL],
2236
+ useFactory: runningOnTerminalFactory,
2237
+ },
2238
+ ];
2239
+
2240
+ /**
2241
+ * Перечисление названий справочников.
2242
+ */
2243
+ // eslint-disable-next-line no-shadow
2244
+ var ScReferenceName;
2245
+ (function (ScReferenceName) {
2246
+ /**
2247
+ * Тип канала сообщений чата.
2248
+ */
2249
+ ScReferenceName["chatChannel"] = "chat-channel";
2250
+ /**
2251
+ * Город.
2252
+ */
2253
+ ScReferenceName["city"] = "city";
2254
+ /**
2255
+ * Город с информацией о регионе и стране.
2256
+ */
2257
+ ScReferenceName["cityWithRegionAndCountry"] = "city-with-region-and-country";
2258
+ /**
2259
+ * Город с информацией о регионе.
2260
+ */
2261
+ ScReferenceName["cityWithRegion"] = "city-with-region";
2262
+ /**
2263
+ * Страна.
2264
+ */
2265
+ ScReferenceName["country"] = "country";
2266
+ /**
2267
+ * Тип доставки.
2268
+ */
2269
+ ScReferenceName["deliveryType"] = "delivery-type";
2270
+ /**
2271
+ * Статус оплаты заказа.
2272
+ */
2273
+ ScReferenceName["orderPaymentStatus"] = "order-payment-status";
2079
2274
  /**
2080
2275
  * Статус заказа.
2081
2276
  */
@@ -2118,6 +2313,138 @@ var ScReferenceName;
2118
2313
  ScReferenceName["currency"] = "currency";
2119
2314
  })(ScReferenceName || (ScReferenceName = {}));
2120
2315
 
2316
+ /* eslint-disable security/detect-object-injection,no-param-reassign */
2317
+ /**
2318
+ * Сервис конвертации данных.
2319
+ */
2320
+ class ScConvertersService {
2321
+ /**
2322
+ * Инициализирует экземпляр класса {@link ScConvertersService}.
2323
+ *
2324
+ * @param locale Язык приложения из поставщика.
2325
+ */
2326
+ constructor(locale) {
2327
+ this.locale = locale;
2328
+ }
2329
+ /**
2330
+ * Конвертирует объект в {@link HttpParams}.
2331
+ *
2332
+ * @param object Объект, которые нужно перевести в {@link HttpParams}.
2333
+ * @param options Параметры конвертации объекта.
2334
+ */
2335
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2336
+ toHttpParams(object, options) {
2337
+ object = this.toSimpleObjectRecursive(object);
2338
+ object = this.convertDateToString(object);
2339
+ if (options?.nonNullable) {
2340
+ object = tuiCleanObject(object);
2341
+ }
2342
+ if (options?.minLength) {
2343
+ object = this.removeByStrLength(object, options.minLength);
2344
+ }
2345
+ return new HttpParams().appendAll(object);
2346
+ }
2347
+ /**
2348
+ * Возвращает {@link T} объект из которого удалены свойства со значением null.
2349
+ *
2350
+ * @param object Объект, в котором необходимо удалить свойства со значением null.
2351
+ */
2352
+ // eslint-disable-next-line class-methods-use-this
2353
+ removeNull(object) {
2354
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2355
+ return Object.fromEntries(Object.entries(object).filter(([_, v]) => v !== null && v !== ''));
2356
+ }
2357
+ /**
2358
+ * Возвращает {@link T} объект из которого рекурсивно удалены свойства со значением null.
2359
+ *
2360
+ * @param object Объект, в котором необходимо удалить свойства со значением null.
2361
+ */
2362
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2363
+ removeNullRecursive(object) {
2364
+ // eslint-disable-next-line no-restricted-syntax
2365
+ for (const k of Object.keys(object)) {
2366
+ if (object[k] === null) {
2367
+ if (Array.isArray(object)) {
2368
+ object.splice(+k, 1);
2369
+ }
2370
+ else {
2371
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
2372
+ delete object[k];
2373
+ }
2374
+ this.removeNullRecursive(object);
2375
+ }
2376
+ else if (typeof object[k] === 'object') {
2377
+ this.removeNullRecursive(object[k]);
2378
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2379
+ if (Array.isArray(object) && Object.keys(object[k]).length === 0) {
2380
+ object.splice(+k, 1);
2381
+ }
2382
+ }
2383
+ }
2384
+ return object;
2385
+ }
2386
+ /**
2387
+ * Возвращает {@link T} объект из которого удалены свойства меньшей длины, чем {@link minLength}.
2388
+ *
2389
+ * @param object ООбъект, в котором необходимо удалить свойства меньшей длины, чем {@link minLength}.
2390
+ * @param minLength Минимально допустимая длина строковых свойств объекта.
2391
+ */
2392
+ // eslint-disable-next-line class-methods-use-this
2393
+ removeByStrLength(object, minLength) {
2394
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2395
+ return Object.fromEntries(Object.entries(object).filter(([_, v]) => (typeof v === 'string' && v.length > minLength) || typeof v !== 'string'));
2396
+ }
2397
+ /**
2398
+ * Конвертирует поля, имеющие тип {@link Date}, в {@link object}, и возвращает как новый объект.
2399
+ *
2400
+ * @param object Объект, в котором необходимо преобразовать поля Date в string.
2401
+ */
2402
+ convertDateToString(object) {
2403
+ return Object.fromEntries(Object.entries(object).map(([_, v]) => (v instanceof Date ? [_, v.toLocaleDateString(this.locale)] : [_, v])));
2404
+ }
2405
+ // eslint-disable-next-line class-methods-use-this
2406
+ createParamKeyString(keys) {
2407
+ // eslint-disable-next-line unicorn/no-array-reduce
2408
+ return keys.reduce((result, current, index) => (index === 0 ? current : `${result}[${current}]`), '');
2409
+ }
2410
+ /**
2411
+ * Возвращает новое представление объекта в котором рекурсивно поля преобразованы в формат <patent_properties>[<child_properties>]... .
2412
+ *
2413
+ * @param object Объект, в котором необходимо преобразовать поля в формат <patent_properties>[<child_properties>]... .
2414
+ * @param keys Список ключей до объекта {@link object} в исходном объекте.
2415
+ * @param resultObject Итоговый объект.
2416
+ */
2417
+ toSimpleObjectRecursive(
2418
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2419
+ object, keys = [],
2420
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2421
+ resultObject = {}) {
2422
+ // eslint-disable-next-line no-restricted-syntax
2423
+ for (const key in object) {
2424
+ if (object.hasOwnProperty.call(object, key)) {
2425
+ if (typeof object[key] === 'object' && object[key] !== null && !(object[key] instanceof Date)) {
2426
+ this.toSimpleObjectRecursive(object[key], [...keys, key], resultObject);
2427
+ }
2428
+ else {
2429
+ resultObject[this.createParamKeyString([...keys, key])] = object[key];
2430
+ }
2431
+ }
2432
+ }
2433
+ return resultObject;
2434
+ }
2435
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScConvertersService, deps: [{ token: LOCALE_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
2436
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScConvertersService, providedIn: 'root' }); }
2437
+ }
2438
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScConvertersService, decorators: [{
2439
+ type: Injectable,
2440
+ args: [{
2441
+ providedIn: 'root',
2442
+ }]
2443
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
2444
+ type: Inject,
2445
+ args: [LOCALE_ID]
2446
+ }] }] });
2447
+
2121
2448
  /**
2122
2449
  * Сервис справочников.
2123
2450
  */
@@ -2216,335 +2543,95 @@ class ScReferencesService {
2216
2543
  * Возвращает данные справочника по идентификатору.
2217
2544
  *
2218
2545
  * @param referenceName Название справочника.
2219
- * @param id Идентификатор записи справочника, информацию о которой необходимо вернуть.
2220
- */
2221
- getReferenceById$(referenceName, id) {
2222
- return this.http.get(`${this.urls.apiUrl}/references/${referenceName}/${id}`).pipe(shareReplay(1));
2223
- }
2224
- /**
2225
- * Возвращает {@link Observable} направления продаж, соответствующий идентификатору на входе.
2226
- *
2227
- * @param directionId Идентификатор направления продаж.
2228
- */
2229
- getDirectionById$(directionId) {
2230
- return this.directions$.pipe(map((directions) => directions.find((direction) => direction.id === directionId)));
2231
- }
2232
- /**
2233
- * Возвращает {@link Observable} типа клиента, соответствующий символьному обозначению (slug) на входе.
2234
- * TODO: Написать тесты после доработки справочников.
2235
- *
2236
- * @param slug Символьное обозначение (slug) типа клиента.
2237
- */
2238
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
2239
- getClientTypesBySlug$(slug) {
2240
- // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
2241
- return this.clientTypes$.pipe(map((types) => types.find((type) => type.name === slug)));
2242
- }
2243
- /**
2244
- * Возвращает {@link Observable} статус оплаты, соответствующий идентификатору на входе.
2245
- *
2246
- * @param typeId Идентификатор статуса оплаты.
2247
- */
2248
- getPaymentStatusById$(typeId) {
2249
- return this.paymentStatuses$.pipe(map((types) => types.find((type) => type.id === typeId)));
2250
- }
2251
- /**
2252
- * Возвращает {@link Observable} тип доставки, соответствующий идентификатору на входе.
2253
- *
2254
- * @param typeId Идентификатор типа доставки.
2255
- */
2256
- getDeliveryTypeById$(typeId) {
2257
- return this.deliveryTypes$.pipe(map((types) => types.find((type) => type.id === typeId)));
2258
- }
2259
- /**
2260
- * Возвращает {@link Observable} тип статуса заказа, соответствующий идентификатору на входе.
2261
- *
2262
- * @param statusId Идентификатор типа статуса.
2263
- */
2264
- getOrderStatusById$(statusId) {
2265
- return this.orderStatuses$.pipe(map((types) => types.find((type) => type.id === statusId)));
2266
- }
2267
- /**
2268
- * Возвращает {@link Observable} типа статуса рекламаций, соответствующий указанному идентификатору.
2269
- *
2270
- * @param statusId Идентификатор типа статуса.
2271
- */
2272
- getReclamationStatusById$(statusId) {
2273
- return this.reclamationStatuses$.pipe(map((types) => types.find((type) => type.id === statusId)));
2274
- }
2275
- /**
2276
- * Возвращает {@link Observable} тип оплаты, соответствующий идентификатору на входе.
2277
- *
2278
- * @param typeId Идентификатор типа оплаты.
2279
- */
2280
- getPaymentTypeById$(typeId) {
2281
- return this.paymentTypes$.pipe(map((types) => types.find((type) => type.id === typeId)));
2282
- }
2283
- /**
2284
- * Возвращает {@link Observable} организационно-правовой формы, соответствующий символьному обозначению (slug) на входе.
2285
- *
2286
- * @param slug Символьное обозначение (slug).
2287
- */
2288
- getOpfBySlug$(slug) {
2289
- return this.opf$.pipe(map((types) => types.find((type) => type.slug === slug)));
2290
- }
2291
- /**
2292
- * Возвращает {@link Observable} валюты, соответствующий идентификатору на входе.
2293
- *
2294
- * @param currencyId Идентификатор валюты.
2295
- */
2296
- getCurrencyById$(currencyId) {
2297
- return this.currencies$.pipe(map((types) => types.find((type) => type.id === currencyId)));
2298
- }
2299
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScReferencesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2300
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScReferencesService, providedIn: 'root' }); }
2301
- }
2302
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScReferencesService, decorators: [{
2303
- type: Injectable,
2304
- args: [{
2305
- providedIn: 'root',
2306
- }]
2307
- }] });
2308
-
2309
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2310
- /**
2311
- * Возвращает фильтр для {@link Observable} изменений метаданных пользователя.
2312
- *
2313
- * @param target Свойство для которого отслеживается изменение.
2314
- * @returns Функция {@link distinctUntilKeyChanged} для отслеживания изменения {@link Observable} {@link ScUserMetadata}.
2315
- */
2316
- function filterChangedByKey(target) {
2317
- return distinctUntilKeyChanged(target, (previous, current) => previous === current);
2318
- }
2319
-
2320
- /* eslint-disable security/detect-object-injection */
2321
- /**
2322
- * Сервис для работы с UI.
2323
- */
2324
- class ScUIService {
2325
- /**
2326
- * Инициализирует экземпляр класса {@link ScUIService}.
2327
- *
2328
- * @param userService Сервис информации о пользователе.
2329
- */
2330
- constructor(userService) {
2331
- this.userService = userService;
2332
- /**
2333
- * {@link ReplaySubject} метаданных пользователя.
2334
- */
2335
- this.userMetadataSubject = new ReplaySubject(1);
2336
- userService.getUserChange$().subscribe((user) => {
2337
- if (this.metadataSubjectSubscription) {
2338
- this.metadataSubjectSubscription.unsubscribe();
2339
- }
2340
- this.userMetadataSubject.next(new ScUserMetadata(user.metadata));
2341
- this.metadataSubjectSubscription = this.userMetadataSubject
2342
- .pipe(skip(1), // Не нужно обновлять данные пользователя при его смене.
2343
- switchMap((metadata) => user.userType === ScUserType.guest ? this.userService.updateGuestInfo$({ metadata: metadata }) : this.userService.updateUserInfo$({ metadata: metadata })))
2344
- .subscribe();
2345
- });
2346
- }
2347
- /**
2348
- * Возвращает {@link Observable} метаданных, когда изменяется значение переданного свойства.
2349
- *
2350
- * @param target Свойство для которого отслеживается изменение.
2351
- */
2352
- getMetadataChangeByKey$(target) {
2353
- return this.userMetadataSubject.pipe(filterChangedByKey(target), map((metadata) => metadata[target]));
2354
- }
2355
- /**
2356
- * Возвращает {@link Observable} метаданных, когда изменяется значение переданного свойства.
2357
- * TODO: Доработать функцию, чтобы она возвращала Observable.
2358
- *
2359
- * @param target Свойство, значение которого необходимо изменить.
2360
- * @param value Новое значение.
2361
- */
2362
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
2363
- setMetadataByKey(target, value) {
2364
- this.userMetadataSubject.pipe(first()).subscribe((metadata) => {
2365
- const newMetadata = new ScUserMetadata(metadata);
2366
- newMetadata[target] = value;
2367
- this.userMetadataSubject.next(newMetadata);
2368
- });
2369
- }
2370
- /**
2371
- * Возвращает {@link Observable} списка категорий, которые необходимо скрыть.
2372
- */
2373
- getHiddenCategoriesList$() {
2374
- return this.getMetadataChangeByKey$('hiddenCategories');
2375
- }
2376
- /**
2377
- * Устанавливает список категорий, которые необходимо скрыть.
2378
- *
2379
- * @param categoryIds Список идентификаторов категорий, которые необходимо скрыть.
2380
- */
2381
- setHiddenCategoriesList(categoryIds) {
2382
- this.setMetadataByKey('hiddenCategories', categoryIds);
2383
- }
2384
- /**
2385
- * Возвращает {@link Observable} вида представления товара в списке.
2386
- */
2387
- getProductTileType$() {
2388
- return this.getMetadataChangeByKey$('productTileType');
2389
- }
2390
- /**
2391
- * Устанавливает вид представления товара в списке.
2392
- *
2393
- * @param productTileType Вид представления товара в списке.
2394
- */
2395
- setProductTileType(productTileType) {
2396
- this.setMetadataByKey('productTileType', productTileType);
2397
- }
2398
- /**
2399
- * Возвращает {@link Observable} количества элементов на странице пагинации.
2400
- */
2401
- getPaginatePageSize$() {
2402
- return this.getMetadataChangeByKey$('paginatePageSize');
2403
- }
2404
- /**
2405
- * Устанавливает количество элементов на странице пагинации.
2406
- *
2407
- * @param paginatePageSize Количество элементов на странице пагинации.
2546
+ * @param id Идентификатор записи справочника, информацию о которой необходимо вернуть.
2408
2547
  */
2409
- setPaginatePageSize(paginatePageSize) {
2410
- this.setMetadataByKey('paginatePageSize', paginatePageSize);
2548
+ getReferenceById$(referenceName, id) {
2549
+ return this.http.get(`${this.urls.apiUrl}/references/${referenceName}/${id}`).pipe(shareReplay(1));
2411
2550
  }
2412
2551
  /**
2413
- * Возвращает {@link Observable} метаданных неоформленного заказа по направлению продаж.
2552
+ * Возвращает {@link Observable} направления продаж, соответствующий идентификатору на входе.
2414
2553
  *
2415
- * @param directionsId Идентификатор направления продаж.
2554
+ * @param directionId Идентификатор направления продаж.
2416
2555
  */
2417
- getNewOrderMetadata$(directionsId) {
2418
- // Данные представлены массивом объектов, поэтому не используется getMetadataChangeByKey$().
2419
- return this.userMetadataSubject.pipe(map((metadata) => metadata.newOrdersMetadata), distinctUntilChanged(), map((ordersMetadata) => ordersMetadata[directionsId]), distinctUntilChanged());
2556
+ getDirectionById$(directionId) {
2557
+ return this.directions$.pipe(map((directions) => directions.find((direction) => direction.id === directionId)));
2420
2558
  }
2421
2559
  /**
2422
- * Устанавливает метаданные неоформленного заказа по направлению продаж.
2560
+ * Возвращает {@link Observable} типа клиента, соответствующий символьному обозначению (slug) на входе.
2561
+ * TODO: Написать тесты после доработки справочников.
2423
2562
  *
2424
- * @param directionsId Идентификатор направления продаж.
2425
- * @param newOrderMetadata Данные нового неоформленного заказа.
2563
+ * @param slug Символьное обозначение (slug) типа клиента.
2426
2564
  */
2427
- setNewOrderMetadata(directionsId, newOrderMetadata) {
2428
- // При сохранении изображения выдаёт ошибку 500 'Произошла ошибка при работе с базой данных'.
2429
- // TODO: TASK[#6370]: Доработать после решения задачи.
2430
- if (newOrderMetadata.image) {
2431
- // eslint-disable-next-line no-param-reassign
2432
- delete newOrderMetadata.image;
2433
- }
2434
- this.getMetadataChangeByKey$('newOrdersMetadata')
2435
- .pipe(first())
2436
- .subscribe((ordersMetadata) => {
2437
- // eslint-disable-next-line no-param-reassign
2438
- ordersMetadata[directionsId] = newOrderMetadata;
2439
- this.setMetadataByKey('newOrdersMetadata', structuredClone(ordersMetadata));
2440
- });
2565
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2566
+ getClientTypesBySlug$(slug) {
2567
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
2568
+ return this.clientTypes$.pipe(map((types) => types.find((type) => type.name === slug)));
2441
2569
  }
2442
2570
  /**
2443
- * Удаляет метаданные неоформленного заказа по направлению продаж.
2571
+ * Возвращает {@link Observable} статус оплаты, соответствующий идентификатору на входе.
2444
2572
  *
2445
- * @param directionsId Идентификатор направления продаж.
2573
+ * @param typeId Идентификатор статуса оплаты.
2446
2574
  */
2447
- removeNewOrderMetadata(directionsId) {
2448
- this.getMetadataChangeByKey$('newOrdersMetadata')
2449
- .pipe(first())
2450
- .subscribe((ordersMetadata) => {
2451
- // eslint-disable-next-line @typescript-eslint/no-dynamic-delete,no-param-reassign
2452
- delete ordersMetadata[directionsId];
2453
- this.setMetadataByKey('newOrdersMetadata', structuredClone(ordersMetadata));
2454
- });
2575
+ getPaymentStatusById$(typeId) {
2576
+ return this.paymentStatuses$.pipe(map((types) => types.find((type) => type.id === typeId)));
2455
2577
  }
2456
2578
  /**
2457
- * Удаляет метаданные не оформленных заказов по всем направлениям продаж.
2579
+ * Возвращает {@link Observable} тип доставки, соответствующий идентификатору на входе.
2580
+ *
2581
+ * @param typeId Идентификатор типа доставки.
2458
2582
  */
2459
- removeAllNewOrdersMetadata() {
2460
- this.setMetadataByKey('newOrdersMetadata', []);
2583
+ getDeliveryTypeById$(typeId) {
2584
+ return this.deliveryTypes$.pipe(map((types) => types.find((type) => type.id === typeId)));
2461
2585
  }
2462
2586
  /**
2463
- * Возвращает дату последнего открытия опросников.
2587
+ * Возвращает {@link Observable} тип статуса заказа, соответствующий идентификатору на входе.
2588
+ *
2589
+ * @param statusId Идентификатор типа статуса.
2464
2590
  */
2465
- getLastOpenQuestionnaireTime$() {
2466
- return this.getMetadataChangeByKey$('lastOpenQuestionnaireTime');
2591
+ getOrderStatusById$(statusId) {
2592
+ return this.orderStatuses$.pipe(map((types) => types.find((type) => type.id === statusId)));
2467
2593
  }
2468
2594
  /**
2469
- * Устанавливает дату последнего открытия опросников.
2595
+ * Возвращает {@link Observable} типа статуса рекламаций, соответствующий указанному идентификатору.
2470
2596
  *
2471
- * @param lastOpenQuestionnaireTime Дата последнего открытия опросников.
2597
+ * @param statusId Идентификатор типа статуса.
2472
2598
  */
2473
- setLastOpenQuestionnaireTime(lastOpenQuestionnaireTime) {
2474
- this.setMetadataByKey('lastOpenQuestionnaireTime', lastOpenQuestionnaireTime);
2599
+ getReclamationStatusById$(statusId) {
2600
+ return this.reclamationStatuses$.pipe(map((types) => types.find((type) => type.id === statusId)));
2475
2601
  }
2476
2602
  /**
2477
- * Возвращает формат отображения каталога.
2603
+ * Возвращает {@link Observable} тип оплаты, соответствующий идентификатору на входе.
2604
+ *
2605
+ * @param typeId Идентификатор типа оплаты.
2478
2606
  */
2479
- getCatalogFormat$() {
2480
- return this.getMetadataChangeByKey$('catalogFormat');
2607
+ getPaymentTypeById$(typeId) {
2608
+ return this.paymentTypes$.pipe(map((types) => types.find((type) => type.id === typeId)));
2481
2609
  }
2482
2610
  /**
2483
- * Устанавливает формат отображения каталога.
2611
+ * Возвращает {@link Observable} организационно-правовой формы, соответствующий символьному обозначению (slug) на входе.
2484
2612
  *
2485
- * @param catalogFormat Формат отображения каталога.
2613
+ * @param slug Символьное обозначение (slug).
2486
2614
  */
2487
- setCatalogFormat(catalogFormat) {
2488
- this.setMetadataByKey('catalogFormat', catalogFormat);
2615
+ getOpfBySlug$(slug) {
2616
+ return this.opf$.pipe(map((types) => types.find((type) => type.slug === slug)));
2489
2617
  }
2490
2618
  /**
2491
- * Устанавливает идентификатор выбранного склада.
2619
+ * Возвращает {@link Observable} валюты, соответствующий идентификатору на входе.
2492
2620
  *
2493
- * @param selectedWarehouseId Идентификатор выбранного склада.
2621
+ * @param currencyId Идентификатор валюты.
2494
2622
  */
2495
- setSelectedWarehouseId(selectedWarehouseId) {
2496
- this.setMetadataByKey('selectedWarehouseId', selectedWarehouseId);
2623
+ getCurrencyById$(currencyId) {
2624
+ return this.currencies$.pipe(map((types) => types.find((type) => type.id === currencyId)));
2497
2625
  }
2498
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, deps: [{ token: ScUserService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2499
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, providedIn: 'root' }); }
2626
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScReferencesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2627
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScReferencesService, providedIn: 'root' }); }
2500
2628
  }
2501
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, decorators: [{
2629
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScReferencesService, decorators: [{
2502
2630
  type: Injectable,
2503
2631
  args: [{
2504
2632
  providedIn: 'root',
2505
2633
  }]
2506
- }], ctorParameters: () => [{ type: ScUserService }] });
2507
-
2508
- /* eslint-disable @typescript-eslint/no-unsafe-member-access,security/detect-non-literal-regexp */
2509
- /**
2510
- * Токен признака запущено ли приложение на терминале.
2511
- */
2512
- const IS_RUNNING_ON_TERMINAL = new InjectionToken('IS_RUNNING_ON_TERMINAL');
2513
- /**
2514
- * Возвращает признак, что приложение запущено на терминале, а также код склада который обслуживает этот терминал (вернет null если не идентификатор склада отсутствует).
2515
- *
2516
- * @param userAgentTerminal Регулярное выражение агента пользователя для терминала.
2517
- *
2518
- * @returns Если приложение запущено на терминале, возвращает признак этого
2519
- * и возвращает идентификатор склада привязанного к терминалу в случае его извлечения и, null в случае если склад не удалось извлечь.
2520
- */
2521
- function runningOnTerminalFactory(userAgentTerminal) {
2522
- const isRunningOnTerminal = userAgentTerminal.test(inject(WA_USER_AGENT));
2523
- if (isRunningOnTerminal) {
2524
- const matchResult = new RegExp(`${userAgentTerminal.source}(\\w+)`, 'i').exec(inject(WA_USER_AGENT));
2525
- if (matchResult && matchResult.length > 1) {
2526
- return { isRunningOnTerminal: isRunningOnTerminal, warehouseId: Number.parseInt(matchResult[1], 10) };
2527
- }
2528
- }
2529
- return { isRunningOnTerminal: isRunningOnTerminal, warehouseId: null };
2530
- }
2531
- /**
2532
- * Токен агента пользователя для терминала.
2533
- */
2534
- const USER_AGENT_TERMINAL = new InjectionToken('USER_AGENT_TERMINAL', {
2535
- providedIn: 'root',
2536
- factory: () => /sc_terminal_w/i,
2537
- });
2538
- /**
2539
- * Провайдеры данных о терминале.
2540
- */
2541
- const TERMINAL_PROVIDERS = [
2542
- {
2543
- provide: IS_RUNNING_ON_TERMINAL,
2544
- deps: [USER_AGENT_TERMINAL],
2545
- useFactory: runningOnTerminalFactory,
2546
- },
2547
- ];
2634
+ }] });
2548
2635
 
2549
2636
  /**
2550
2637
  * Сервис для работы со складами.
@@ -2658,18 +2745,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
2658
2745
  }], ctorParameters: () => [] });
2659
2746
 
2660
2747
  /**
2661
- * Сервис для работы с корзиной.
2748
+ * Данные о сервисе корзины.
2662
2749
  */
2663
2750
  class ScCartService {
2664
2751
  /**
2665
2752
  * Инициализирует экземпляр класса {@link ScCartService}.
2666
- *
2667
2753
  */
2668
2754
  constructor() {
2669
- /**
2670
- * {@link ReplaySubject} для содержимого корзины.
2671
- */
2672
- this.cart$ = new ReplaySubject(1);
2673
2755
  /**
2674
2756
  * Признак, что скрипт выполняется в браузере.
2675
2757
  */
@@ -2699,72 +2781,73 @@ class ScCartService {
2699
2781
  */
2700
2782
  this.userMetrikaService = inject(ScUserMetrikaService);
2701
2783
  if (this.isBrowser) {
2702
- this.user$.pipe(switchMap(() => this.updateCart$())).subscribe((cart) => {
2703
- this.cart$.next(cart);
2784
+ this.cartCachedItem$ = new ScCachedItem(Infinity, this.getCartData$(), loadingPlaceholder);
2785
+ this.user$.subscribe(() => {
2786
+ this.cartCachedItem$.update();
2704
2787
  });
2705
2788
  }
2706
2789
  else {
2707
- this.cart$.next(new ScCart());
2790
+ this.cartCachedItem$ = new ScCachedItem(Infinity, of(new ScCart()), loadingPlaceholder);
2708
2791
  }
2709
- this.cartDirections$ = inject(ScReferencesService).directions$.pipe(switchMap((directions) => this.cart$.pipe(switchMap((cart) => this.warehouseService.getWarehouseSelectChange$().pipe(map((warehouse) => directions
2710
- .map((direction) => new ScISalesDirectionCart(direction, cart.items.filter((cartItem) => !cartItem.product.isNull && !cartItem.product.isHidden && cartItem.salesDirection === direction.id), cart.directionsSum[direction.id], warehouse.id))
2711
- .filter((direction) => direction.items.length > 0 || direction.itemsOnOrder.length > 0 || direction.itemsNotInWarehouseStock.length > 0)))))));
2712
2792
  }
2713
2793
  /**
2714
- * Возвращает {@link Observable} содержимого корзины.
2794
+ * Создаёт запрос получения содержимого корзины и обновляет корзину, возвращая {@link Observable} содержимого корзины.
2715
2795
  */
2716
- getCartChange$() {
2717
- return this.cart$.asObservable();
2796
+ getCartData$() {
2797
+ return this.http.get(`${this.urls.apiUrl}/cart`).pipe(map((cartDTO) => new ScCart(cartDTO)));
2718
2798
  }
2719
2799
  /**
2720
- * Создаёт запрос получения содержимого корзины и обновляет корзину, возвращая {@link Observable} содержимого корзины.
2800
+ * Возвращает полную информацию о корзине (контекст загрузчика).
2721
2801
  */
2722
- updateCart$() {
2723
- return this.http.get(`${this.urls.apiUrl}/cart`).pipe(map((cartDTO) => new ScCart(cartDTO)), tap((cart) => {
2724
- this.cart$.next(cart);
2725
- }));
2802
+ get$() {
2803
+ return this.cartCachedItem$.item$;
2804
+ }
2805
+ /**
2806
+ * Возвращает список элементов корзины.
2807
+ */
2808
+ getItems$() {
2809
+ return this.get$().pipe(map((cart) => (cart === loadingPlaceholder ? loadingPlaceholder : cart.items)));
2726
2810
  }
2727
2811
  /**
2728
- * Создаёт запрос добавления товара в корзину и возвращает {@link Observable} содержимого корзины.
2812
+ * Добавляет продукт в корзину.
2729
2813
  *
2730
- * @param cartNewItem Новый элемент корзины.
2814
+ * @param data Данные добавляемого продукта.
2731
2815
  */
2732
- addToCart$(cartNewItem) {
2733
- return this.http.patch(`${this.urls.apiUrl}/cart`, cartNewItem).pipe(map((cartDTO) => new ScCart(cartDTO)), tap(() => {
2734
- if (cartNewItem.productId) {
2816
+ addProduct$(data) {
2817
+ return this.http.patch(`${this.urls.apiUrl}/cart`, data).pipe(map((cartDTO) => new ScCart(cartDTO)), tap(() => {
2818
+ if (data.productId) {
2735
2819
  this.userMetrikaService.emitUserMetrikaEvent({
2736
2820
  target: ScUserMetrikaGoalsEnum.cartItemAdded,
2737
- params: { product_id: cartNewItem.productId },
2821
+ params: { product_id: data.productId },
2738
2822
  });
2739
2823
  }
2740
2824
  }), tap((cart) => {
2741
- this.cart$.next(cart);
2825
+ this.cartCachedItem$.setValue(cart);
2742
2826
  }));
2743
2827
  }
2744
2828
  /**
2745
- * Создаёт запрос обновления позиции в корзине и возвращает {@link Observable} содержимого корзины.
2829
+ * Изменяет продукт в корзине.
2746
2830
  *
2747
- * @param cartItemId Идентификатор элемента корзины.
2748
- * @param cartPatchItem Новые данные элемента корзины.
2831
+ * @param id Идентификатор позиции.
2832
+ * @param patch Частичные данные для обновления.
2749
2833
  */
2750
- patchCartItem$(cartItemId, cartPatchItem) {
2751
- return this.http.patch(`${this.urls.apiUrl}/cart/${cartItemId}`, cartPatchItem).pipe(map((cartDTO) => new ScCart(cartDTO)), tap((cart) => {
2752
- this.cart$.next(cart);
2834
+ updateProduct$(id, patch) {
2835
+ return this.http.patch(`${this.urls.apiUrl}/cart/${id}`, patch).pipe(map((cartDTO) => new ScCart(cartDTO)), tap((cart) => {
2836
+ this.cartCachedItem$.setValue(cart);
2753
2837
  }));
2754
2838
  }
2755
2839
  /**
2756
- * Создаёт запрос удаления позиции из корзины и возвращает {@link Observable} содержимого корзины.
2840
+ * Удаляет продукт из корзины.
2757
2841
  *
2758
- * @param cartItem Запись корзины, которую необходимо удалить.
2842
+ * @param item Удаляемая позиция.
2759
2843
  */
2760
- deleteCartItem$(cartItem) {
2761
- return this.http.delete(`${this.urls.apiUrl}/cart/${cartItem.id}`).pipe(map((cartDTO) => new ScCart(cartDTO)), tap(() => {
2844
+ deleteProduct$(item) {
2845
+ return this.http.delete(`${this.urls.apiUrl}/cart/${item.id}`).pipe(map((cartDTO) => new ScCart(cartDTO)), tap((cart) => {
2846
+ this.cartCachedItem$.setValue(cart);
2762
2847
  this.userMetrikaService.emitUserMetrikaEvent({
2763
2848
  target: ScUserMetrikaGoalsEnum.cartItemDeleted,
2764
- params: { product_id: cartItem.product.id },
2849
+ params: { product_id: item.product.id },
2765
2850
  });
2766
- }), tap((cart) => {
2767
- this.cart$.next(cart);
2768
2851
  }));
2769
2852
  }
2770
2853
  /**
@@ -2777,20 +2860,22 @@ class ScCartService {
2777
2860
  });
2778
2861
  }), tap(() => {
2779
2862
  this.uiService.removeAllNewOrdersMetadata();
2780
- this.cart$.next(new ScCart());
2863
+ this.cartCachedItem$.setValue(new ScCart());
2781
2864
  }));
2782
2865
  }
2783
2866
  /**
2784
- * Возвращает {@link Observable} содержимого корзины по направлениям продаж.
2867
+ * Обновляет корзину.
2785
2868
  */
2786
- getCartDirectionsChange$() {
2787
- return this.cartDirections$;
2869
+ updateCart() {
2870
+ this.cartCachedItem$.update();
2788
2871
  }
2789
2872
  /**
2790
2873
  * Возвращает {@link Observable} позиций в корзине с товарами, которые были удалены из прайс-лита и больше не продаются.
2874
+ *
2875
+ * @deprecated
2791
2876
  */
2792
2877
  getNullCartItems$() {
2793
- return this.getCartChange$().pipe(map((cart) => cart.items.filter((item) => item.product.isNull || item.product.isHidden)));
2878
+ return this.get$().pipe(map((cart) => (cart === loadingPlaceholder ? loadingPlaceholder : cart.items.filter((item) => item.product.isNull || item.product.isHidden))));
2794
2879
  }
2795
2880
  /**
2796
2881
  * Возвращает объект {@link ScCart} корзины, созданный из объекта заказа.
@@ -2800,7 +2885,7 @@ class ScCartService {
2800
2885
  // eslint-disable-next-line class-methods-use-this
2801
2886
  getCartByOrder(order) {
2802
2887
  return {
2803
- items: order.products ?? [],
2888
+ items: order.products,
2804
2889
  resultSum: { rub: order.sum },
2805
2890
  directionsSum: { [order.direction]: new ScSum(order.sum) },
2806
2891
  };
@@ -2822,7 +2907,7 @@ class ScCartService {
2822
2907
  */
2823
2908
  addProductsFromCsv$(file) {
2824
2909
  return this.http.post(`${this.urls.apiUrl}/cart/csv`, { file }).pipe(map((cartDTO) => new ScCart(cartDTO)), tap((cart) => {
2825
- this.cart$.next(cart);
2910
+ this.cartCachedItem$.setValue(cart);
2826
2911
  this.userMetrikaService.emitUserMetrikaEvent({
2827
2912
  target: ScUserMetrikaGoalsEnum.cartCsvUpload,
2828
2913
  });
@@ -2946,40 +3031,6 @@ class ScCachedData {
2946
3031
  }
2947
3032
  }
2948
3033
 
2949
- /**
2950
- * Модель кэшированных данных.
2951
- */
2952
- class ScCachedItem {
2953
- /**
2954
- * Инициализирует экземпляр класса {@link ScCachedItem}.
2955
- *
2956
- * @param lifeTime Время жизни записи в ms.
2957
- * @param item$ {@link Observable} запроса кэшируемых данных.
2958
- */
2959
- constructor(lifeTime, item$) {
2960
- /**
2961
- * {@link Observable} обновления данных.
2962
- */
2963
- this.update$ = new BehaviorSubject(undefined);
2964
- this.item$ = this.update$.pipe(switchMap(() => item$.pipe(tap(() => {
2965
- this.cachedUntil = Date.now() + lifeTime;
2966
- }), startWith(null))), materialize(), shareReplay(1), dematerialize());
2967
- }
2968
- /**
2969
- * Возвращает признак того, что кэшированные данные актуальны.
2970
- */
2971
- cachedDataIsActual() {
2972
- return !this.cachedUntil || this.cachedUntil > Date.now();
2973
- }
2974
- /**
2975
- * Выполняет обновления {@link Observable} запроса кэшируемых данных.
2976
- */
2977
- update() {
2978
- this.cachedUntil = undefined;
2979
- this.update$.next();
2980
- }
2981
- }
2982
-
2983
3034
  /**
2984
3035
  * Данные о виртуальной категории.
2985
3036
  */
@@ -3217,7 +3268,7 @@ class ScCatalogService {
3217
3268
  getVirtualCategoryCached$(slug) {
3218
3269
  let cachedItem = this.virtualCategoryMap.get(slug);
3219
3270
  if (!cachedItem) {
3220
- cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.http.get(`${this.urls.apiUrl}/catalog/v-categories/${slug}`).pipe(map((category) => new ScVirtualCategory(category))));
3271
+ cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.http.get(`${this.urls.apiUrl}/catalog/v-categories/${slug}`).pipe(map((category) => new ScVirtualCategory(category))), null);
3221
3272
  this.virtualCategoryMap.set(slug, cachedItem);
3222
3273
  }
3223
3274
  if (!cachedItem.cachedDataIsActual()) {
@@ -3237,7 +3288,7 @@ class ScCatalogService {
3237
3288
  }
3238
3289
  let cachedItem = this.categoryMap.get(categoryIdOrSlug?.toString());
3239
3290
  if (!cachedItem) {
3240
- cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getCategoryData$(categoryIdOrSlug));
3291
+ cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getCategoryData$(categoryIdOrSlug), null);
3241
3292
  this.categoryMap.set(categoryIdOrSlug?.toString(), cachedItem);
3242
3293
  }
3243
3294
  if (!cachedItem.cachedDataIsActual()) {
@@ -3283,7 +3334,7 @@ class ScCatalogService {
3283
3334
  .get(`${this.urls.apiUrl}/catalog/products/${product.id}/price-history`, {
3284
3335
  context: SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT,
3285
3336
  })
3286
- .pipe(catchError(() => of({}))));
3337
+ .pipe(catchError(() => of({}))), null);
3287
3338
  this.productHistoryMap.set(product.id.toString(), cachedItem);
3288
3339
  }
3289
3340
  return cachedItem.item$;
@@ -3321,7 +3372,7 @@ class ScCatalogService {
3321
3372
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
3322
3373
  let cachedItem = this.categoryProductsMap.get(cachedKey.toString());
3323
3374
  if (!cachedItem) {
3324
- cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getProducts$(params));
3375
+ cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getProducts$(params), null);
3325
3376
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-call
3326
3377
  this.categoryProductsMap.set(cachedKey.toString(), cachedItem);
3327
3378
  }
@@ -3350,7 +3401,7 @@ class ScCatalogService {
3350
3401
  }
3351
3402
  let cachedItem = this.productMap.get(productIdOrSlug.toString());
3352
3403
  if (!cachedItem) {
3353
- cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getProductData$(productIdOrSlug));
3404
+ cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getProductData$(productIdOrSlug), null);
3354
3405
  this.productMap.set(productIdOrSlug.toString(), cachedItem);
3355
3406
  }
3356
3407
  if (!cachedItem.cachedDataIsActual()) {
@@ -3540,7 +3591,8 @@ class ScRecommendationService {
3540
3591
  .get(`${this.urls.apiUrl}/catalog/categories/${categoryIdOrSlug}/recommendations`, {
3541
3592
  context: SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT,
3542
3593
  })
3543
- .pipe(catchError(() => of([])), map((productsDTO) => productsDTO.map((product) => new ScProduct(product)))));
3594
+ .pipe(catchError(() => of([])), map((productsDTO) => productsDTO.map((product) => new ScProduct(product))))
3595
+ .pipe(startWith(null)), null);
3544
3596
  this.productsByCategoryMap.set(categoryIdOrSlug.toString(), cachedItem);
3545
3597
  }
3546
3598
  return cachedItem.item$;
@@ -3558,7 +3610,8 @@ class ScRecommendationService {
3558
3610
  .get(`${this.urls.apiUrl}/catalog/products/${productIdOrSlug}/recommendations`, {
3559
3611
  context: SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT,
3560
3612
  })
3561
- .pipe(catchError(() => of([])), map((productsDTO) => productsDTO.map((product) => new ScProduct(product)))));
3613
+ .pipe(catchError(() => of([])), map((productsDTO) => productsDTO.map((product) => new ScProduct(product))))
3614
+ .pipe(startWith(null)), null);
3562
3615
  this.productsByProductMap.set(productIdOrSlug.toString(), cachedItem);
3563
3616
  }
3564
3617
  return cachedItem.item$;
@@ -3580,12 +3633,10 @@ class ScRecommendationService {
3580
3633
  * Создает запрос на получение списка рекомендованных товаров для корзины клиента.
3581
3634
  */
3582
3635
  getProductsByCart$() {
3583
- return this.cartService.getCartChange$().pipe(
3584
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-conversion
3585
- map((cart) => cart.items.map((item) => Number(item.product.id))),
3636
+ return this.cartService.get$().pipe(map((cart) => (cart !== loadingPlaceholder && 'items' in cart ? cart.items.map((item) => item.product.id) : [])),
3586
3637
  // Отфильтровываем повторения. Они возникнут если было изменено количество товара без удаления\добавления новых товаров.
3587
3638
  // eslint-disable-next-line sonarjs/no-misleading-array-reverse
3588
- distinctUntilChanged((previous, current) => JSON.stringify(previous.sort((a, b) => a - b)) === JSON.stringify(current.sort((a, b) => a - b))), switchMap((productIds) => this.getProductsByProductIds$(productIds).pipe(startWith(null))));
3639
+ distinctUntilChanged((previous, current) => JSON.stringify([...previous].sort((a, b) => a - b)) === JSON.stringify([...current].sort((a, b) => a - b))), switchMap((productIds) => this.getProductsByProductIds$(productIds).pipe(startWith(null))));
3589
3640
  }
3590
3641
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScRecommendationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3591
3642
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScRecommendationService, providedIn: 'root' }); }
@@ -3609,10 +3660,34 @@ var ScRouteKeys;
3609
3660
  * Ключ главной страницы.
3610
3661
  */
3611
3662
  ScRouteKeys["landing"] = "landing";
3663
+ /**
3664
+ * Ключ страницы лендинга подоконников.
3665
+ */
3666
+ ScRouteKeys["landingWindowsill"] = "landing_windowsill";
3667
+ /**
3668
+ * Ключ страницы лендинга москитных сеток.
3669
+ */
3670
+ ScRouteKeys["landingMosquito"] = "landing_mosquito";
3612
3671
  /**
3613
3672
  * Ключ страницы контактов и реквизитов.
3614
3673
  */
3615
3674
  ScRouteKeys["contacts"] = "contacts";
3675
+ /**
3676
+ * Ключ страницы "Общих" контактов.
3677
+ */
3678
+ ScRouteKeys["personal"] = "personal";
3679
+ /**
3680
+ * Ключ страницы карты обратной связи.
3681
+ */
3682
+ ScRouteKeys["retailsMap"] = "retails_map";
3683
+ /**
3684
+ * Ключ карточки контактов менеджера.
3685
+ */
3686
+ ScRouteKeys["managerCard"] = "manager_card";
3687
+ /**
3688
+ * Ключ страницы менеджеров в разделе контактов.
3689
+ */
3690
+ ScRouteKeys["contactsDirectionManagers"] = "contacts_direction_managers";
3616
3691
  /**
3617
3692
  * Ключ страницы публичной оферты.
3618
3693
  */
@@ -3622,17 +3697,113 @@ var ScRouteKeys;
3622
3697
  */
3623
3698
  ScRouteKeys["personalDataProcessingPolicy"] = "personal_data_processing_policy";
3624
3699
  /**
3625
- * Ключ страницы ошибок.
3700
+ * Ключ страницы политики конфиденциальности.
3701
+ */
3702
+ ScRouteKeys["privacyPolicy"] = "privacy_policy";
3703
+ /**
3704
+ * Ключ страницы часто задаваемых вопросов.
3705
+ */
3706
+ ScRouteKeys["frequentlyAskedQuestions"] = "frequently-asked-questions";
3707
+ /**
3708
+ * Ключ страницы ошибок.
3709
+ */
3710
+ ScRouteKeys["error"] = "error";
3711
+ /**
3712
+ * Ключ файлов и документов.
3713
+ */
3714
+ ScRouteKeys["files"] = "files";
3715
+ /**
3716
+ * Ключ списка заказов.
3717
+ */
3718
+ ScRouteKeys["orders"] = "orders";
3719
+ /**
3720
+ * Ключ оформления заказа.
3721
+ */
3722
+ ScRouteKeys["newOrder"] = "new_order";
3723
+ /**
3724
+ * Ключ оформления заказа из черновика.
3725
+ */
3726
+ ScRouteKeys["newOrderDraft"] = "new_order_draft";
3727
+ /**
3728
+ * Ключ заказа.
3729
+ */
3730
+ ScRouteKeys["order"] = "order";
3731
+ /**
3732
+ * Ключ списка черновиков заказов.
3733
+ */
3734
+ ScRouteKeys["drafts"] = "drafts";
3735
+ /**
3736
+ * Ключ черновика заказа.
3737
+ */
3738
+ ScRouteKeys["draft"] = "draft";
3739
+ /**
3740
+ * Ключ личного кабинета.
3741
+ */
3742
+ ScRouteKeys["profile"] = "profile";
3743
+ /**
3744
+ * Ключ рекламаций.
3745
+ */
3746
+ ScRouteKeys["reclamations"] = "reclamations";
3747
+ /**
3748
+ * Ключ рекламации.
3749
+ */
3750
+ ScRouteKeys["reclamation"] = "reclamation";
3751
+ /**
3752
+ * Ключ корзины.
3753
+ */
3754
+ ScRouteKeys["cart"] = "cart";
3755
+ /**
3756
+ * Ключ корневого каталога.
3757
+ */
3758
+ ScRouteKeys["catalog"] = "catalog";
3759
+ /**
3760
+ * Ключ страницы товара в каталоге.
3761
+ */
3762
+ ScRouteKeys["productInfo"] = "product_info_page";
3763
+ /**
3764
+ * Ключ страницы "Статус оплаты".
3765
+ */
3766
+ ScRouteKeys["paymentStatus"] = "payment_status";
3767
+ /**
3768
+ * Ключ категории в каталоге.
3769
+ */
3770
+ ScRouteKeys["categoryContent"] = "category_content";
3771
+ /**
3772
+ * Ключ результатов поиска в каталоге.
3773
+ */
3774
+ ScRouteKeys["search"] = "search";
3775
+ /**
3776
+ * Ключ избранных товаров и категорий.
3777
+ */
3778
+ ScRouteKeys["favorite"] = "favorite";
3779
+ /**
3780
+ * Ключ списка новостей.
3781
+ */
3782
+ ScRouteKeys["newsList"] = "news_list";
3783
+ /**
3784
+ * Ключ страницы деталей новости.
3785
+ */
3786
+ ScRouteKeys["news"] = "news";
3787
+ /**
3788
+ * Ключ страницы вакансий.
3789
+ */
3790
+ ScRouteKeys["vacancies"] = "vacancies";
3791
+ /**
3792
+ * Ключ страницы истории покупок.
3793
+ */
3794
+ ScRouteKeys["previouslyOrdered"] = "previously_ordered";
3795
+ /**
3796
+ * Ключ страницы скидок.
3626
3797
  */
3627
- ScRouteKeys["error"] = "error";
3798
+ ScRouteKeys["discounted"] = "discounted";
3628
3799
  /**
3629
- * Ключ страницы файлы и документы.
3800
+ * Ключ виртуального каталога.
3630
3801
  */
3631
- ScRouteKeys["files"] = "files";
3802
+ ScRouteKeys["virtualCatalog"] = "virtual_catalog";
3632
3803
  /**
3633
- * Ключ страницы вакансий.
3804
+ * Ключ посадочной страницы подоконников.
3634
3805
  */
3635
- ScRouteKeys["vacancies"] = "vacancies";
3806
+ ScRouteKeys["windowsill"] = "windowsill";
3636
3807
  })(ScRouteKeys || (ScRouteKeys = {}));
3637
3808
 
3638
3809
  /**
@@ -4561,7 +4732,7 @@ class ScContragentService {
4561
4732
  let cachedItem = this.contactsService.contragentContactsMap.get(contragentId);
4562
4733
  if (!cachedItem) {
4563
4734
  // Устанавливаем время жизни cachedItem равное, потому что нам не важно время жизни. Нам нужен функционал update() в будущем.
4564
- cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/contragents/${contragentId}/contacts`));
4735
+ cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/contragents/${contragentId}/contacts`).pipe(startWith(null)), null);
4565
4736
  this.contactsService.contragentContactsMap.set(contragentId, cachedItem);
4566
4737
  }
4567
4738
  return cachedItem.item$;
@@ -4594,7 +4765,7 @@ class ScContragentService {
4594
4765
  let cachedItem = this.contragentBankAccountsMap.get(contragentId);
4595
4766
  if (!cachedItem) {
4596
4767
  // Устанавливаем время жизни cachedItem равное, потому что нам не важно время жизни. Нам нужен функционал update().
4597
- cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/contragents/${contragentId}/bank-accounts`));
4768
+ cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/contragents/${contragentId}/bank-accounts`).pipe(startWith(null)), null);
4598
4769
  this.contragentBankAccountsMap.set(contragentId, cachedItem);
4599
4770
  }
4600
4771
  return cachedItem.item$;
@@ -4706,7 +4877,9 @@ class ScDeliveryAddressService {
4706
4877
  let cachedItem = this.contactsService.deliveryAddressContactsMap.get(addressId);
4707
4878
  if (!cachedItem) {
4708
4879
  // Устанавливаем время жизни cachedItem равное, потому что нам не важно время жизни. Нам нужен функционал update().
4709
- cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/delivery-addresses/${addressId}/contacts`));
4880
+ cachedItem = new ScCachedItem(0, this.http
4881
+ .get(`${this.urls.apiUrl}/user/delivery-addresses/${addressId}/contacts`)
4882
+ .pipe(startWith(null)), null);
4710
4883
  this.contactsService.deliveryAddressContactsMap.set(addressId, cachedItem);
4711
4884
  }
4712
4885
  return cachedItem.item$;
@@ -5617,10 +5790,6 @@ var ScOpfList;
5617
5790
  // eslint-disable-next-line no-shadow
5618
5791
  var ScOrderStateStatus;
5619
5792
  (function (ScOrderStateStatus) {
5620
- /**
5621
- * Черновик.
5622
- */
5623
- ScOrderStateStatus[ScOrderStateStatus["draft"] = 0] = "draft";
5624
5793
  /**
5625
5794
  * Принято в обработку.
5626
5795
  */
@@ -6143,13 +6312,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
6143
6312
  }], ctorParameters: () => [] });
6144
6313
 
6145
6314
  /**
6146
- * Модель данных о бесплатной доставке.
6315
+ * Данные о стоимости доставки.
6147
6316
  */
6148
6317
  class ScDeliveryCost {
6149
6318
  /**
6150
6319
  * Инициализирует экземпляр класса {@link ScDeliveryCost}.
6151
6320
  *
6152
- * @param deliveryCost DTO данных о бесплатной доставке.
6321
+ * @param deliveryCost Данные о стоимости доставки (DTO).
6153
6322
  * @param deliveryDate Дата доставки.
6154
6323
  */
6155
6324
  constructor(deliveryCost, deliveryDate) {
@@ -6161,6 +6330,137 @@ class ScDeliveryCost {
6161
6330
  }
6162
6331
  }
6163
6332
 
6333
+ /**
6334
+ * Базовые данные о заказе.
6335
+ */
6336
+ class ScOrderBase {
6337
+ /**
6338
+ * Инициализирует экземпляр класса {@link ScOrderBase}.
6339
+ *
6340
+ * @param data Данные для первоначальной инициализации.
6341
+ */
6342
+ constructor(data) {
6343
+ this.id = data.id;
6344
+ this.createdAt = data.createdAt;
6345
+ this.sum = data.sum;
6346
+ }
6347
+ /**
6348
+ * @inheritDoc
6349
+ */
6350
+ getSumStr() {
6351
+ return this.sum && this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6352
+ }
6353
+ /**
6354
+ * @inheritDoc
6355
+ */
6356
+ getSumMessage() {
6357
+ return this.sum === 0 ? 'Цена требует уточнения' : '';
6358
+ }
6359
+ }
6360
+
6361
+ /**
6362
+ * Данные о коммерческом предложении/черновике заказа.
6363
+ */
6364
+ class ScOrderDraft {
6365
+ /**
6366
+ * Инициализирует экземпляр класса {@link ScOrderDraft}.
6367
+ *
6368
+ * @param data Данные для первоначальной инициализации.
6369
+ */
6370
+ constructor(data) {
6371
+ /**
6372
+ * Дата последнего обновления данных.
6373
+ */
6374
+ this.lastUpdateDate = new Date();
6375
+ this.id = data.id;
6376
+ this.name = data.name;
6377
+ this.type = data.type;
6378
+ this.createdAt = data.createdAt;
6379
+ this.sum = data.sum;
6380
+ this.products = data.products.map((item) => new ScOrderItem(item));
6381
+ }
6382
+ /**
6383
+ * @inheritDoc
6384
+ */
6385
+ getSumStr() {
6386
+ return this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6387
+ }
6388
+ /**
6389
+ * @inheritDoc
6390
+ */
6391
+ getSumMessage() {
6392
+ return this.sum === 0 ? 'Цена требует уточнения' : '';
6393
+ }
6394
+ /**
6395
+ * @inheritDoc
6396
+ */
6397
+ cachedDataIsActual(lifeTime) {
6398
+ return this.lastUpdateDate.getTime() >= Date.now() - lifeTime;
6399
+ }
6400
+ /**
6401
+ * @inheritDoc
6402
+ */
6403
+ updateData(offer) {
6404
+ this.name = offer.name;
6405
+ this.type = offer.type;
6406
+ this.sum = offer.sum;
6407
+ this.products = offer.products;
6408
+ this.lastUpdateDate = new Date();
6409
+ }
6410
+ /**
6411
+ * @inheritDoc
6412
+ */
6413
+ updateDataFromShortOffer(offer) {
6414
+ this.name = offer.name;
6415
+ this.type = offer.type;
6416
+ }
6417
+ }
6418
+
6419
+ /**
6420
+ * Данные о кратком коммерческом предложении/черновике заказа.
6421
+ */
6422
+ class ScOrderDraftShort extends ScOrderBase {
6423
+ /**
6424
+ * Инициализирует экземпляр класса {@link ScOrderDraftShort}.
6425
+ *
6426
+ * @param data Данные для первоначальной инициализации.
6427
+ */
6428
+ constructor(data) {
6429
+ super(data);
6430
+ this.name = data.name;
6431
+ this.type = data.type;
6432
+ }
6433
+ }
6434
+
6435
+ /**
6436
+ * Данные о кратком заказе.
6437
+ */
6438
+ class ScOrderShort extends ScOrderBase {
6439
+ /**
6440
+ * Инициализирует экземпляр класса {@link ScOrderShort}.
6441
+ *
6442
+ * @param data Данные для первоначальной инициализации.
6443
+ */
6444
+ constructor(data) {
6445
+ super(data);
6446
+ this.status = data.status;
6447
+ this.direction = data.direction;
6448
+ this.payment = data.payment;
6449
+ this.numberDoc = data.numberDoc;
6450
+ this.barcode = data.barcode;
6451
+ }
6452
+ /**
6453
+ * @inheritDoc
6454
+ */
6455
+ updateData(order) {
6456
+ this.status = order.status;
6457
+ this.direction = order.direction;
6458
+ this.payment = order.payment;
6459
+ this.sum = order.sum;
6460
+ this.delivery = order.delivery;
6461
+ }
6462
+ }
6463
+
6164
6464
  /**
6165
6465
  * Перечисление типов доставки заказа.
6166
6466
  */
@@ -6177,6 +6477,22 @@ var ScDeliveryType;
6177
6477
  ScDeliveryType[ScDeliveryType["delivery"] = 2] = "delivery";
6178
6478
  })(ScDeliveryType || (ScDeliveryType = {}));
6179
6479
 
6480
+ /**
6481
+ * Перечисление типов коммерческих предложений/черновиков заказа.
6482
+ */
6483
+ // eslint-disable-next-line no-shadow
6484
+ var ScOrderDraftType;
6485
+ (function (ScOrderDraftType) {
6486
+ /**
6487
+ * Коммерческое предложение.
6488
+ */
6489
+ ScOrderDraftType["offer"] = "offer";
6490
+ /**
6491
+ * Заказ-черновик.
6492
+ */
6493
+ ScOrderDraftType["draft"] = "draft";
6494
+ })(ScOrderDraftType || (ScOrderDraftType = {}));
6495
+
6180
6496
  /**
6181
6497
  * Перечисление типов отплат заказа.
6182
6498
  */
@@ -6210,47 +6526,42 @@ var ScPaymentType;
6210
6526
  })(ScPaymentType || (ScPaymentType = {}));
6211
6527
 
6212
6528
  /**
6213
- * Полная информация о заказе.
6529
+ * Данные о заказе.
6214
6530
  */
6215
- class ScOrder {
6531
+ class ScOrder extends ScOrderShort {
6216
6532
  /**
6217
6533
  * Инициализирует экземпляр класса {@link ScOrder}.
6218
6534
  *
6219
- * @param orderDTO DTO полная информация о заказе.
6220
- */
6221
- constructor(orderDTO) {
6222
- this.id = orderDTO.id;
6223
- this.createdAt = orderDTO.createdAt;
6224
- this.status = orderDTO.status;
6225
- this.direction = orderDTO.direction;
6226
- this.payment = orderDTO.payment;
6227
- this.sum = orderDTO.sum;
6228
- this.products = orderDTO.products?.map((productDTO) => new ScCartItem(productDTO));
6229
- this.history = orderDTO.history;
6230
- this.invoices = orderDTO.invoices;
6231
- this.comment = orderDTO.comment;
6232
- this.image = orderDTO.image;
6233
- this.delivery = orderDTO.delivery;
6234
- this.contragent = orderDTO.contragent;
6235
- this.attachedUser = orderDTO.attachedUser;
6236
- this.numberDoc = orderDTO.numberDoc;
6237
- this.barcode = orderDTO.barcode;
6535
+ * @param data Данные для первоначальной инициализации.
6536
+ */
6537
+ constructor(data) {
6538
+ super(data);
6539
+ this.history = data.history;
6540
+ this.invoices = data.invoices;
6541
+ this.comment = data.comment;
6542
+ this.image = data.image;
6543
+ this.delivery = data.delivery;
6544
+ this.contragent = data.contragent;
6545
+ this.attachedUser = data.attachedUser;
6546
+ this.numberDoc = data.numberDoc;
6547
+ this.barcode = data.barcode;
6238
6548
  this.lastUpdateDate = new Date();
6549
+ this.products = data.products.map((item) => new ScOrderItem(item));
6239
6550
  }
6240
6551
  /**
6241
- * Тип оплаты.
6552
+ * @inheritDoc
6242
6553
  */
6243
6554
  get paymentType() {
6244
6555
  return this.payment.type;
6245
6556
  }
6246
6557
  /**
6247
- * Тип доставки.
6558
+ * @inheritDoc
6248
6559
  */
6249
6560
  get deliveryType() {
6250
6561
  return this.delivery.type;
6251
6562
  }
6252
6563
  /**
6253
- * Признак, что заказ можно оплатить online.
6564
+ * @inheritDoc
6254
6565
  */
6255
6566
  get isPayable() {
6256
6567
  return ([ScOrderStateStatus.new, ScOrderStateStatus.worked_out, ScOrderStateStatus.pending].includes(this.status) &&
@@ -6260,134 +6571,242 @@ class ScOrder {
6260
6571
  this.payment.onlinePaymentLink !== undefined);
6261
6572
  }
6262
6573
  /**
6263
- * Признак черновика заказа.
6264
- */
6265
- get isDraft() {
6266
- return this.status === ScOrderStateStatus.draft;
6267
- }
6268
- /**
6269
- * Признак, что заказ будет подлежать online-оплате.
6574
+ * @inheritDoc
6270
6575
  */
6271
6576
  get isPayableSoon() {
6272
- return (![ScOrderStateStatus.draft, ScOrderStateStatus.declined, ScOrderStateStatus.deleted, ScOrderStateStatus.completed].includes(this.status) &&
6577
+ return (![ScOrderStateStatus.declined, ScOrderStateStatus.deleted, ScOrderStateStatus.completed].includes(this.status) &&
6273
6578
  !this.isPayable &&
6274
6579
  this.payment.type === ScPaymentType.online);
6275
6580
  }
6276
6581
  /**
6277
- * Признак, что заказ завершён.
6582
+ * @inheritDoc
6278
6583
  */
6279
6584
  get isCompleted() {
6280
6585
  return [ScOrderStateStatus.completed, ScOrderStateStatus.declined, ScOrderStateStatus.deleted].includes(this.status);
6281
6586
  }
6282
6587
  /**
6283
- * Признак нового заказа.
6588
+ * @inheritDoc
6284
6589
  */
6285
6590
  get isNew() {
6286
6591
  return this.status === ScOrderStateStatus.new;
6287
6592
  }
6288
6593
  /**
6289
- * Возвращает сумму заказа в виде строки. Если стоимость отсутствует, то вернёт '-'.
6290
- */
6291
- getSumStr() {
6292
- return this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6293
- }
6294
- /**
6295
- * Возвращает сообщение о необходимости уточнить сумму заказа или пустую строку.
6296
- */
6297
- getSumMessage() {
6298
- return this.sum === 0 ? 'Цена требует уточнения' : '';
6299
- }
6300
- /**
6301
- * Возвращает признак того, что срок жизни информации о заказе не истёк.
6302
- *
6303
- * @param orderLifeTime Срок жизни данных в ms.
6594
+ * @inheritDoc
6304
6595
  */
6305
6596
  cachedDataIsActual(orderLifeTime) {
6306
6597
  return this.lastUpdateDate.getTime() >= Date.now() - orderLifeTime;
6307
6598
  }
6308
6599
  /**
6309
- * Обновляет данные полного заказа.
6310
- *
6311
- * @param order Полная информация о заказе.
6600
+ * @inheritDoc
6312
6601
  */
6313
6602
  updateData(order) {
6314
- this.status = order.status;
6315
- this.direction = order.direction;
6316
- this.payment = order.payment;
6317
- this.sum = order.sum;
6603
+ super.updateData(order);
6318
6604
  this.products = order.products;
6319
6605
  this.history = order.history;
6320
6606
  this.invoices = order.invoices;
6321
6607
  this.comment = order.comment;
6322
6608
  this.image = order.image;
6323
- this.delivery = order.delivery;
6324
6609
  this.contragent = order.contragent;
6325
6610
  this.attachedUser = order.attachedUser;
6326
6611
  this.lastUpdateDate = new Date();
6327
6612
  }
6328
6613
  /**
6329
- * Обновляет данные полного заказа данными краткой информации о заказе. Не обновляете дату последнего обновления.
6330
- *
6331
- * @param order Краткая информация о заказе.
6614
+ * @inheritDoc
6332
6615
  */
6333
6616
  updateDataFromShortOrder(order) {
6334
6617
  this.status = order.status;
6335
6618
  this.direction = order.direction;
6336
- this.payment = order.payment;
6337
6619
  this.sum = order.sum;
6338
- this.delivery.type = order.deliveryType;
6339
6620
  }
6340
6621
  }
6341
6622
 
6623
+ /* eslint-disable no-param-reassign */
6342
6624
  /**
6343
- * Краткая информация о заказе.
6625
+ * Данные о сервисе коммерческих предложений и черновиков заказов.
6344
6626
  */
6345
- class ScOrderShort {
6627
+ class ScOrderDraftsService {
6628
+ /**
6629
+ * Инициализирует экземпляр класса {@link ScOrderDraftsService}.
6630
+ */
6631
+ constructor() {
6632
+ /**
6633
+ * HTTP-клиент.
6634
+ */
6635
+ this.http = inject(HttpClient);
6636
+ /**
6637
+ * Список ссылок приложения.
6638
+ */
6639
+ this.urls = inject(SC_URLS);
6640
+ /**
6641
+ * {@link Observable} данных о текущем пользователе.
6642
+ */
6643
+ this.user$ = inject(SC_USER_INFO);
6644
+ /**
6645
+ * Интервалы обновления данных.
6646
+ */
6647
+ this.updateInterval = inject(SC_UPDATE_INTERVAL);
6648
+ /**
6649
+ * Сервис для работы с корзиной.
6650
+ */
6651
+ this.cartService = inject(ScCartService);
6652
+ /**
6653
+ * Сервис для сбора метрик о действиях пользователей.
6654
+ */
6655
+ this.userMetrikaService = inject(ScUserMetrikaService);
6656
+ /**
6657
+ * Коллекция пар ключ-значение для кэшированных коммерческих предложений/черновиков пользователя.
6658
+ */
6659
+ this.offerMap = new Map();
6660
+ this.user$.pipe(filter((user) => user.isGuest)).subscribe(() => {
6661
+ this.offerMap.clear();
6662
+ });
6663
+ }
6346
6664
  /**
6347
- * Инициализирует экземпляр класса {@link ScIOrderShortDTO}.
6665
+ * Возвращает список коммерческих предложений/черновиков с пагинацией.
6348
6666
  *
6349
- * @param orderDTO DTO Краткая информация о заказе.
6667
+ * @param params Параметры запроса получения списка.
6350
6668
  */
6351
- constructor(orderDTO) {
6352
- this.id = orderDTO.id;
6353
- this.createdAt = orderDTO.createdAt;
6354
- this.status = orderDTO.status;
6355
- this.direction = orderDTO.direction;
6356
- this.payment = orderDTO.payment;
6357
- this.deliveryType = orderDTO.deliveryType;
6358
- this.sum = orderDTO.sum;
6359
- this.numberDoc = orderDTO.numberDoc;
6360
- this.barcode = orderDTO.barcode;
6669
+ getList$(params) {
6670
+ return this.http.get(`${this.urls.apiUrl}/orders/offers`, { params: params }).pipe(map((offersPaginateDTO) => {
6671
+ offersPaginateDTO.data = offersPaginateDTO.data.map((item) => new ScOrderDraftShort(item));
6672
+ return offersPaginateDTO;
6673
+ }));
6361
6674
  }
6362
6675
  /**
6363
- * Возвращает сумму заказа в виде строки. Если стоимость отсутствует, то вернёт '-'.
6676
+ * Создаёт новое коммерческое предложение/черновик заказа.
6677
+ *
6678
+ * @param data Данные для создания.
6364
6679
  */
6365
- getSumStr() {
6366
- return this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6680
+ create$(data) {
6681
+ return this.http.post(`${this.urls.apiUrl}/orders/offers`, data).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6682
+ this.userMetrikaService.emitUserMetrikaEvent({
6683
+ target: ScUserMetrikaGoalsEnum.orderDraftCreated,
6684
+ params: { offer_id: offer.id },
6685
+ });
6686
+ this.cartService.updateCart();
6687
+ this.offerMap.set(offer.id, new ScCachedItem(this.updateInterval.orderData, of(offer), loadingPlaceholder));
6688
+ }));
6367
6689
  }
6368
6690
  /**
6369
- * Возвращает сообщение о необходимости уточнить сумму заказа или пустую строку.
6691
+ * Возвращает полную информацию о коммерческом предложении/черновике.
6692
+ *
6693
+ * @param draftId Идентификатор записи.
6694
+ * @param cacheable Признак возможности получения из кэшированных данных.
6370
6695
  */
6371
- getSumMessage() {
6372
- return this.sum === 0 ? 'Цена требует уточнения' : '';
6696
+ get$(draftId, cacheable = true) {
6697
+ let cachedItem = this.offerMap.get(draftId);
6698
+ if (!cachedItem) {
6699
+ cachedItem = new ScCachedItem(this.updateInterval.orderData, this.http.get(`${this.urls.apiUrl}/orders/offers/${draftId}`).pipe(map((data) => new ScOrderDraft(data))), loadingPlaceholder);
6700
+ if (cacheable) {
6701
+ this.offerMap.set(draftId, cachedItem);
6702
+ }
6703
+ }
6704
+ if (cacheable && !cachedItem.cachedDataIsActual()) {
6705
+ cachedItem.update();
6706
+ }
6707
+ return cachedItem.item$;
6373
6708
  }
6374
6709
  /**
6375
- * Обновляет данные заказа.
6710
+ * Возвращает список элементов коммерческого предложения/черновика.
6376
6711
  *
6377
- * @param order Краткая информация о заказе.
6712
+ * @param id Идентификатор коммерческого предложения/черновика.
6378
6713
  */
6379
- updateData(order) {
6380
- this.status = order.status;
6381
- this.direction = order.direction;
6382
- this.payment = order.payment;
6383
- this.sum = order.sum;
6384
- this.deliveryType = order.deliveryType;
6714
+ getItems$(id) {
6715
+ return this.get$(id).pipe(map((draft) => (draft === loadingPlaceholder ? loadingPlaceholder : draft.products)));
6716
+ }
6717
+ /**
6718
+ * Обновляет данные коммерческого предложения/черновика.
6719
+ *
6720
+ * @param draftId Идентификатор записи.
6721
+ * @param patch Данные для обновления.
6722
+ */
6723
+ update$(draftId, patch) {
6724
+ const cachedItem = this.offerMap.get(draftId);
6725
+ return this.http.patch(`${this.urls.apiUrl}/orders/offers/${draftId}`, patch).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6726
+ this.userMetrikaService.emitUserMetrikaEvent({
6727
+ target: ScUserMetrikaGoalsEnum.orderDraftUpdated,
6728
+ params: { offer_id: draftId },
6729
+ });
6730
+ cachedItem?.setValue(offer);
6731
+ }));
6732
+ }
6733
+ /**
6734
+ * Удаляет коммерческое предложение/черновик.
6735
+ *
6736
+ * @param offerId Идентификатор записи.
6737
+ */
6738
+ delete$(offerId) {
6739
+ return this.http.delete(`${this.urls.apiUrl}/orders/offers/${offerId}`).pipe(tap(() => {
6740
+ this.userMetrikaService.emitUserMetrikaEvent({
6741
+ target: ScUserMetrikaGoalsEnum.orderDraftDeleted,
6742
+ params: { offer_id: offerId },
6743
+ });
6744
+ this.offerMap.delete(offerId);
6745
+ }));
6746
+ }
6747
+ /**
6748
+ * Создаёт заказ на основе коммерческого предложения/черновика.
6749
+ *
6750
+ * @param offerId Идентификатор записи.
6751
+ * @param data Данные заказа.
6752
+ */
6753
+ createOrder$(offerId, data) {
6754
+ return this.http.post(`${this.urls.apiUrl}/orders/offers/${offerId}/create-order`, data).pipe(map((orders) => orders.map((item) => new ScOrderShort(item))), tap((orders) => {
6755
+ orders.forEach((order) => {
6756
+ this.userMetrikaService.emitUserMetrikaEvent({
6757
+ target: ScUserMetrikaGoalsEnum.orderCreatedFromDraft,
6758
+ params: { offer_id: offerId, order_id: order.id },
6759
+ });
6760
+ });
6761
+ }));
6762
+ }
6763
+ /**
6764
+ * Добавляет продукт в коммерческое предложение/черновик.
6765
+ *
6766
+ * @param productData Данные продукта для добавления.
6767
+ * @param offerId Идентификатор коммерческого предложения/черновика.
6768
+ */
6769
+ addProduct$(productData, offerId) {
6770
+ return this.http.post(`${this.urls.apiUrl}/orders/offers/${offerId}/products`, productData).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6771
+ this.offerMap.set(offerId, new ScCachedItem(this.updateInterval.orderData, of(offer), loadingPlaceholder));
6772
+ }));
6773
+ }
6774
+ /**
6775
+ * Изменяет продукт в коммерческом предложении/черновике.
6776
+ *
6777
+ * @param productId Идентификатор продукта в корзине.
6778
+ * @param patch Частичные данные для обновления.
6779
+ * @param offerId Идентификатор коммерческого предложения/черновика.
6780
+ */
6781
+ updateProduct$(productId, patch, offerId) {
6782
+ return this.http.patch(`${this.urls.apiUrl}/orders/offers/${offerId}/products/${productId}`, patch).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6783
+ this.offerMap.set(offerId, new ScCachedItem(this.updateInterval.orderData, of(offer), loadingPlaceholder));
6784
+ }));
6785
+ }
6786
+ /**
6787
+ * Удаляет продукт из коммерческого предложения/черновика.
6788
+ *
6789
+ * @param item Удаляемая позиция.
6790
+ * @param offerId Идентификатор коммерческого предложения/черновика.
6791
+ */
6792
+ deleteProduct$(item, offerId) {
6793
+ return this.http.delete(`${this.urls.apiUrl}/orders/offers/${offerId}/products/${item.id}`).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6794
+ this.offerMap.set(offerId, new ScCachedItem(this.updateInterval.orderData, of(offer), loadingPlaceholder));
6795
+ }));
6385
6796
  }
6797
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderDraftsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6798
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderDraftsService, providedIn: 'root' }); }
6386
6799
  }
6800
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderDraftsService, decorators: [{
6801
+ type: Injectable,
6802
+ args: [{
6803
+ providedIn: 'root',
6804
+ }]
6805
+ }], ctorParameters: () => [] });
6387
6806
 
6388
6807
  /* eslint-disable no-param-reassign */
6389
6808
  /**
6390
- * Сервис для работы с заказами.
6809
+ * Данные о сервисе заказов.
6391
6810
  */
6392
6811
  class ScOrdersService {
6393
6812
  /**
@@ -6425,13 +6844,13 @@ class ScOrdersService {
6425
6844
  /**
6426
6845
  * Коллекция пар ключ-значение для заказов пользователя.
6427
6846
  */
6428
- this.idOrderMap = new Map();
6847
+ this.orderMap = new Map();
6429
6848
  /**
6430
6849
  * Формат дат.
6431
6850
  */
6432
6851
  this.dateFormats = inject(SC_DATE_FORMAT);
6433
6852
  this.user$.pipe(filter((user) => user.isGuest)).subscribe(() => {
6434
- this.idOrderMap.clear();
6853
+ this.orderMap.clear();
6435
6854
  });
6436
6855
  }
6437
6856
  /**
@@ -6477,15 +6896,6 @@ class ScOrdersService {
6477
6896
  return this.http.get(`${this.urls.apiUrl}/orders`, { params: params }).pipe(map((ordersPaginateDTO) => {
6478
6897
  ordersPaginateDTO.data = ordersPaginateDTO.data.map((item) => new ScOrderShort(item));
6479
6898
  return ordersPaginateDTO;
6480
- }), tap((ordersPaginate) => {
6481
- this.idOrderMap.forEach((order) => {
6482
- if (order.cachedDataIsActual(this.updateInterval.orderData)) {
6483
- const findOrder = ordersPaginate.data.find((item) => item.id === order.id);
6484
- if (findOrder) {
6485
- order.updateDataFromShortOrder(findOrder);
6486
- }
6487
- }
6488
- });
6489
6899
  }));
6490
6900
  }
6491
6901
  /**
@@ -6494,18 +6904,27 @@ class ScOrdersService {
6494
6904
  * @param orderId Идентификатор заказа.
6495
6905
  * @param cacheable Признак возможности получения заказа из кэшированных данных.
6496
6906
  */
6497
- getOrder$(orderId, cacheable = true) {
6498
- const orderMap = this.idOrderMap.get(orderId);
6499
- if (cacheable && orderMap?.cachedDataIsActual(this.updateInterval.orderData)) {
6500
- return of(orderMap);
6907
+ get$(orderId, cacheable = true) {
6908
+ let cachedItem = this.orderMap.get(orderId);
6909
+ if (!cachedItem) {
6910
+ cachedItem = new ScCachedItem(this.updateInterval.orderData, this.http.get(`${this.urls.apiUrl}/orders/${orderId}`).pipe(map((data) => new ScOrder(data))), loadingPlaceholder);
6911
+ if (cacheable) {
6912
+ this.orderMap.set(orderId, cachedItem);
6913
+ }
6501
6914
  }
6502
- return this.http.get(`${this.urls.apiUrl}/orders/${orderId}`).pipe(map((orderDTO) => new ScOrder(orderDTO)), switchMap((order) => this.cartService.getCartChange$().pipe(map((cart) => {
6503
- order.products?.map((product) => {
6504
- product.product.cartItem = cart.items.find((item) => item.product.id === product.product.id);
6505
- return product;
6506
- });
6507
- return order;
6508
- }))), tap((order) => this.idOrderMap.set(order.id, order)));
6915
+ if (cacheable && !cachedItem.cachedDataIsActual()) {
6916
+ cachedItem.update();
6917
+ }
6918
+ return cachedItem.item$;
6919
+ }
6920
+ /**
6921
+ * Возвращает список элементов заказа.
6922
+ *
6923
+ * @param id Идентификатор заказа.
6924
+ * @param cacheable Признак возможности получения списка элементов заказа из кэшированных данных.
6925
+ */
6926
+ getItems$(id, cacheable = true) {
6927
+ return this.get$(id, cacheable).pipe(map((order) => (order === loadingPlaceholder ? loadingPlaceholder : order.products)));
6509
6928
  }
6510
6929
  /**
6511
6930
  * Копирует товары заказа в корзину текущего пользователя.
@@ -6518,7 +6937,9 @@ class ScOrdersService {
6518
6937
  target: ScUserMetrikaGoalsEnum.orderCloned,
6519
6938
  params: { order_id: orderId },
6520
6939
  });
6521
- }), switchMap(() => this.cartService.updateCart$()));
6940
+ }), tap(() => {
6941
+ this.cartService.updateCart();
6942
+ }));
6522
6943
  }
6523
6944
  /**
6524
6945
  * Отменяет заказ.
@@ -6533,33 +6954,6 @@ class ScOrdersService {
6533
6954
  });
6534
6955
  }));
6535
6956
  }
6536
- /**
6537
- * Создаёт запрос нового заказа из заказа черновика.
6538
- *
6539
- * @param orderId Идентификатор заказа черновика.
6540
- * @param newOrder Данные нового заказа.
6541
- */
6542
- createOrderByDraft$(orderId, newOrder) {
6543
- return this.http.post(`${this.urls.apiUrl}/orders/${orderId}/draft`, newOrder).pipe(map((orders) => orders.map((item) => new ScOrderShort(item))), tap(() => {
6544
- this.userMetrikaService.emitUserMetrikaEvent({
6545
- target: ScUserMetrikaGoalsEnum.orderCreatedFromDraft,
6546
- params: { order_id: orderId },
6547
- });
6548
- }), tap(() => this.idOrderMap.delete(orderId)));
6549
- }
6550
- /**
6551
- * Создаёт запрос на удаление заказа черновика.
6552
- *
6553
- * @param orderId Идентификатор заказа черновика.
6554
- */
6555
- deleteDraftOrder$(orderId) {
6556
- return this.http.delete(`${this.urls.apiUrl}/orders/${orderId}/draft`).pipe(tap(() => {
6557
- this.userMetrikaService.emitUserMetrikaEvent({
6558
- target: ScUserMetrikaGoalsEnum.orderDeleted,
6559
- params: { order_id: orderId, is_draft: true },
6560
- });
6561
- }), tap(() => this.idOrderMap.delete(orderId)));
6562
- }
6563
6957
  /**
6564
6958
  * Возвращает информацию о стоимости доставки.
6565
6959
  *
@@ -7811,5 +8205,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
7811
8205
  * Generated bundle index. Do not edit.
7812
8206
  */
7813
8207
 
7814
- export { CATEGORY_PROVIDERS, EMPTY_CART, ERROR_HANDLER, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, RESPONSE, SC_ACCESS_AUTH_TOKEN_STORAGE_KEY, SC_API_KEYS, SC_AUTH_ADD_HEADER_REQUIRED, SC_AUTH_AS_CLIENT_DEFAULT_OPTIONS, SC_AUTH_AS_CLIENT_OPTIONS, SC_CACHE_LIFETIME, SC_CACHE_SETTINGS, SC_CATALOG_PAGE_META, SC_CATEGORY_INFO, SC_COMPANY_INFO, SC_COMPANY_NAME, SC_CONFIGURATOR_COMPONENTS, SC_CONFIGURATOR_SETTINGS, SC_COUNT_FIRST_DISCOUNTED_PRODUCTS, SC_COUNT_LAST_NEWS, SC_DATE_FORMAT, SC_DEFAULT_PAGE_META, SC_FEEDBACK_API, SC_GUEST_ENDPOINTS_TOKEN, SC_GUEST_PARAMETER_NAME_TOKEN, SC_GUEST_TOKEN_STORAGE_KEY, SC_ID_OR_SLUG_IN_ROUTE, SC_IS_HEADER_REQUIRED, SC_IS_HIDDEN_ERROR_ALERT, SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT, SC_IS_LOGOUT_REQUEST, SC_IS_REFRESH_REQUIRED, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_MAX_LENGTH_SEARCH_TERM, SC_MIN_LENGTH_SEARCH_TERM, SC_NEXT_PAGE_PAGINATION_CLICK, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_UPDATE_INTERVAL, SC_URLS, SC_USER_INFO, SC_VACANCIES_DATA_SOURCE, SC_VIRTUAL_CATEGORY_INFO, SC_VIRTUAL_CATEGORY_PROVIDERS, SEARCH_TERM, SEARCH_TERM_PROVIDERS, ScAuthAsClientGuard, ScAuthInterceptor, ScAuthService, ScBanner, ScBannerService, ScCacheInterceptor, ScCacheSettings, ScCachedData, ScCachedItem, ScCart, ScCartItem, ScCartService, ScCatalogFilterService, ScCatalogFormat, ScCatalogItem, ScCatalogService, ScCatalogableItem, ScCategory, ScClientType, ScCodedIdentity, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDateFormatInterceptor, ScDeletableNamedIdentity, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorsInterceptor, ScFavoriteService, ScFeedbackForms, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScHiddenCatalogableItem, ScIBreadcrumbItem, ScISalesDirectionCart, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScIdentity, ScImage, ScImageHelper, ScLocationsService, ScMediaImageTransformerPipe, ScMimeTypes, ScNamedIdentity, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScPrimaryCatalogableItem, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScReference, ScReferenceName, ScReferencesService, ScRequisitesService, ScRouteKeys, ScSearchService, ScSeoService, ScSocialType, ScSuggestionService, ScSum, ScTokenService, ScUIService, ScUTMService, ScUnitsHelper, ScUpdatableNamedIdentity, ScUploadedFile, ScUser, ScUserMetadata, ScUserMetrikaGoalsEnum, ScUserMetrikaService, ScUserService, ScUserType, ScVCardService, ScVacanciesList, ScVacanciesService, ScVacancy, ScVerificationService, ScVirtualCategory, ScWarehouseService, SchemaOrgFactory, TERMINAL_PROVIDERS, USER_AGENT_TERMINAL, filterChangedByKey, runningOnTerminalFactory, searchTermFactory };
8208
+ export { CATEGORY_PROVIDERS, EMPTY_CART, ERROR_HANDLER, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, RESPONSE, SC_ACCESS_AUTH_TOKEN_STORAGE_KEY, SC_API_KEYS, SC_AUTH_ADD_HEADER_REQUIRED, SC_AUTH_AS_CLIENT_DEFAULT_OPTIONS, SC_AUTH_AS_CLIENT_OPTIONS, SC_CACHE_LIFETIME, SC_CACHE_SETTINGS, SC_CATALOG_PAGE_META, SC_CATEGORY_INFO, SC_COMPANY_INFO, SC_COMPANY_NAME, SC_CONFIGURATOR_COMPONENTS, SC_CONFIGURATOR_SETTINGS, SC_COUNT_FIRST_DISCOUNTED_PRODUCTS, SC_COUNT_LAST_NEWS, SC_DATE_FORMAT, SC_DEFAULT_PAGE_META, SC_FEEDBACK_API, SC_GUEST_ENDPOINTS_TOKEN, SC_GUEST_PARAMETER_NAME_TOKEN, SC_GUEST_TOKEN_STORAGE_KEY, SC_ID_OR_SLUG_IN_ROUTE, SC_IS_HEADER_REQUIRED, SC_IS_HIDDEN_ERROR_ALERT, SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT, SC_IS_LOGOUT_REQUEST, SC_IS_REFRESH_REQUIRED, SC_LINEAR_VALUES, SC_LINEAR_VALUES_TOKEN, SC_MAX_LENGTH_SEARCH_TERM, SC_MIN_LENGTH_SEARCH_TERM, SC_NEXT_PAGE_PAGINATION_CLICK, SC_ORDER_LOADER, SC_ORDER_LOADING, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_UPDATE_INTERVAL, SC_URLS, SC_USER_INFO, SC_VACANCIES_DATA_SOURCE, SC_VIRTUAL_CATEGORY_INFO, SC_VIRTUAL_CATEGORY_PROVIDERS, SEARCH_TERM, SEARCH_TERM_PROVIDERS, ScAuthAsClientGuard, ScAuthInterceptor, ScAuthService, ScBanner, ScBannerService, ScCacheInterceptor, ScCacheSettings, ScCachedData, ScCachedItem, ScCart, ScCartService, ScCatalogFilterService, ScCatalogFormat, ScCatalogItem, ScCatalogService, ScCatalogableItem, ScCategory, ScClientType, ScCodedIdentity, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDateFormatInterceptor, ScDeletableNamedIdentity, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorsInterceptor, ScFavoriteService, ScFeedbackForms, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScHiddenCatalogableItem, ScIBreadcrumbItem, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScIdentity, ScImage, ScImageHelper, ScLocationsService, ScMediaImageTransformerPipe, ScMimeTypes, ScNamedIdentity, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderBase, ScOrderDraft, ScOrderDraftShort, ScOrderDraftType, ScOrderDraftsService, ScOrderItem, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScPrimaryCatalogableItem, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScReference, ScReferenceName, ScReferencesService, ScRequisitesService, ScRouteKeys, ScSearchService, ScSeoService, ScSocialType, ScSuggestionService, ScSum, ScTokenService, ScUIService, ScUTMService, ScUnitsHelper, ScUpdatableNamedIdentity, ScUploadedFile, ScUser, ScUserMetadata, ScUserMetrikaGoalsEnum, ScUserMetrikaService, ScUserService, ScUserType, ScVCardService, ScVacanciesList, ScVacanciesService, ScVacancy, ScVerificationService, ScVirtualCategory, ScWarehouseService, SchemaOrgFactory, TERMINAL_PROVIDERS, USER_AGENT_TERMINAL, filterChangedByKey, loadingPlaceholder, runningOnTerminalFactory, scOrderIsLoaded, searchTermFactory };
7815
8209
  //# sourceMappingURL=snabcentr-client-core.mjs.map