@snabcentr/client-core 2.65.2 → 2.66.0

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 (151) 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/esm2022/banners/dto/sc-banner.mjs +12 -12
  14. package/esm2022/cart/classes/index.mjs +2 -1
  15. package/esm2022/cart/classes/sc-cart.mjs +18 -0
  16. package/esm2022/cart/classes/sc-sum.mjs +2 -2
  17. package/esm2022/cart/index.mjs +1 -2
  18. package/esm2022/cart/internal/index.mjs +2 -3
  19. package/esm2022/cart/internal/sc-i-cart.mjs +2 -0
  20. package/esm2022/cart/services/sc-cart.service.mjs +50 -52
  21. package/esm2022/catalog/classes/sc-cached-item.mjs +31 -6
  22. package/esm2022/catalog/dto/sc-product.mjs +1 -1
  23. package/esm2022/catalog/interfaces/sc-i-category-product-params.mjs +1 -1
  24. package/esm2022/catalog/interfaces/sc-property-filters.mjs +1 -1
  25. package/esm2022/catalog/services/sc-catalog.service.mjs +6 -6
  26. package/esm2022/catalog/services/sc-recommendation.service.mjs +8 -7
  27. package/esm2022/contragent/services/sc-contragent.service.mjs +3 -3
  28. package/esm2022/delivery-address/services/sc-delivery-address.service.mjs +4 -2
  29. package/esm2022/order/classes/index.mjs +11 -0
  30. package/esm2022/order/classes/sc-delivery-cost.mjs +19 -0
  31. package/esm2022/order/classes/sc-order-base.mjs +28 -0
  32. package/esm2022/order/classes/sc-order-delivery.mjs +2 -0
  33. package/esm2022/order/classes/sc-order-draft-short.mjs +17 -0
  34. package/esm2022/order/classes/sc-order-draft.mjs +59 -0
  35. package/esm2022/order/classes/sc-order-history.mjs +2 -0
  36. package/esm2022/order/classes/sc-order-item.mjs +60 -0
  37. package/esm2022/order/classes/sc-order-payment.mjs +2 -0
  38. package/esm2022/order/classes/sc-order-short.mjs +30 -0
  39. package/esm2022/order/classes/sc-order.mjs +100 -0
  40. package/esm2022/order/enums/index.mjs +2 -1
  41. package/esm2022/order/enums/sc-order-draft-type.mjs +16 -0
  42. package/esm2022/order/index.mjs +5 -3
  43. package/esm2022/order/internal/index.mjs +14 -3
  44. package/esm2022/order/internal/sc-i-delivery-cost-dto.mjs +1 -1
  45. package/esm2022/order/internal/sc-i-new-order-draft-request.mjs +2 -0
  46. package/esm2022/order/internal/sc-i-new-order-item-base.mjs +2 -0
  47. package/esm2022/order/internal/sc-i-new-order-item-measured.mjs +2 -0
  48. package/esm2022/order/internal/sc-i-new-order.mjs +2 -0
  49. package/esm2022/order/internal/sc-i-order-base.mjs +2 -0
  50. package/esm2022/order/internal/sc-i-order-draft-list-params.mjs +2 -0
  51. package/esm2022/order/internal/sc-i-order-draft-short.mjs +2 -0
  52. package/esm2022/order/internal/sc-i-order-draft.mjs +2 -0
  53. package/esm2022/order/internal/sc-i-order-item.mjs +2 -0
  54. package/esm2022/order/internal/sc-i-order-loader.mjs +2 -0
  55. package/esm2022/order/internal/sc-i-order-short.mjs +2 -0
  56. package/esm2022/order/internal/sc-i-order.mjs +2 -0
  57. package/esm2022/order/internal/sc-i-update-order-order-request.mjs +2 -0
  58. package/esm2022/order/services/index.mjs +3 -0
  59. package/esm2022/order/services/sc-order-drafts.service.mjs +195 -0
  60. package/esm2022/order/services/sc-orders.service.mjs +33 -54
  61. package/esm2022/order/tokens/index.mjs +2 -0
  62. package/esm2022/order/tokens/sc-order-loader.token.mjs +25 -0
  63. package/esm2022/pagination/dto/index.mjs +3 -1
  64. package/esm2022/pagination/dto/sc-i-range-filter.mjs +2 -0
  65. package/esm2022/pagination/dto/sc-i-sort-order.mjs +2 -0
  66. package/esm2022/reclamation/interfaces/sc-i-pagination-params.mjs +1 -1
  67. package/esm2022/references/enums/sc-order-state-status.mjs +1 -5
  68. package/esm2022/seo/classes/schema-org-factory.mjs +41 -2
  69. package/esm2022/seo/interfaces/index.mjs +2 -2
  70. package/esm2022/seo/interfaces/sc-i-breadcrumb-item.mjs +12 -0
  71. package/esm2022/seo/services/sc-seo.service.mjs +11 -2
  72. package/esm2022/ui/services/sc-ui.service.mjs +1 -1
  73. package/esm2022/user/dto/sc-user-metadata.mjs +1 -1
  74. package/esm2022/user-metrika/enums/sc-user-metrika-goals-enum.mjs +19 -1
  75. package/fesm2022/snabcentr-client-core.mjs +1093 -768
  76. package/fesm2022/snabcentr-client-core.mjs.map +1 -1
  77. package/order/{dto → classes}/index.d.ts +5 -3
  78. package/order/{dto → classes}/sc-delivery-cost.d.ts +2 -2
  79. package/order/classes/sc-order-base.d.ts +32 -0
  80. package/order/classes/sc-order-draft-short.d.ts +22 -0
  81. package/order/classes/sc-order-draft.d.ts +63 -0
  82. package/order/{dto → classes}/sc-order-history.d.ts +1 -1
  83. package/order/classes/sc-order-item.d.ts +98 -0
  84. package/order/{dto → classes}/sc-order-payment.d.ts +1 -1
  85. package/order/classes/sc-order-short.d.ts +44 -0
  86. package/order/classes/sc-order.d.ts +102 -0
  87. package/order/enums/index.d.ts +1 -0
  88. package/order/enums/sc-order-draft-type.d.ts +13 -0
  89. package/order/index.d.ts +4 -2
  90. package/order/internal/index.d.ts +13 -2
  91. package/order/internal/sc-i-delivery-cost-dto.d.ts +1 -1
  92. package/order/internal/sc-i-new-order-draft-request.d.ts +13 -0
  93. package/{cart/dto/sc-i-new-cart-item-base.d.ts → order/internal/sc-i-new-order-item-base.d.ts} +2 -2
  94. package/order/internal/sc-i-new-order-item-measured.d.ts +10 -0
  95. package/order/{dto → internal}/sc-i-new-order.d.ts +1 -5
  96. package/order/internal/sc-i-order-base.d.ts +25 -0
  97. package/order/internal/sc-i-order-draft-list-params.d.ts +32 -0
  98. package/order/internal/sc-i-order-draft-short.d.ts +15 -0
  99. package/order/internal/sc-i-order-draft.d.ts +43 -0
  100. package/{cart/dto/sc-cart-item.d.ts → order/internal/sc-i-order-item.d.ts} +6 -13
  101. package/order/internal/sc-i-order-loader.d.ts +51 -0
  102. package/order/internal/{sc-i-order-short-dto.d.ts → sc-i-order-short.d.ts} +14 -16
  103. package/order/{dto/sc-order.d.ts → internal/sc-i-order.d.ts} +15 -67
  104. package/order/internal/sc-i-update-order-order-request.d.ts +9 -0
  105. package/order/services/index.d.ts +2 -0
  106. package/order/services/sc-order-drafts.service.d.ts +118 -0
  107. package/order/services/sc-orders.service.d.ts +19 -20
  108. package/order/tokens/index.d.ts +1 -0
  109. package/order/tokens/sc-order-loader.token.d.ts +26 -0
  110. package/package.json +1 -1
  111. package/pagination/dto/index.d.ts +2 -0
  112. package/pagination/dto/sc-i-range-filter.d.ts +15 -0
  113. package/pagination/dto/sc-i-sort-order.d.ts +15 -0
  114. package/reclamation/interfaces/sc-i-pagination-params.d.ts +3 -21
  115. package/references/enums/sc-order-state-status.d.ts +0 -4
  116. package/seo/classes/schema-org-factory.d.ts +9 -2
  117. package/seo/interfaces/index.d.ts +1 -1
  118. package/seo/interfaces/sc-i-breadcrumb-item.d.ts +25 -0
  119. package/seo/services/sc-seo.service.d.ts +1 -1
  120. package/ui/services/sc-ui.service.d.ts +1 -1
  121. package/user/dto/sc-user-metadata.d.ts +1 -1
  122. package/user-metrika/enums/sc-user-metrika-goals-enum.d.ts +18 -0
  123. package/cart/dto/index.d.ts +0 -5
  124. package/cart/dto/sc-i-new-cart-item-measured.d.ts +0 -10
  125. package/cart/dto/sc-i-sales-direction-cart.d.ts +0 -37
  126. package/cart/internal/sc-i-cart-item-dto.d.ts +0 -73
  127. package/esm2022/cart/dto/index.mjs +0 -6
  128. package/esm2022/cart/dto/sc-cart-item.mjs +0 -60
  129. package/esm2022/cart/dto/sc-cart.mjs +0 -18
  130. package/esm2022/cart/dto/sc-i-new-cart-item-base.mjs +0 -2
  131. package/esm2022/cart/dto/sc-i-new-cart-item-measured.mjs +0 -2
  132. package/esm2022/cart/dto/sc-i-sales-direction-cart.mjs +0 -21
  133. package/esm2022/cart/internal/sc-i-cart-dto.mjs +0 -2
  134. package/esm2022/cart/internal/sc-i-cart-item-dto.mjs +0 -2
  135. package/esm2022/order/dto/index.mjs +0 -9
  136. package/esm2022/order/dto/sc-delivery-cost.mjs +0 -19
  137. package/esm2022/order/dto/sc-i-new-order-from-draft.mjs +0 -2
  138. package/esm2022/order/dto/sc-i-new-order.mjs +0 -2
  139. package/esm2022/order/dto/sc-order-delivery.mjs +0 -2
  140. package/esm2022/order/dto/sc-order-history.mjs +0 -2
  141. package/esm2022/order/dto/sc-order-payment.mjs +0 -2
  142. package/esm2022/order/dto/sc-order-short.mjs +0 -46
  143. package/esm2022/order/dto/sc-order.mjs +0 -134
  144. package/esm2022/order/internal/sc-i-order-dto.mjs +0 -2
  145. package/esm2022/order/internal/sc-i-order-short-dto.mjs +0 -2
  146. package/esm2022/seo/interfaces/sc-i-schema-org-breadcrumb-list.mjs +0 -2
  147. package/order/dto/sc-i-new-order-from-draft.d.ts +0 -10
  148. package/order/dto/sc-order-short.d.ts +0 -65
  149. package/order/internal/sc-i-order-dto.d.ts +0 -94
  150. package/seo/interfaces/sc-i-schema-org-breadcrumb-list.d.ts +0 -34
  151. /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';
@@ -656,6 +656,24 @@ var ScUserMetrikaGoalsEnum;
656
656
  * - стоимость заказа (параметр "cost").
657
657
  */
658
658
  ScUserMetrikaGoalsEnum["orderDeleted"] = "ORDER_DELETED";
659
+ /**
660
+ * Коммерческое предложение/черновик заказа создано.
661
+ *
662
+ * В качестве параметра должен быть указан идентификатор КП/черновика (параметр "offer_id").
663
+ */
664
+ ScUserMetrikaGoalsEnum["orderDraftCreated"] = "ORDER_DRAFT_CREATED";
665
+ /**
666
+ * Коммерческое предложение/черновик заказа обновлено.
667
+ *
668
+ * В качестве параметра должен быть указан идентификатор КП/черновика (параметр "offer_id").
669
+ */
670
+ ScUserMetrikaGoalsEnum["orderDraftUpdated"] = "ORDER_DRAFT_UPDATED";
671
+ /**
672
+ * Коммерческое предложение/черновик заказа удалено.
673
+ *
674
+ * В качестве параметра должен быть указан идентификатор КП/черновика (параметр "offer_id").
675
+ */
676
+ ScUserMetrikaGoalsEnum["orderDraftDeleted"] = "ORDER_DRAFT_DELETED";
659
677
  /**
660
678
  * Открыто диалоговое окно/страница конфигуратора товара.
661
679
  *
@@ -1071,18 +1089,18 @@ class ScBanner {
1071
1089
  /**
1072
1090
  * Инициализирует экземпляр класса {@link ScBanner}.
1073
1091
  *
1074
- * @param bannerDTO Данные для инициализации.
1092
+ * @param data Данные для инициализации.
1075
1093
  */
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;
1094
+ constructor(data) {
1095
+ this.id = data.id;
1096
+ this.location = data.location;
1097
+ this.mediaType = data.mediaType;
1098
+ this.mediaFile = data.mediaFile;
1099
+ this.mediaFileWebp = data.mediaFileWebp;
1100
+ this.title = data.title;
1101
+ this.url = data.url;
1102
+ this.width = data.width;
1103
+ this.height = data.height;
1086
1104
  }
1087
1105
  /**
1088
1106
  * Возвращает признак того, что баннер является изображением.
@@ -1385,7 +1403,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
1385
1403
  const EMPTY_CART = { items: [], result_sum: { rub: 0 }, directions_sum: {} };
1386
1404
 
1387
1405
  /**
1388
- * Модель данных итоговой суммы.
1406
+ * Данные об итоговой сумме.
1389
1407
  */
1390
1408
  class ScSum {
1391
1409
  /**
@@ -1752,58 +1770,58 @@ class ScProduct extends ScCatalogItem {
1752
1770
  }
1753
1771
 
1754
1772
  /**
1755
- * Единичная позиция товара/услуги в корзине.
1773
+ * Данные о единичной позиции товара/услуги в заказе (корзине / черновике).
1756
1774
  */
1757
- class ScCartItem {
1775
+ class ScOrderItem {
1758
1776
  /**
1759
- * Инициализирует экземпляр класса {@link ScCartItem}.
1777
+ * Инициализирует экземпляр класса {@link ScOrderItem}.
1760
1778
  *
1761
- * @param cartItemDTO DTO единичной позиции товара/услуги в корзине.
1779
+ * @param data Данные для первоначальной инициализации.
1762
1780
  */
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
- * Возвращает стоимость единицы товара (включая валюту). Если стоимость отсутствует, то вернёт '-'.
1781
+ constructor(data) {
1782
+ this.id = data.id;
1783
+ this.product = new ScProduct(data.product);
1784
+ this.quantity = data.quantity;
1785
+ this.cost = data.cost;
1786
+ this.costOne = data.costOne;
1787
+ this.costRub = data.costRub;
1788
+ this.costOneRub = data.costOneRub;
1789
+ this.marker = data.marker;
1790
+ this.height = data.height;
1791
+ this.length = data.length;
1792
+ this.width = data.width;
1793
+ this.logicGroupId = data.logicGroupId;
1794
+ this.salesDirection = data.salesDirection;
1795
+ this.specificationImgUrl = data.specificationImgUrl;
1796
+ this.configurator = data.configurator;
1797
+ this.configuratorParams = data.configuratorParams;
1798
+ }
1799
+ /**
1800
+ * @inheritDoc
1783
1801
  */
1784
1802
  getCostPerItem() {
1785
1803
  return this.costOne > 0 ? `${this.costOne.toLocaleString()} ${this.product.currency.symbol}` : '-';
1786
1804
  }
1787
1805
  /**
1788
- * Возвращает строковое представление стоимости единицы товара (включая единицу измерения) в валюте. Если стоимость отсутствует, то вернёт '-'.
1806
+ * @inheritDoc
1789
1807
  */
1790
1808
  getCostInCurrencyDescPerItem() {
1791
1809
  return this.costOne > 0 ? `${this.costOne.toLocaleString()} ${this.product.currency.symbol} / ${this.product.unit.name}` : '-';
1792
1810
  }
1793
1811
  /**
1794
- * Возвращает строковое представление стоимости единицы товара (включая единицу измерения) в рублях. Если стоимость отсутствует, то вернёт '-'.
1812
+ * @inheritDoc
1795
1813
  */
1796
1814
  getCostInRubDescPerItem() {
1797
1815
  return this.costOneRub > 0 ? `${this.costOneRub.toLocaleString()} ₽ / ${this.product.unit.name}` : '-';
1798
1816
  }
1799
1817
  /**
1800
- * Возвращает стоимость товара в виде строки. Если стоимость отсутствует, то вернёт '-'.
1818
+ * @inheritDoc
1801
1819
  */
1802
1820
  getCostRubStr() {
1803
1821
  return this.costRub > 0 ? `${this.costRub.toLocaleString()} ₽` : '-';
1804
1822
  }
1805
1823
  /**
1806
- * Возвращает сообщение о необходимости уточнить цену или пустую строку.
1824
+ * @inheritDoc
1807
1825
  */
1808
1826
  getCostMessage() {
1809
1827
  return this.costRub === 0 ? 'Цена требует уточнения' : '';
@@ -1811,174 +1829,103 @@ class ScCartItem {
1811
1829
  }
1812
1830
 
1813
1831
  /**
1814
- * Модель данных информация о содержимом корзины.
1832
+ * Данные о содержимом корзины.
1815
1833
  */
1816
1834
  class ScCart {
1817
1835
  /**
1818
1836
  * Инициализирует экземпляр класса {@link ScCart}.
1819
1837
  *
1820
- * @param cartDTO DTO с информацией о содержимом корзины.
1838
+ * @param data Данные для первоначальной инициализации.
1821
1839
  */
1822
1840
  // 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;
1841
+ constructor(data = { items: [], resultSum: { rub: 0 }, directionsSum: {} }) {
1842
+ this.items = data.items.map((item) => new ScOrderItem(item));
1843
+ this.resultSum = data.resultSum;
1844
+ this.directionsSum = data.directionsSum;
1827
1845
  }
1828
1846
  }
1829
1847
 
1830
1848
  /**
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;
1848
- }
1849
- }
1850
-
1851
- /* eslint-disable security/detect-object-injection,no-param-reassign */
1852
- /**
1853
- * Сервис конвертации данных.
1849
+ * Модель кэшированных данных.
1854
1850
  */
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
- }
1851
+ class ScCachedItem {
1882
1852
  /**
1883
- * Возвращает {@link T} объект из которого удалены свойства со значением null.
1853
+ * Инициализирует экземпляр класса {@link ScCachedItem}.
1884
1854
  *
1885
- * @param object Объект, в котором необходимо удалить свойства со значением null.
1855
+ * @param lifeTime Время жизни записи в ms.
1856
+ * @param item$ {@link Observable} запроса кэшируемых данных.
1857
+ * @param initialValue Начальное значение данных.
1886
1858
  */
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 !== ''));
1859
+ constructor(lifeTime, item$, initialValue) {
1860
+ /**
1861
+ * {@link Observable} обновления данных.
1862
+ */
1863
+ this.update$ = new BehaviorSubject(undefined);
1864
+ /**
1865
+ * Текущее значение данных, установленное напрямую.
1866
+ */
1867
+ this.currentValue$ = new Subject();
1868
+ this.lifeTime = lifeTime;
1869
+ const requestData$ = this.update$.pipe(switchMap(() => item$.pipe(tap(() => {
1870
+ this.updateCacheTime();
1871
+ }), startWith((initialValue ?? null)))), materialize(), shareReplay(1), dematerialize());
1872
+ this.item$ = merge(this.currentValue$, requestData$).pipe(shareReplay());
1891
1873
  }
1892
1874
  /**
1893
- * Возвращает {@link T} объект из которого рекурсивно удалены свойства со значением null.
1894
- *
1895
- * @param object Объект, в котором необходимо удалить свойства со значением null.
1875
+ * Обновляет время кэширования данных.
1896
1876
  */
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;
1877
+ updateCacheTime() {
1878
+ this.cachedUntil = Date.now() + this.lifeTime;
1920
1879
  }
1921
1880
  /**
1922
- * Возвращает {@link T} объект из которого удалены свойства меньшей длины, чем {@link minLength}.
1923
- *
1924
- * @param object ООбъект, в котором необходимо удалить свойства меньшей длины, чем {@link minLength}.
1925
- * @param minLength Минимально допустимая длина строковых свойств объекта.
1881
+ * Возвращает признак того, что кэшированные данные актуальны.
1926
1882
  */
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'));
1883
+ cachedDataIsActual() {
1884
+ return !this.cachedUntil || this.cachedUntil > Date.now();
1931
1885
  }
1932
1886
  /**
1933
- * Конвертирует поля, имеющие тип {@link Date}, в {@link object}, и возвращает как новый объект.
1934
- *
1935
- * @param object Объект, в котором необходимо преобразовать поля Date в string.
1887
+ * Выполняет обновления {@link Observable} запроса кэшируемых данных.
1936
1888
  */
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}]`), '');
1889
+ update() {
1890
+ this.cachedUntil = undefined;
1891
+ this.update$.next();
1944
1892
  }
1945
1893
  /**
1946
- * Возвращает новое представление объекта в котором рекурсивно поля преобразованы в формат <patent_properties>[<child_properties>]... .
1894
+ * Устанавливает значение данных напрямую без провоцирования запроса через {@link Observable}.
1947
1895
  *
1948
- * @param object Объект, в котором необходимо преобразовать поля в формат <patent_properties>[<child_properties>]... .
1949
- * @param keys Список ключей до объекта {@link object} в исходном объекте.
1950
- * @param resultObject Итоговый объект.
1896
+ * @param value Новое значение данных.
1897
+ * @param updateCacheTime Обновить время кэширования. По умолчанию true.
1951
1898
  */
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
- }
1899
+ setValue(value, updateCacheTime = true) {
1900
+ if (updateCacheTime) {
1901
+ this.updateCacheTime();
1967
1902
  }
1968
- return resultObject;
1903
+ this.currentValue$.next(value);
1969
1904
  }
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
1905
  }
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
- }] }] });
1906
+
1907
+ /**
1908
+ * Плейсхолдер загрузки данных заказа (корзины / черновика).
1909
+ */
1910
+ const loadingPlaceholder = {};
1911
+ /**
1912
+ * Проверяет, что объект заказа (корзины / черновика) загружен, а не является плейсхолдером загрузки.
1913
+ *
1914
+ * @param value Значение (загруженные данные или плейсхолдер загрузки).
1915
+ */
1916
+ function scOrderIsLoaded(value) {
1917
+ return !isNil(value) && value !== loadingPlaceholder;
1918
+ }
1919
+ /**
1920
+ * Токен инъекции сервиса списка товаров заказа.
1921
+ * Предоставляется в корне компонента корзины, заказа или черновика — в зависимости от контекста
1922
+ * внедряется соответствующая реализация (корзина, заказ, черновик = заказ).
1923
+ */
1924
+ const SC_ORDER_LOADER = new InjectionToken('ScOrderLoader (order / cart / draft)');
1925
+ /**
1926
+ * Плейсхолдер загрузки данных заказа (корзины / черновика).
1927
+ */
1928
+ const SC_ORDER_LOADING = new InjectionToken('ScOrderLoading', { factory: () => loadingPlaceholder });
1982
1929
 
1983
1930
  /**
1984
1931
  * Формат отображения каталога.
@@ -2042,42 +1989,282 @@ class ScUserMetadata {
2042
1989
  }
2043
1990
  }
2044
1991
 
1992
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2045
1993
  /**
2046
- * Перечисление названий справочников.
1994
+ * Возвращает фильтр для {@link Observable} изменений метаданных пользователя.
1995
+ *
1996
+ * @param target Свойство для которого отслеживается изменение.
1997
+ * @returns Функция {@link distinctUntilKeyChanged} для отслеживания изменения {@link Observable} {@link ScUserMetadata}.
2047
1998
  */
2048
- // eslint-disable-next-line no-shadow
2049
- var ScReferenceName;
2050
- (function (ScReferenceName) {
1999
+ function filterChangedByKey(target) {
2000
+ return distinctUntilKeyChanged(target, (previous, current) => previous === current);
2001
+ }
2002
+
2003
+ /* eslint-disable security/detect-object-injection */
2004
+ /**
2005
+ * Сервис для работы с UI.
2006
+ */
2007
+ class ScUIService {
2051
2008
  /**
2052
- * Тип канала сообщений чата.
2009
+ * Инициализирует экземпляр класса {@link ScUIService}.
2010
+ *
2011
+ * @param userService Сервис информации о пользователе.
2053
2012
  */
2054
- ScReferenceName["chatChannel"] = "chat-channel";
2013
+ constructor(userService) {
2014
+ this.userService = userService;
2015
+ /**
2016
+ * {@link ReplaySubject} метаданных пользователя.
2017
+ */
2018
+ this.userMetadataSubject = new ReplaySubject(1);
2019
+ userService.getUserChange$().subscribe((user) => {
2020
+ if (this.metadataSubjectSubscription) {
2021
+ this.metadataSubjectSubscription.unsubscribe();
2022
+ }
2023
+ this.userMetadataSubject.next(new ScUserMetadata(user.metadata));
2024
+ this.metadataSubjectSubscription = this.userMetadataSubject
2025
+ .pipe(skip(1), // Не нужно обновлять данные пользователя при его смене.
2026
+ switchMap((metadata) => user.userType === ScUserType.guest ? this.userService.updateGuestInfo$({ metadata: metadata }) : this.userService.updateUserInfo$({ metadata: metadata })))
2027
+ .subscribe();
2028
+ });
2029
+ }
2055
2030
  /**
2056
- * Город.
2031
+ * Возвращает {@link Observable} метаданных, когда изменяется значение переданного свойства.
2032
+ *
2033
+ * @param target Свойство для которого отслеживается изменение.
2057
2034
  */
2058
- ScReferenceName["city"] = "city";
2035
+ getMetadataChangeByKey$(target) {
2036
+ return this.userMetadataSubject.pipe(filterChangedByKey(target), map((metadata) => metadata[target]));
2037
+ }
2059
2038
  /**
2060
- * Город с информацией о регионе и стране.
2039
+ * Возвращает {@link Observable} метаданных, когда изменяется значение переданного свойства.
2040
+ * TODO: Доработать функцию, чтобы она возвращала Observable.
2041
+ *
2042
+ * @param target Свойство, значение которого необходимо изменить.
2043
+ * @param value Новое значение.
2061
2044
  */
2062
- ScReferenceName["cityWithRegionAndCountry"] = "city-with-region-and-country";
2045
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters
2046
+ setMetadataByKey(target, value) {
2047
+ this.userMetadataSubject.pipe(first()).subscribe((metadata) => {
2048
+ const newMetadata = new ScUserMetadata(metadata);
2049
+ newMetadata[target] = value;
2050
+ this.userMetadataSubject.next(newMetadata);
2051
+ });
2052
+ }
2063
2053
  /**
2064
- * Город с информацией о регионе.
2054
+ * Возвращает {@link Observable} списка категорий, которые необходимо скрыть.
2065
2055
  */
2066
- ScReferenceName["cityWithRegion"] = "city-with-region";
2056
+ getHiddenCategoriesList$() {
2057
+ return this.getMetadataChangeByKey$('hiddenCategories');
2058
+ }
2067
2059
  /**
2068
- * Страна.
2060
+ * Устанавливает список категорий, которые необходимо скрыть.
2061
+ *
2062
+ * @param categoryIds Список идентификаторов категорий, которые необходимо скрыть.
2069
2063
  */
2070
- ScReferenceName["country"] = "country";
2064
+ setHiddenCategoriesList(categoryIds) {
2065
+ this.setMetadataByKey('hiddenCategories', categoryIds);
2066
+ }
2071
2067
  /**
2072
- * Тип доставки.
2068
+ * Возвращает {@link Observable} вида представления товара в списке.
2073
2069
  */
2074
- ScReferenceName["deliveryType"] = "delivery-type";
2070
+ getProductTileType$() {
2071
+ return this.getMetadataChangeByKey$('productTileType');
2072
+ }
2075
2073
  /**
2076
- * Статус оплаты заказа.
2074
+ * Устанавливает вид представления товара в списке.
2075
+ *
2076
+ * @param productTileType Вид представления товара в списке.
2077
2077
  */
2078
- ScReferenceName["orderPaymentStatus"] = "order-payment-status";
2078
+ setProductTileType(productTileType) {
2079
+ this.setMetadataByKey('productTileType', productTileType);
2080
+ }
2079
2081
  /**
2080
- * Статус заказа.
2082
+ * Возвращает {@link Observable} количества элементов на странице пагинации.
2083
+ */
2084
+ getPaginatePageSize$() {
2085
+ return this.getMetadataChangeByKey$('paginatePageSize');
2086
+ }
2087
+ /**
2088
+ * Устанавливает количество элементов на странице пагинации.
2089
+ *
2090
+ * @param paginatePageSize Количество элементов на странице пагинации.
2091
+ */
2092
+ setPaginatePageSize(paginatePageSize) {
2093
+ this.setMetadataByKey('paginatePageSize', paginatePageSize);
2094
+ }
2095
+ /**
2096
+ * Возвращает {@link Observable} метаданных неоформленного заказа по направлению продаж.
2097
+ *
2098
+ * @param directionsId Идентификатор направления продаж.
2099
+ */
2100
+ getNewOrderMetadata$(directionsId) {
2101
+ // Данные представлены массивом объектов, поэтому не используется getMetadataChangeByKey$().
2102
+ return this.userMetadataSubject.pipe(map((metadata) => metadata.newOrdersMetadata), distinctUntilChanged(), map((ordersMetadata) => ordersMetadata[directionsId]), distinctUntilChanged());
2103
+ }
2104
+ /**
2105
+ * Устанавливает метаданные неоформленного заказа по направлению продаж.
2106
+ *
2107
+ * @param directionsId Идентификатор направления продаж.
2108
+ * @param newOrderMetadata Данные нового неоформленного заказа.
2109
+ */
2110
+ setNewOrderMetadata(directionsId, newOrderMetadata) {
2111
+ // При сохранении изображения выдаёт ошибку 500 'Произошла ошибка при работе с базой данных'.
2112
+ // TODO: TASK[#6370]: Доработать после решения задачи.
2113
+ if (newOrderMetadata.image) {
2114
+ // eslint-disable-next-line no-param-reassign
2115
+ delete newOrderMetadata.image;
2116
+ }
2117
+ this.getMetadataChangeByKey$('newOrdersMetadata')
2118
+ .pipe(first())
2119
+ .subscribe((ordersMetadata) => {
2120
+ // eslint-disable-next-line no-param-reassign
2121
+ ordersMetadata[directionsId] = newOrderMetadata;
2122
+ this.setMetadataByKey('newOrdersMetadata', structuredClone(ordersMetadata));
2123
+ });
2124
+ }
2125
+ /**
2126
+ * Удаляет метаданные неоформленного заказа по направлению продаж.
2127
+ *
2128
+ * @param directionsId Идентификатор направления продаж.
2129
+ */
2130
+ removeNewOrderMetadata(directionsId) {
2131
+ this.getMetadataChangeByKey$('newOrdersMetadata')
2132
+ .pipe(first())
2133
+ .subscribe((ordersMetadata) => {
2134
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete,no-param-reassign
2135
+ delete ordersMetadata[directionsId];
2136
+ this.setMetadataByKey('newOrdersMetadata', structuredClone(ordersMetadata));
2137
+ });
2138
+ }
2139
+ /**
2140
+ * Удаляет метаданные не оформленных заказов по всем направлениям продаж.
2141
+ */
2142
+ removeAllNewOrdersMetadata() {
2143
+ this.setMetadataByKey('newOrdersMetadata', []);
2144
+ }
2145
+ /**
2146
+ * Возвращает дату последнего открытия опросников.
2147
+ */
2148
+ getLastOpenQuestionnaireTime$() {
2149
+ return this.getMetadataChangeByKey$('lastOpenQuestionnaireTime');
2150
+ }
2151
+ /**
2152
+ * Устанавливает дату последнего открытия опросников.
2153
+ *
2154
+ * @param lastOpenQuestionnaireTime Дата последнего открытия опросников.
2155
+ */
2156
+ setLastOpenQuestionnaireTime(lastOpenQuestionnaireTime) {
2157
+ this.setMetadataByKey('lastOpenQuestionnaireTime', lastOpenQuestionnaireTime);
2158
+ }
2159
+ /**
2160
+ * Возвращает формат отображения каталога.
2161
+ */
2162
+ getCatalogFormat$() {
2163
+ return this.getMetadataChangeByKey$('catalogFormat');
2164
+ }
2165
+ /**
2166
+ * Устанавливает формат отображения каталога.
2167
+ *
2168
+ * @param catalogFormat Формат отображения каталога.
2169
+ */
2170
+ setCatalogFormat(catalogFormat) {
2171
+ this.setMetadataByKey('catalogFormat', catalogFormat);
2172
+ }
2173
+ /**
2174
+ * Устанавливает идентификатор выбранного склада.
2175
+ *
2176
+ * @param selectedWarehouseId Идентификатор выбранного склада.
2177
+ */
2178
+ setSelectedWarehouseId(selectedWarehouseId) {
2179
+ this.setMetadataByKey('selectedWarehouseId', selectedWarehouseId);
2180
+ }
2181
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, deps: [{ token: ScUserService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2182
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, providedIn: 'root' }); }
2183
+ }
2184
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, decorators: [{
2185
+ type: Injectable,
2186
+ args: [{
2187
+ providedIn: 'root',
2188
+ }]
2189
+ }], ctorParameters: () => [{ type: ScUserService }] });
2190
+
2191
+ /* eslint-disable @typescript-eslint/no-unsafe-member-access,security/detect-non-literal-regexp */
2192
+ /**
2193
+ * Токен признака запущено ли приложение на терминале.
2194
+ */
2195
+ const IS_RUNNING_ON_TERMINAL = new InjectionToken('IS_RUNNING_ON_TERMINAL');
2196
+ /**
2197
+ * Возвращает признак, что приложение запущено на терминале, а также код склада который обслуживает этот терминал (вернет null если не идентификатор склада отсутствует).
2198
+ *
2199
+ * @param userAgentTerminal Регулярное выражение агента пользователя для терминала.
2200
+ *
2201
+ * @returns Если приложение запущено на терминале, возвращает признак этого
2202
+ * и возвращает идентификатор склада привязанного к терминалу в случае его извлечения и, null в случае если склад не удалось извлечь.
2203
+ */
2204
+ function runningOnTerminalFactory(userAgentTerminal) {
2205
+ const isRunningOnTerminal = userAgentTerminal.test(inject(WA_USER_AGENT));
2206
+ if (isRunningOnTerminal) {
2207
+ const matchResult = new RegExp(`${userAgentTerminal.source}(\\w+)`, 'i').exec(inject(WA_USER_AGENT));
2208
+ if (matchResult && matchResult.length > 1) {
2209
+ return { isRunningOnTerminal: isRunningOnTerminal, warehouseId: Number.parseInt(matchResult[1], 10) };
2210
+ }
2211
+ }
2212
+ return { isRunningOnTerminal: isRunningOnTerminal, warehouseId: null };
2213
+ }
2214
+ /**
2215
+ * Токен агента пользователя для терминала.
2216
+ */
2217
+ const USER_AGENT_TERMINAL = new InjectionToken('USER_AGENT_TERMINAL', {
2218
+ providedIn: 'root',
2219
+ factory: () => /sc_terminal_w/i,
2220
+ });
2221
+ /**
2222
+ * Провайдеры данных о терминале.
2223
+ */
2224
+ const TERMINAL_PROVIDERS = [
2225
+ {
2226
+ provide: IS_RUNNING_ON_TERMINAL,
2227
+ deps: [USER_AGENT_TERMINAL],
2228
+ useFactory: runningOnTerminalFactory,
2229
+ },
2230
+ ];
2231
+
2232
+ /**
2233
+ * Перечисление названий справочников.
2234
+ */
2235
+ // eslint-disable-next-line no-shadow
2236
+ var ScReferenceName;
2237
+ (function (ScReferenceName) {
2238
+ /**
2239
+ * Тип канала сообщений чата.
2240
+ */
2241
+ ScReferenceName["chatChannel"] = "chat-channel";
2242
+ /**
2243
+ * Город.
2244
+ */
2245
+ ScReferenceName["city"] = "city";
2246
+ /**
2247
+ * Город с информацией о регионе и стране.
2248
+ */
2249
+ ScReferenceName["cityWithRegionAndCountry"] = "city-with-region-and-country";
2250
+ /**
2251
+ * Город с информацией о регионе.
2252
+ */
2253
+ ScReferenceName["cityWithRegion"] = "city-with-region";
2254
+ /**
2255
+ * Страна.
2256
+ */
2257
+ ScReferenceName["country"] = "country";
2258
+ /**
2259
+ * Тип доставки.
2260
+ */
2261
+ ScReferenceName["deliveryType"] = "delivery-type";
2262
+ /**
2263
+ * Статус оплаты заказа.
2264
+ */
2265
+ ScReferenceName["orderPaymentStatus"] = "order-payment-status";
2266
+ /**
2267
+ * Статус заказа.
2081
2268
  */
2082
2269
  ScReferenceName["orderStatus"] = "order-status";
2083
2270
  /**
@@ -2109,14 +2296,146 @@ var ScReferenceName;
2109
2296
  */
2110
2297
  ScReferenceName["warehouse"] = "warehouse";
2111
2298
  /**
2112
- * ОПФ (организационно-правовая форма).
2299
+ * ОПФ (организационно-правовая форма).
2300
+ */
2301
+ ScReferenceName["opf"] = "opf";
2302
+ /**
2303
+ * Валюта.
2304
+ */
2305
+ ScReferenceName["currency"] = "currency";
2306
+ })(ScReferenceName || (ScReferenceName = {}));
2307
+
2308
+ /* eslint-disable security/detect-object-injection,no-param-reassign */
2309
+ /**
2310
+ * Сервис конвертации данных.
2311
+ */
2312
+ class ScConvertersService {
2313
+ /**
2314
+ * Инициализирует экземпляр класса {@link ScConvertersService}.
2315
+ *
2316
+ * @param locale Язык приложения из поставщика.
2317
+ */
2318
+ constructor(locale) {
2319
+ this.locale = locale;
2320
+ }
2321
+ /**
2322
+ * Конвертирует объект в {@link HttpParams}.
2323
+ *
2324
+ * @param object Объект, которые нужно перевести в {@link HttpParams}.
2325
+ * @param options Параметры конвертации объекта.
2326
+ */
2327
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2328
+ toHttpParams(object, options) {
2329
+ object = this.toSimpleObjectRecursive(object);
2330
+ object = this.convertDateToString(object);
2331
+ if (options?.nonNullable) {
2332
+ object = tuiCleanObject(object);
2333
+ }
2334
+ if (options?.minLength) {
2335
+ object = this.removeByStrLength(object, options.minLength);
2336
+ }
2337
+ return new HttpParams().appendAll(object);
2338
+ }
2339
+ /**
2340
+ * Возвращает {@link T} объект из которого удалены свойства со значением null.
2341
+ *
2342
+ * @param object Объект, в котором необходимо удалить свойства со значением null.
2343
+ */
2344
+ // eslint-disable-next-line class-methods-use-this
2345
+ removeNull(object) {
2346
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2347
+ return Object.fromEntries(Object.entries(object).filter(([_, v]) => v !== null && v !== ''));
2348
+ }
2349
+ /**
2350
+ * Возвращает {@link T} объект из которого рекурсивно удалены свойства со значением null.
2351
+ *
2352
+ * @param object Объект, в котором необходимо удалить свойства со значением null.
2353
+ */
2354
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2355
+ removeNullRecursive(object) {
2356
+ // eslint-disable-next-line no-restricted-syntax
2357
+ for (const k of Object.keys(object)) {
2358
+ if (object[k] === null) {
2359
+ if (Array.isArray(object)) {
2360
+ object.splice(+k, 1);
2361
+ }
2362
+ else {
2363
+ // eslint-disable-next-line @typescript-eslint/no-dynamic-delete
2364
+ delete object[k];
2365
+ }
2366
+ this.removeNullRecursive(object);
2367
+ }
2368
+ else if (typeof object[k] === 'object') {
2369
+ this.removeNullRecursive(object[k]);
2370
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2371
+ if (Array.isArray(object) && Object.keys(object[k]).length === 0) {
2372
+ object.splice(+k, 1);
2373
+ }
2374
+ }
2375
+ }
2376
+ return object;
2377
+ }
2378
+ /**
2379
+ * Возвращает {@link T} объект из которого удалены свойства меньшей длины, чем {@link minLength}.
2380
+ *
2381
+ * @param object ООбъект, в котором необходимо удалить свойства меньшей длины, чем {@link minLength}.
2382
+ * @param minLength Минимально допустимая длина строковых свойств объекта.
2383
+ */
2384
+ // eslint-disable-next-line class-methods-use-this
2385
+ removeByStrLength(object, minLength) {
2386
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2387
+ return Object.fromEntries(Object.entries(object).filter(([_, v]) => (typeof v === 'string' && v.length > minLength) || typeof v !== 'string'));
2388
+ }
2389
+ /**
2390
+ * Конвертирует поля, имеющие тип {@link Date}, в {@link object}, и возвращает как новый объект.
2391
+ *
2392
+ * @param object Объект, в котором необходимо преобразовать поля Date в string.
2113
2393
  */
2114
- ScReferenceName["opf"] = "opf";
2394
+ convertDateToString(object) {
2395
+ return Object.fromEntries(Object.entries(object).map(([_, v]) => (v instanceof Date ? [_, v.toLocaleDateString(this.locale)] : [_, v])));
2396
+ }
2397
+ // eslint-disable-next-line class-methods-use-this
2398
+ createParamKeyString(keys) {
2399
+ // eslint-disable-next-line unicorn/no-array-reduce
2400
+ return keys.reduce((result, current, index) => (index === 0 ? current : `${result}[${current}]`), '');
2401
+ }
2115
2402
  /**
2116
- * Валюта.
2403
+ * Возвращает новое представление объекта в котором рекурсивно поля преобразованы в формат <patent_properties>[<child_properties>]... .
2404
+ *
2405
+ * @param object Объект, в котором необходимо преобразовать поля в формат <patent_properties>[<child_properties>]... .
2406
+ * @param keys Список ключей до объекта {@link object} в исходном объекте.
2407
+ * @param resultObject Итоговый объект.
2117
2408
  */
2118
- ScReferenceName["currency"] = "currency";
2119
- })(ScReferenceName || (ScReferenceName = {}));
2409
+ toSimpleObjectRecursive(
2410
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2411
+ object, keys = [],
2412
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
2413
+ resultObject = {}) {
2414
+ // eslint-disable-next-line no-restricted-syntax
2415
+ for (const key in object) {
2416
+ if (object.hasOwnProperty.call(object, key)) {
2417
+ if (typeof object[key] === 'object' && object[key] !== null && !(object[key] instanceof Date)) {
2418
+ this.toSimpleObjectRecursive(object[key], [...keys, key], resultObject);
2419
+ }
2420
+ else {
2421
+ resultObject[this.createParamKeyString([...keys, key])] = object[key];
2422
+ }
2423
+ }
2424
+ }
2425
+ return resultObject;
2426
+ }
2427
+ 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 }); }
2428
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScConvertersService, providedIn: 'root' }); }
2429
+ }
2430
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScConvertersService, decorators: [{
2431
+ type: Injectable,
2432
+ args: [{
2433
+ providedIn: 'root',
2434
+ }]
2435
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
2436
+ type: Inject,
2437
+ args: [LOCALE_ID]
2438
+ }] }] });
2120
2439
 
2121
2440
  /**
2122
2441
  * Сервис справочников.
@@ -2236,315 +2555,75 @@ class ScReferencesService {
2236
2555
  * @param slug Символьное обозначение (slug) типа клиента.
2237
2556
  */
2238
2557
  // 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 Количество элементов на странице пагинации.
2408
- */
2409
- setPaginatePageSize(paginatePageSize) {
2410
- this.setMetadataByKey('paginatePageSize', paginatePageSize);
2411
- }
2412
- /**
2413
- * Возвращает {@link Observable} метаданных неоформленного заказа по направлению продаж.
2414
- *
2415
- * @param directionsId Идентификатор направления продаж.
2416
- */
2417
- getNewOrderMetadata$(directionsId) {
2418
- // Данные представлены массивом объектов, поэтому не используется getMetadataChangeByKey$().
2419
- return this.userMetadataSubject.pipe(map((metadata) => metadata.newOrdersMetadata), distinctUntilChanged(), map((ordersMetadata) => ordersMetadata[directionsId]), distinctUntilChanged());
2420
- }
2421
- /**
2422
- * Устанавливает метаданные неоформленного заказа по направлению продаж.
2423
- *
2424
- * @param directionsId Идентификатор направления продаж.
2425
- * @param newOrderMetadata Данные нового неоформленного заказа.
2426
- */
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
- });
2558
+ getClientTypesBySlug$(slug) {
2559
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access
2560
+ return this.clientTypes$.pipe(map((types) => types.find((type) => type.name === slug)));
2441
2561
  }
2442
2562
  /**
2443
- * Удаляет метаданные неоформленного заказа по направлению продаж.
2563
+ * Возвращает {@link Observable} статус оплаты, соответствующий идентификатору на входе.
2444
2564
  *
2445
- * @param directionsId Идентификатор направления продаж.
2565
+ * @param typeId Идентификатор статуса оплаты.
2446
2566
  */
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
- });
2567
+ getPaymentStatusById$(typeId) {
2568
+ return this.paymentStatuses$.pipe(map((types) => types.find((type) => type.id === typeId)));
2455
2569
  }
2456
2570
  /**
2457
- * Удаляет метаданные не оформленных заказов по всем направлениям продаж.
2571
+ * Возвращает {@link Observable} тип доставки, соответствующий идентификатору на входе.
2572
+ *
2573
+ * @param typeId Идентификатор типа доставки.
2458
2574
  */
2459
- removeAllNewOrdersMetadata() {
2460
- this.setMetadataByKey('newOrdersMetadata', []);
2575
+ getDeliveryTypeById$(typeId) {
2576
+ return this.deliveryTypes$.pipe(map((types) => types.find((type) => type.id === typeId)));
2461
2577
  }
2462
2578
  /**
2463
- * Возвращает дату последнего открытия опросников.
2579
+ * Возвращает {@link Observable} тип статуса заказа, соответствующий идентификатору на входе.
2580
+ *
2581
+ * @param statusId Идентификатор типа статуса.
2464
2582
  */
2465
- getLastOpenQuestionnaireTime$() {
2466
- return this.getMetadataChangeByKey$('lastOpenQuestionnaireTime');
2583
+ getOrderStatusById$(statusId) {
2584
+ return this.orderStatuses$.pipe(map((types) => types.find((type) => type.id === statusId)));
2467
2585
  }
2468
2586
  /**
2469
- * Устанавливает дату последнего открытия опросников.
2587
+ * Возвращает {@link Observable} типа статуса рекламаций, соответствующий указанному идентификатору.
2470
2588
  *
2471
- * @param lastOpenQuestionnaireTime Дата последнего открытия опросников.
2589
+ * @param statusId Идентификатор типа статуса.
2472
2590
  */
2473
- setLastOpenQuestionnaireTime(lastOpenQuestionnaireTime) {
2474
- this.setMetadataByKey('lastOpenQuestionnaireTime', lastOpenQuestionnaireTime);
2591
+ getReclamationStatusById$(statusId) {
2592
+ return this.reclamationStatuses$.pipe(map((types) => types.find((type) => type.id === statusId)));
2475
2593
  }
2476
2594
  /**
2477
- * Возвращает формат отображения каталога.
2595
+ * Возвращает {@link Observable} тип оплаты, соответствующий идентификатору на входе.
2596
+ *
2597
+ * @param typeId Идентификатор типа оплаты.
2478
2598
  */
2479
- getCatalogFormat$() {
2480
- return this.getMetadataChangeByKey$('catalogFormat');
2599
+ getPaymentTypeById$(typeId) {
2600
+ return this.paymentTypes$.pipe(map((types) => types.find((type) => type.id === typeId)));
2481
2601
  }
2482
2602
  /**
2483
- * Устанавливает формат отображения каталога.
2603
+ * Возвращает {@link Observable} организационно-правовой формы, соответствующий символьному обозначению (slug) на входе.
2484
2604
  *
2485
- * @param catalogFormat Формат отображения каталога.
2605
+ * @param slug Символьное обозначение (slug).
2486
2606
  */
2487
- setCatalogFormat(catalogFormat) {
2488
- this.setMetadataByKey('catalogFormat', catalogFormat);
2607
+ getOpfBySlug$(slug) {
2608
+ return this.opf$.pipe(map((types) => types.find((type) => type.slug === slug)));
2489
2609
  }
2490
2610
  /**
2491
- * Устанавливает идентификатор выбранного склада.
2611
+ * Возвращает {@link Observable} валюты, соответствующий идентификатору на входе.
2492
2612
  *
2493
- * @param selectedWarehouseId Идентификатор выбранного склада.
2613
+ * @param currencyId Идентификатор валюты.
2494
2614
  */
2495
- setSelectedWarehouseId(selectedWarehouseId) {
2496
- this.setMetadataByKey('selectedWarehouseId', selectedWarehouseId);
2615
+ getCurrencyById$(currencyId) {
2616
+ return this.currencies$.pipe(map((types) => types.find((type) => type.id === currencyId)));
2497
2617
  }
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' }); }
2618
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScReferencesService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
2619
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScReferencesService, providedIn: 'root' }); }
2500
2620
  }
2501
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScUIService, decorators: [{
2621
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScReferencesService, decorators: [{
2502
2622
  type: Injectable,
2503
2623
  args: [{
2504
2624
  providedIn: 'root',
2505
2625
  }]
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
- ];
2626
+ }] });
2548
2627
 
2549
2628
  /**
2550
2629
  * Сервис для работы со складами.
@@ -2658,18 +2737,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
2658
2737
  }], ctorParameters: () => [] });
2659
2738
 
2660
2739
  /**
2661
- * Сервис для работы с корзиной.
2740
+ * Данные о сервисе корзины.
2662
2741
  */
2663
2742
  class ScCartService {
2664
2743
  /**
2665
2744
  * Инициализирует экземпляр класса {@link ScCartService}.
2666
- *
2667
2745
  */
2668
2746
  constructor() {
2669
- /**
2670
- * {@link ReplaySubject} для содержимого корзины.
2671
- */
2672
- this.cart$ = new ReplaySubject(1);
2673
2747
  /**
2674
2748
  * Признак, что скрипт выполняется в браузере.
2675
2749
  */
@@ -2699,72 +2773,73 @@ class ScCartService {
2699
2773
  */
2700
2774
  this.userMetrikaService = inject(ScUserMetrikaService);
2701
2775
  if (this.isBrowser) {
2702
- this.user$.pipe(switchMap(() => this.updateCart$())).subscribe((cart) => {
2703
- this.cart$.next(cart);
2776
+ this.cartCachedItem$ = new ScCachedItem(Infinity, this.getCartData$(), loadingPlaceholder);
2777
+ this.user$.subscribe(() => {
2778
+ this.cartCachedItem$.update();
2704
2779
  });
2705
2780
  }
2706
2781
  else {
2707
- this.cart$.next(new ScCart());
2782
+ this.cartCachedItem$ = new ScCachedItem(Infinity, of(new ScCart()), loadingPlaceholder);
2708
2783
  }
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
2784
  }
2713
2785
  /**
2714
- * Возвращает {@link Observable} содержимого корзины.
2786
+ * Создаёт запрос получения содержимого корзины и обновляет корзину, возвращая {@link Observable} содержимого корзины.
2715
2787
  */
2716
- getCartChange$() {
2717
- return this.cart$.asObservable();
2788
+ getCartData$() {
2789
+ return this.http.get(`${this.urls.apiUrl}/cart`).pipe(map((cartDTO) => new ScCart(cartDTO)));
2718
2790
  }
2719
2791
  /**
2720
- * Создаёт запрос получения содержимого корзины и обновляет корзину, возвращая {@link Observable} содержимого корзины.
2792
+ * Возвращает полную информацию о корзине (контекст загрузчика).
2721
2793
  */
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
- }));
2794
+ get$() {
2795
+ return this.cartCachedItem$.item$;
2726
2796
  }
2727
2797
  /**
2728
- * Создаёт запрос добавления товара в корзину и возвращает {@link Observable} содержимого корзины.
2798
+ * Возвращает список элементов корзины.
2799
+ */
2800
+ getItems$() {
2801
+ return this.get$().pipe(map((cart) => (cart === loadingPlaceholder ? loadingPlaceholder : cart.items)));
2802
+ }
2803
+ /**
2804
+ * Добавляет продукт в корзину.
2729
2805
  *
2730
- * @param cartNewItem Новый элемент корзины.
2806
+ * @param data Данные добавляемого продукта.
2731
2807
  */
2732
- addToCart$(cartNewItem) {
2733
- return this.http.patch(`${this.urls.apiUrl}/cart`, cartNewItem).pipe(map((cartDTO) => new ScCart(cartDTO)), tap(() => {
2734
- if (cartNewItem.productId) {
2808
+ addProduct$(data) {
2809
+ return this.http.patch(`${this.urls.apiUrl}/cart`, data).pipe(map((cartDTO) => new ScCart(cartDTO)), tap(() => {
2810
+ if (data.productId) {
2735
2811
  this.userMetrikaService.emitUserMetrikaEvent({
2736
2812
  target: ScUserMetrikaGoalsEnum.cartItemAdded,
2737
- params: { product_id: cartNewItem.productId },
2813
+ params: { product_id: data.productId },
2738
2814
  });
2739
2815
  }
2740
2816
  }), tap((cart) => {
2741
- this.cart$.next(cart);
2817
+ this.cartCachedItem$.setValue(cart);
2742
2818
  }));
2743
2819
  }
2744
2820
  /**
2745
- * Создаёт запрос обновления позиции в корзине и возвращает {@link Observable} содержимого корзины.
2821
+ * Изменяет продукт в корзине.
2746
2822
  *
2747
- * @param cartItemId Идентификатор элемента корзины.
2748
- * @param cartPatchItem Новые данные элемента корзины.
2823
+ * @param id Идентификатор позиции.
2824
+ * @param patch Частичные данные для обновления.
2749
2825
  */
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);
2826
+ updateProduct$(id, patch) {
2827
+ return this.http.patch(`${this.urls.apiUrl}/cart/${id}`, patch).pipe(map((cartDTO) => new ScCart(cartDTO)), tap((cart) => {
2828
+ this.cartCachedItem$.setValue(cart);
2753
2829
  }));
2754
2830
  }
2755
2831
  /**
2756
- * Создаёт запрос удаления позиции из корзины и возвращает {@link Observable} содержимого корзины.
2832
+ * Удаляет продукт из корзины.
2757
2833
  *
2758
- * @param cartItem Запись корзины, которую необходимо удалить.
2834
+ * @param item Удаляемая позиция.
2759
2835
  */
2760
- deleteCartItem$(cartItem) {
2761
- return this.http.delete(`${this.urls.apiUrl}/cart/${cartItem.id}`).pipe(map((cartDTO) => new ScCart(cartDTO)), tap(() => {
2836
+ deleteProduct$(item) {
2837
+ return this.http.delete(`${this.urls.apiUrl}/cart/${item.id}`).pipe(map((cartDTO) => new ScCart(cartDTO)), tap((cart) => {
2838
+ this.cartCachedItem$.setValue(cart);
2762
2839
  this.userMetrikaService.emitUserMetrikaEvent({
2763
2840
  target: ScUserMetrikaGoalsEnum.cartItemDeleted,
2764
- params: { product_id: cartItem.product.id },
2841
+ params: { product_id: item.product.id },
2765
2842
  });
2766
- }), tap((cart) => {
2767
- this.cart$.next(cart);
2768
2843
  }));
2769
2844
  }
2770
2845
  /**
@@ -2777,20 +2852,22 @@ class ScCartService {
2777
2852
  });
2778
2853
  }), tap(() => {
2779
2854
  this.uiService.removeAllNewOrdersMetadata();
2780
- this.cart$.next(new ScCart());
2855
+ this.cartCachedItem$.setValue(new ScCart());
2781
2856
  }));
2782
2857
  }
2783
2858
  /**
2784
- * Возвращает {@link Observable} содержимого корзины по направлениям продаж.
2859
+ * Обновляет корзину.
2785
2860
  */
2786
- getCartDirectionsChange$() {
2787
- return this.cartDirections$;
2861
+ updateCart() {
2862
+ this.cartCachedItem$.update();
2788
2863
  }
2789
2864
  /**
2790
2865
  * Возвращает {@link Observable} позиций в корзине с товарами, которые были удалены из прайс-лита и больше не продаются.
2866
+ *
2867
+ * @deprecated
2791
2868
  */
2792
2869
  getNullCartItems$() {
2793
- return this.getCartChange$().pipe(map((cart) => cart.items.filter((item) => item.product.isNull || item.product.isHidden)));
2870
+ return this.get$().pipe(map((cart) => (cart === loadingPlaceholder ? loadingPlaceholder : cart.items.filter((item) => item.product.isNull || item.product.isHidden))));
2794
2871
  }
2795
2872
  /**
2796
2873
  * Возвращает объект {@link ScCart} корзины, созданный из объекта заказа.
@@ -2800,7 +2877,7 @@ class ScCartService {
2800
2877
  // eslint-disable-next-line class-methods-use-this
2801
2878
  getCartByOrder(order) {
2802
2879
  return {
2803
- items: order.products ?? [],
2880
+ items: order.products,
2804
2881
  resultSum: { rub: order.sum },
2805
2882
  directionsSum: { [order.direction]: new ScSum(order.sum) },
2806
2883
  };
@@ -2822,7 +2899,7 @@ class ScCartService {
2822
2899
  */
2823
2900
  addProductsFromCsv$(file) {
2824
2901
  return this.http.post(`${this.urls.apiUrl}/cart/csv`, { file }).pipe(map((cartDTO) => new ScCart(cartDTO)), tap((cart) => {
2825
- this.cart$.next(cart);
2902
+ this.cartCachedItem$.setValue(cart);
2826
2903
  this.userMetrikaService.emitUserMetrikaEvent({
2827
2904
  target: ScUserMetrikaGoalsEnum.cartCsvUpload,
2828
2905
  });
@@ -2946,40 +3023,6 @@ class ScCachedData {
2946
3023
  }
2947
3024
  }
2948
3025
 
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
3026
  /**
2984
3027
  * Данные о виртуальной категории.
2985
3028
  */
@@ -3217,7 +3260,7 @@ class ScCatalogService {
3217
3260
  getVirtualCategoryCached$(slug) {
3218
3261
  let cachedItem = this.virtualCategoryMap.get(slug);
3219
3262
  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))));
3263
+ cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.http.get(`${this.urls.apiUrl}/catalog/v-categories/${slug}`).pipe(map((category) => new ScVirtualCategory(category))), null);
3221
3264
  this.virtualCategoryMap.set(slug, cachedItem);
3222
3265
  }
3223
3266
  if (!cachedItem.cachedDataIsActual()) {
@@ -3237,7 +3280,7 @@ class ScCatalogService {
3237
3280
  }
3238
3281
  let cachedItem = this.categoryMap.get(categoryIdOrSlug?.toString());
3239
3282
  if (!cachedItem) {
3240
- cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getCategoryData$(categoryIdOrSlug));
3283
+ cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getCategoryData$(categoryIdOrSlug), null);
3241
3284
  this.categoryMap.set(categoryIdOrSlug?.toString(), cachedItem);
3242
3285
  }
3243
3286
  if (!cachedItem.cachedDataIsActual()) {
@@ -3283,7 +3326,7 @@ class ScCatalogService {
3283
3326
  .get(`${this.urls.apiUrl}/catalog/products/${product.id}/price-history`, {
3284
3327
  context: SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT,
3285
3328
  })
3286
- .pipe(catchError(() => of({}))));
3329
+ .pipe(catchError(() => of({}))), null);
3287
3330
  this.productHistoryMap.set(product.id.toString(), cachedItem);
3288
3331
  }
3289
3332
  return cachedItem.item$;
@@ -3321,7 +3364,7 @@ class ScCatalogService {
3321
3364
  // eslint-disable-next-line @typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-call,@typescript-eslint/no-unsafe-member-access
3322
3365
  let cachedItem = this.categoryProductsMap.get(cachedKey.toString());
3323
3366
  if (!cachedItem) {
3324
- cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getProducts$(params));
3367
+ cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getProducts$(params), null);
3325
3368
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,@typescript-eslint/no-unsafe-argument,@typescript-eslint/no-unsafe-call
3326
3369
  this.categoryProductsMap.set(cachedKey.toString(), cachedItem);
3327
3370
  }
@@ -3350,7 +3393,7 @@ class ScCatalogService {
3350
3393
  }
3351
3394
  let cachedItem = this.productMap.get(productIdOrSlug.toString());
3352
3395
  if (!cachedItem) {
3353
- cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getProductData$(productIdOrSlug));
3396
+ cachedItem = new ScCachedItem(this.cacheLifeTime.categoryData, this.getProductData$(productIdOrSlug), null);
3354
3397
  this.productMap.set(productIdOrSlug.toString(), cachedItem);
3355
3398
  }
3356
3399
  if (!cachedItem.cachedDataIsActual()) {
@@ -3540,7 +3583,8 @@ class ScRecommendationService {
3540
3583
  .get(`${this.urls.apiUrl}/catalog/categories/${categoryIdOrSlug}/recommendations`, {
3541
3584
  context: SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT,
3542
3585
  })
3543
- .pipe(catchError(() => of([])), map((productsDTO) => productsDTO.map((product) => new ScProduct(product)))));
3586
+ .pipe(catchError(() => of([])), map((productsDTO) => productsDTO.map((product) => new ScProduct(product))))
3587
+ .pipe(startWith(null)), null);
3544
3588
  this.productsByCategoryMap.set(categoryIdOrSlug.toString(), cachedItem);
3545
3589
  }
3546
3590
  return cachedItem.item$;
@@ -3558,7 +3602,8 @@ class ScRecommendationService {
3558
3602
  .get(`${this.urls.apiUrl}/catalog/products/${productIdOrSlug}/recommendations`, {
3559
3603
  context: SC_IS_HIDDEN_ERROR_ALERT_HTTP_CONTEXT,
3560
3604
  })
3561
- .pipe(catchError(() => of([])), map((productsDTO) => productsDTO.map((product) => new ScProduct(product)))));
3605
+ .pipe(catchError(() => of([])), map((productsDTO) => productsDTO.map((product) => new ScProduct(product))))
3606
+ .pipe(startWith(null)), null);
3562
3607
  this.productsByProductMap.set(productIdOrSlug.toString(), cachedItem);
3563
3608
  }
3564
3609
  return cachedItem.item$;
@@ -3580,12 +3625,10 @@ class ScRecommendationService {
3580
3625
  * Создает запрос на получение списка рекомендованных товаров для корзины клиента.
3581
3626
  */
3582
3627
  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))),
3628
+ return this.cartService.get$().pipe(map((cart) => (cart !== loadingPlaceholder && 'items' in cart ? cart.items.map((item) => item.product.id) : [])),
3586
3629
  // Отфильтровываем повторения. Они возникнут если было изменено количество товара без удаления\добавления новых товаров.
3587
3630
  // 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))));
3631
+ 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
3632
  }
3590
3633
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScRecommendationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
3591
3634
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScRecommendationService, providedIn: 'root' }); }
@@ -4561,7 +4604,7 @@ class ScContragentService {
4561
4604
  let cachedItem = this.contactsService.contragentContactsMap.get(contragentId);
4562
4605
  if (!cachedItem) {
4563
4606
  // Устанавливаем время жизни cachedItem равное, потому что нам не важно время жизни. Нам нужен функционал update() в будущем.
4564
- cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/contragents/${contragentId}/contacts`));
4607
+ cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/contragents/${contragentId}/contacts`).pipe(startWith(null)), null);
4565
4608
  this.contactsService.contragentContactsMap.set(contragentId, cachedItem);
4566
4609
  }
4567
4610
  return cachedItem.item$;
@@ -4594,7 +4637,7 @@ class ScContragentService {
4594
4637
  let cachedItem = this.contragentBankAccountsMap.get(contragentId);
4595
4638
  if (!cachedItem) {
4596
4639
  // Устанавливаем время жизни cachedItem равное, потому что нам не важно время жизни. Нам нужен функционал update().
4597
- cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/contragents/${contragentId}/bank-accounts`));
4640
+ cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/contragents/${contragentId}/bank-accounts`).pipe(startWith(null)), null);
4598
4641
  this.contragentBankAccountsMap.set(contragentId, cachedItem);
4599
4642
  }
4600
4643
  return cachedItem.item$;
@@ -4706,7 +4749,9 @@ class ScDeliveryAddressService {
4706
4749
  let cachedItem = this.contactsService.deliveryAddressContactsMap.get(addressId);
4707
4750
  if (!cachedItem) {
4708
4751
  // Устанавливаем время жизни cachedItem равное, потому что нам не важно время жизни. Нам нужен функционал update().
4709
- cachedItem = new ScCachedItem(0, this.http.get(`${this.urls.apiUrl}/user/delivery-addresses/${addressId}/contacts`));
4752
+ cachedItem = new ScCachedItem(0, this.http
4753
+ .get(`${this.urls.apiUrl}/user/delivery-addresses/${addressId}/contacts`)
4754
+ .pipe(startWith(null)), null);
4710
4755
  this.contactsService.deliveryAddressContactsMap.set(addressId, cachedItem);
4711
4756
  }
4712
4757
  return cachedItem.item$;
@@ -5617,10 +5662,6 @@ var ScOpfList;
5617
5662
  // eslint-disable-next-line no-shadow
5618
5663
  var ScOrderStateStatus;
5619
5664
  (function (ScOrderStateStatus) {
5620
- /**
5621
- * Черновик.
5622
- */
5623
- ScOrderStateStatus[ScOrderStateStatus["draft"] = 0] = "draft";
5624
5665
  /**
5625
5666
  * Принято в обработку.
5626
5667
  */
@@ -6089,75 +6130,206 @@ class ScNotificationsService {
6089
6130
  return this.http.patch(`${this.urls.apiUrl}/user/notifications`, {});
6090
6131
  }
6091
6132
  /**
6092
- * Создает запрос на удаление уведомления по идентификатору.
6093
- *
6094
- * @param notificationId Идентификатор уведомления, которое необходимо удалить.
6133
+ * Создает запрос на удаление уведомления по идентификатору.
6134
+ *
6135
+ * @param notificationId Идентификатор уведомления, которое необходимо удалить.
6136
+ */
6137
+ deleteNotificationById$(notificationId) {
6138
+ return this.http.delete(`${this.urls.apiUrl}/user/notifications/${notificationId}`);
6139
+ }
6140
+ /**
6141
+ * Создает запрос на прочтение уведомления по идентификатору.
6142
+ *
6143
+ * @param notificationId Идентификатор уведомления, которое необходимо пометить прочитанным.
6144
+ */
6145
+ readNotificationById$(notificationId) {
6146
+ return this.http.patch(`${this.urls.apiUrl}/user/notifications/${notificationId}`, {});
6147
+ }
6148
+ /**
6149
+ * Возвращает {@link Observable} количества уведомлений пользователя.
6150
+ */
6151
+ getNotificationsCountChange$() {
6152
+ return this.notificationsCount$.asObservable();
6153
+ }
6154
+ /**
6155
+ * Возвращает {@link Observable} списка уведомлений пользователя.
6156
+ */
6157
+ getNotificationsChange$() {
6158
+ return this.notifications$.asObservable();
6159
+ }
6160
+ /**
6161
+ * Устанавливает {@link Observable} количества уведомлений пользователя.
6162
+ *
6163
+ * @param notificationsCount Данные о количестве уведомлений.
6164
+ */
6165
+ setNotificationsCountChange(notificationsCount) {
6166
+ this.notificationsCount$.next(notificationsCount);
6167
+ }
6168
+ /**
6169
+ * Устанавливает {@link Observable} списка уведомлений пользователя.
6170
+ *
6171
+ * @param notifications Данные о списке уведомлений.
6172
+ */
6173
+ setNotificationsChange(notifications) {
6174
+ this.notifications$.next(notifications);
6175
+ }
6176
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScNotificationsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6177
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScNotificationsService, providedIn: 'root' }); }
6178
+ }
6179
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScNotificationsService, decorators: [{
6180
+ type: Injectable,
6181
+ args: [{
6182
+ providedIn: 'root',
6183
+ }]
6184
+ }], ctorParameters: () => [] });
6185
+
6186
+ /**
6187
+ * Данные о стоимости доставки.
6188
+ */
6189
+ class ScDeliveryCost {
6190
+ /**
6191
+ * Инициализирует экземпляр класса {@link ScDeliveryCost}.
6192
+ *
6193
+ * @param deliveryCost Данные о стоимости доставки (DTO).
6194
+ * @param deliveryDate Дата доставки.
6195
+ */
6196
+ constructor(deliveryCost, deliveryDate) {
6197
+ if (deliveryCost.freeShippingTerms?.minOrdersSum !== undefined && deliveryCost.freeShippingTerms.currentOrdersSum !== undefined) {
6198
+ this.freeShippingTerms = { minOrdersSum: deliveryCost.freeShippingTerms.minOrdersSum, currentOrdersSum: deliveryCost.freeShippingTerms.currentOrdersSum };
6199
+ this.message = `Для оформления бесплатной доставки сумма заказов на ${deliveryDate} должна быть более ${this.freeShippingTerms.minOrdersSum.toLocaleString()} руб.<br>
6200
+ Текущая сумма заказов составляет ${this.freeShippingTerms.currentOrdersSum.toLocaleString()} руб`;
6201
+ }
6202
+ }
6203
+ }
6204
+
6205
+ /**
6206
+ * Базовые данные о заказе.
6207
+ */
6208
+ class ScOrderBase {
6209
+ /**
6210
+ * Инициализирует экземпляр класса {@link ScOrderBase}.
6211
+ *
6212
+ * @param data Данные для первоначальной инициализации.
6213
+ */
6214
+ constructor(data) {
6215
+ this.id = data.id;
6216
+ this.createdAt = data.createdAt;
6217
+ this.sum = data.sum;
6218
+ }
6219
+ /**
6220
+ * @inheritDoc
6221
+ */
6222
+ getSumStr() {
6223
+ return this.sum && this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6224
+ }
6225
+ /**
6226
+ * @inheritDoc
6227
+ */
6228
+ getSumMessage() {
6229
+ return this.sum === 0 ? 'Цена требует уточнения' : '';
6230
+ }
6231
+ }
6232
+
6233
+ /**
6234
+ * Данные о коммерческом предложении/черновике заказа.
6235
+ */
6236
+ class ScOrderDraft {
6237
+ /**
6238
+ * Инициализирует экземпляр класса {@link ScOrderDraft}.
6239
+ *
6240
+ * @param data Данные для первоначальной инициализации.
6241
+ */
6242
+ constructor(data) {
6243
+ /**
6244
+ * Дата последнего обновления данных.
6245
+ */
6246
+ this.lastUpdateDate = new Date();
6247
+ this.id = data.id;
6248
+ this.name = data.name;
6249
+ this.type = data.type;
6250
+ this.createdAt = data.createdAt;
6251
+ this.sum = data.sum;
6252
+ this.products = data.products.map((item) => new ScOrderItem(item));
6253
+ }
6254
+ /**
6255
+ * @inheritDoc
6095
6256
  */
6096
- deleteNotificationById$(notificationId) {
6097
- return this.http.delete(`${this.urls.apiUrl}/user/notifications/${notificationId}`);
6257
+ getSumStr() {
6258
+ return this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6098
6259
  }
6099
6260
  /**
6100
- * Создает запрос на прочтение уведомления по идентификатору.
6101
- *
6102
- * @param notificationId Идентификатор уведомления, которое необходимо пометить прочитанным.
6261
+ * @inheritDoc
6103
6262
  */
6104
- readNotificationById$(notificationId) {
6105
- return this.http.patch(`${this.urls.apiUrl}/user/notifications/${notificationId}`, {});
6263
+ getSumMessage() {
6264
+ return this.sum === 0 ? 'Цена требует уточнения' : '';
6106
6265
  }
6107
6266
  /**
6108
- * Возвращает {@link Observable} количества уведомлений пользователя.
6267
+ * @inheritDoc
6109
6268
  */
6110
- getNotificationsCountChange$() {
6111
- return this.notificationsCount$.asObservable();
6269
+ cachedDataIsActual(lifeTime) {
6270
+ return this.lastUpdateDate.getTime() >= Date.now() - lifeTime;
6112
6271
  }
6113
6272
  /**
6114
- * Возвращает {@link Observable} списка уведомлений пользователя.
6273
+ * @inheritDoc
6115
6274
  */
6116
- getNotificationsChange$() {
6117
- return this.notifications$.asObservable();
6275
+ updateData(offer) {
6276
+ this.name = offer.name;
6277
+ this.type = offer.type;
6278
+ this.sum = offer.sum;
6279
+ this.products = offer.products;
6280
+ this.lastUpdateDate = new Date();
6118
6281
  }
6119
6282
  /**
6120
- * Устанавливает {@link Observable} количества уведомлений пользователя.
6121
- *
6122
- * @param notificationsCount Данные о количестве уведомлений.
6283
+ * @inheritDoc
6123
6284
  */
6124
- setNotificationsCountChange(notificationsCount) {
6125
- this.notificationsCount$.next(notificationsCount);
6285
+ updateDataFromShortOffer(offer) {
6286
+ this.name = offer.name;
6287
+ this.type = offer.type;
6126
6288
  }
6289
+ }
6290
+
6291
+ /**
6292
+ * Данные о кратком коммерческом предложении/черновике заказа.
6293
+ */
6294
+ class ScOrderDraftShort extends ScOrderBase {
6127
6295
  /**
6128
- * Устанавливает {@link Observable} списка уведомлений пользователя.
6296
+ * Инициализирует экземпляр класса {@link ScOrderDraftShort}.
6129
6297
  *
6130
- * @param notifications Данные о списке уведомлений.
6298
+ * @param data Данные для первоначальной инициализации.
6131
6299
  */
6132
- setNotificationsChange(notifications) {
6133
- this.notifications$.next(notifications);
6300
+ constructor(data) {
6301
+ super(data);
6302
+ this.name = data.name;
6303
+ this.type = data.type;
6134
6304
  }
6135
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScNotificationsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6136
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScNotificationsService, providedIn: 'root' }); }
6137
6305
  }
6138
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScNotificationsService, decorators: [{
6139
- type: Injectable,
6140
- args: [{
6141
- providedIn: 'root',
6142
- }]
6143
- }], ctorParameters: () => [] });
6144
6306
 
6145
6307
  /**
6146
- * Модель данных о бесплатной доставке.
6308
+ * Данные о кратком заказе.
6147
6309
  */
6148
- class ScDeliveryCost {
6310
+ class ScOrderShort extends ScOrderBase {
6149
6311
  /**
6150
- * Инициализирует экземпляр класса {@link ScDeliveryCost}.
6312
+ * Инициализирует экземпляр класса {@link ScOrderShort}.
6151
6313
  *
6152
- * @param deliveryCost DTO данных о бесплатной доставке.
6153
- * @param deliveryDate Дата доставки.
6314
+ * @param data Данные для первоначальной инициализации.
6154
6315
  */
6155
- constructor(deliveryCost, deliveryDate) {
6156
- if (deliveryCost.freeShippingTerms?.minOrdersSum !== undefined && deliveryCost.freeShippingTerms.currentOrdersSum !== undefined) {
6157
- this.freeShippingTerms = { minOrdersSum: deliveryCost.freeShippingTerms.minOrdersSum, currentOrdersSum: deliveryCost.freeShippingTerms.currentOrdersSum };
6158
- this.message = `Для оформления бесплатной доставки сумма заказов на ${deliveryDate} должна быть более ${this.freeShippingTerms.minOrdersSum.toLocaleString()} руб.<br>
6159
- Текущая сумма заказов составляет ${this.freeShippingTerms.currentOrdersSum.toLocaleString()} руб`;
6160
- }
6316
+ constructor(data) {
6317
+ super(data);
6318
+ this.status = data.status;
6319
+ this.direction = data.direction;
6320
+ this.payment = data.payment;
6321
+ this.numberDoc = data.numberDoc;
6322
+ this.barcode = data.barcode;
6323
+ }
6324
+ /**
6325
+ * @inheritDoc
6326
+ */
6327
+ updateData(order) {
6328
+ this.status = order.status;
6329
+ this.direction = order.direction;
6330
+ this.payment = order.payment;
6331
+ this.sum = order.sum;
6332
+ this.delivery = order.delivery;
6161
6333
  }
6162
6334
  }
6163
6335
 
@@ -6177,6 +6349,22 @@ var ScDeliveryType;
6177
6349
  ScDeliveryType[ScDeliveryType["delivery"] = 2] = "delivery";
6178
6350
  })(ScDeliveryType || (ScDeliveryType = {}));
6179
6351
 
6352
+ /**
6353
+ * Перечисление типов коммерческих предложений/черновиков заказа.
6354
+ */
6355
+ // eslint-disable-next-line no-shadow
6356
+ var ScOrderDraftType;
6357
+ (function (ScOrderDraftType) {
6358
+ /**
6359
+ * Коммерческое предложение.
6360
+ */
6361
+ ScOrderDraftType["offer"] = "offer";
6362
+ /**
6363
+ * Заказ-черновик.
6364
+ */
6365
+ ScOrderDraftType["draft"] = "draft";
6366
+ })(ScOrderDraftType || (ScOrderDraftType = {}));
6367
+
6180
6368
  /**
6181
6369
  * Перечисление типов отплат заказа.
6182
6370
  */
@@ -6210,47 +6398,42 @@ var ScPaymentType;
6210
6398
  })(ScPaymentType || (ScPaymentType = {}));
6211
6399
 
6212
6400
  /**
6213
- * Полная информация о заказе.
6401
+ * Данные о заказе.
6214
6402
  */
6215
- class ScOrder {
6403
+ class ScOrder extends ScOrderShort {
6216
6404
  /**
6217
6405
  * Инициализирует экземпляр класса {@link ScOrder}.
6218
6406
  *
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;
6407
+ * @param data Данные для первоначальной инициализации.
6408
+ */
6409
+ constructor(data) {
6410
+ super(data);
6411
+ this.history = data.history;
6412
+ this.invoices = data.invoices;
6413
+ this.comment = data.comment;
6414
+ this.image = data.image;
6415
+ this.delivery = data.delivery;
6416
+ this.contragent = data.contragent;
6417
+ this.attachedUser = data.attachedUser;
6418
+ this.numberDoc = data.numberDoc;
6419
+ this.barcode = data.barcode;
6238
6420
  this.lastUpdateDate = new Date();
6421
+ this.products = data.products.map((item) => new ScOrderItem(item));
6239
6422
  }
6240
6423
  /**
6241
- * Тип оплаты.
6424
+ * @inheritDoc
6242
6425
  */
6243
6426
  get paymentType() {
6244
6427
  return this.payment.type;
6245
6428
  }
6246
6429
  /**
6247
- * Тип доставки.
6430
+ * @inheritDoc
6248
6431
  */
6249
6432
  get deliveryType() {
6250
6433
  return this.delivery.type;
6251
6434
  }
6252
6435
  /**
6253
- * Признак, что заказ можно оплатить online.
6436
+ * @inheritDoc
6254
6437
  */
6255
6438
  get isPayable() {
6256
6439
  return ([ScOrderStateStatus.new, ScOrderStateStatus.worked_out, ScOrderStateStatus.pending].includes(this.status) &&
@@ -6260,134 +6443,242 @@ class ScOrder {
6260
6443
  this.payment.onlinePaymentLink !== undefined);
6261
6444
  }
6262
6445
  /**
6263
- * Признак черновика заказа.
6264
- */
6265
- get isDraft() {
6266
- return this.status === ScOrderStateStatus.draft;
6267
- }
6268
- /**
6269
- * Признак, что заказ будет подлежать online-оплате.
6446
+ * @inheritDoc
6270
6447
  */
6271
6448
  get isPayableSoon() {
6272
- return (![ScOrderStateStatus.draft, ScOrderStateStatus.declined, ScOrderStateStatus.deleted, ScOrderStateStatus.completed].includes(this.status) &&
6449
+ return (![ScOrderStateStatus.declined, ScOrderStateStatus.deleted, ScOrderStateStatus.completed].includes(this.status) &&
6273
6450
  !this.isPayable &&
6274
6451
  this.payment.type === ScPaymentType.online);
6275
6452
  }
6276
6453
  /**
6277
- * Признак, что заказ завершён.
6454
+ * @inheritDoc
6278
6455
  */
6279
6456
  get isCompleted() {
6280
6457
  return [ScOrderStateStatus.completed, ScOrderStateStatus.declined, ScOrderStateStatus.deleted].includes(this.status);
6281
6458
  }
6282
6459
  /**
6283
- * Признак нового заказа.
6460
+ * @inheritDoc
6284
6461
  */
6285
6462
  get isNew() {
6286
6463
  return this.status === ScOrderStateStatus.new;
6287
6464
  }
6288
6465
  /**
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.
6466
+ * @inheritDoc
6304
6467
  */
6305
6468
  cachedDataIsActual(orderLifeTime) {
6306
6469
  return this.lastUpdateDate.getTime() >= Date.now() - orderLifeTime;
6307
6470
  }
6308
6471
  /**
6309
- * Обновляет данные полного заказа.
6310
- *
6311
- * @param order Полная информация о заказе.
6472
+ * @inheritDoc
6312
6473
  */
6313
6474
  updateData(order) {
6314
- this.status = order.status;
6315
- this.direction = order.direction;
6316
- this.payment = order.payment;
6317
- this.sum = order.sum;
6475
+ super.updateData(order);
6318
6476
  this.products = order.products;
6319
6477
  this.history = order.history;
6320
6478
  this.invoices = order.invoices;
6321
6479
  this.comment = order.comment;
6322
6480
  this.image = order.image;
6323
- this.delivery = order.delivery;
6324
6481
  this.contragent = order.contragent;
6325
6482
  this.attachedUser = order.attachedUser;
6326
6483
  this.lastUpdateDate = new Date();
6327
6484
  }
6328
6485
  /**
6329
- * Обновляет данные полного заказа данными краткой информации о заказе. Не обновляете дату последнего обновления.
6330
- *
6331
- * @param order Краткая информация о заказе.
6486
+ * @inheritDoc
6332
6487
  */
6333
6488
  updateDataFromShortOrder(order) {
6334
6489
  this.status = order.status;
6335
6490
  this.direction = order.direction;
6336
- this.payment = order.payment;
6337
6491
  this.sum = order.sum;
6338
- this.delivery.type = order.deliveryType;
6339
6492
  }
6340
6493
  }
6341
6494
 
6495
+ /* eslint-disable no-param-reassign */
6342
6496
  /**
6343
- * Краткая информация о заказе.
6497
+ * Данные о сервисе коммерческих предложений и черновиков заказов.
6344
6498
  */
6345
- class ScOrderShort {
6499
+ class ScOrderDraftsService {
6500
+ /**
6501
+ * Инициализирует экземпляр класса {@link ScOrderDraftsService}.
6502
+ */
6503
+ constructor() {
6504
+ /**
6505
+ * HTTP-клиент.
6506
+ */
6507
+ this.http = inject(HttpClient);
6508
+ /**
6509
+ * Список ссылок приложения.
6510
+ */
6511
+ this.urls = inject(SC_URLS);
6512
+ /**
6513
+ * {@link Observable} данных о текущем пользователе.
6514
+ */
6515
+ this.user$ = inject(SC_USER_INFO);
6516
+ /**
6517
+ * Интервалы обновления данных.
6518
+ */
6519
+ this.updateInterval = inject(SC_UPDATE_INTERVAL);
6520
+ /**
6521
+ * Сервис для работы с корзиной.
6522
+ */
6523
+ this.cartService = inject(ScCartService);
6524
+ /**
6525
+ * Сервис для сбора метрик о действиях пользователей.
6526
+ */
6527
+ this.userMetrikaService = inject(ScUserMetrikaService);
6528
+ /**
6529
+ * Коллекция пар ключ-значение для кэшированных коммерческих предложений/черновиков пользователя.
6530
+ */
6531
+ this.offerMap = new Map();
6532
+ this.user$.pipe(filter((user) => user.isGuest)).subscribe(() => {
6533
+ this.offerMap.clear();
6534
+ });
6535
+ }
6346
6536
  /**
6347
- * Инициализирует экземпляр класса {@link ScIOrderShortDTO}.
6537
+ * Возвращает список коммерческих предложений/черновиков с пагинацией.
6348
6538
  *
6349
- * @param orderDTO DTO Краткая информация о заказе.
6539
+ * @param params Параметры запроса получения списка.
6350
6540
  */
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;
6541
+ getList$(params) {
6542
+ return this.http.get(`${this.urls.apiUrl}/orders/offers`, { params: params }).pipe(map((offersPaginateDTO) => {
6543
+ offersPaginateDTO.data = offersPaginateDTO.data.map((item) => new ScOrderDraftShort(item));
6544
+ return offersPaginateDTO;
6545
+ }));
6361
6546
  }
6362
6547
  /**
6363
- * Возвращает сумму заказа в виде строки. Если стоимость отсутствует, то вернёт '-'.
6548
+ * Создаёт новое коммерческое предложение/черновик заказа.
6549
+ *
6550
+ * @param data Данные для создания.
6364
6551
  */
6365
- getSumStr() {
6366
- return this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6552
+ create$(data) {
6553
+ return this.http.post(`${this.urls.apiUrl}/orders/offers`, data).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6554
+ this.userMetrikaService.emitUserMetrikaEvent({
6555
+ target: ScUserMetrikaGoalsEnum.orderDraftCreated,
6556
+ params: { offer_id: offer.id },
6557
+ });
6558
+ this.cartService.updateCart();
6559
+ this.offerMap.set(offer.id, new ScCachedItem(this.updateInterval.orderData, of(offer), loadingPlaceholder));
6560
+ }));
6367
6561
  }
6368
6562
  /**
6369
- * Возвращает сообщение о необходимости уточнить сумму заказа или пустую строку.
6563
+ * Возвращает полную информацию о коммерческом предложении/черновике.
6564
+ *
6565
+ * @param draftId Идентификатор записи.
6566
+ * @param cacheable Признак возможности получения из кэшированных данных.
6370
6567
  */
6371
- getSumMessage() {
6372
- return this.sum === 0 ? 'Цена требует уточнения' : '';
6568
+ get$(draftId, cacheable = true) {
6569
+ let cachedItem = this.offerMap.get(draftId);
6570
+ if (!cachedItem) {
6571
+ cachedItem = new ScCachedItem(this.updateInterval.orderData, this.http.get(`${this.urls.apiUrl}/orders/offers/${draftId}`).pipe(map((data) => new ScOrderDraft(data))), loadingPlaceholder);
6572
+ if (cacheable) {
6573
+ this.offerMap.set(draftId, cachedItem);
6574
+ }
6575
+ }
6576
+ if (cacheable && !cachedItem.cachedDataIsActual()) {
6577
+ cachedItem.update();
6578
+ }
6579
+ return cachedItem.item$;
6373
6580
  }
6374
6581
  /**
6375
- * Обновляет данные заказа.
6582
+ * Возвращает список элементов коммерческого предложения/черновика.
6376
6583
  *
6377
- * @param order Краткая информация о заказе.
6584
+ * @param id Идентификатор коммерческого предложения/черновика.
6378
6585
  */
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;
6586
+ getItems$(id) {
6587
+ return this.get$(id).pipe(map((draft) => (draft === loadingPlaceholder ? loadingPlaceholder : draft.products)));
6588
+ }
6589
+ /**
6590
+ * Обновляет данные коммерческого предложения/черновика.
6591
+ *
6592
+ * @param draftId Идентификатор записи.
6593
+ * @param patch Данные для обновления.
6594
+ */
6595
+ update$(draftId, patch) {
6596
+ const cachedItem = this.offerMap.get(draftId);
6597
+ return this.http.patch(`${this.urls.apiUrl}/orders/offers/${draftId}`, patch).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6598
+ this.userMetrikaService.emitUserMetrikaEvent({
6599
+ target: ScUserMetrikaGoalsEnum.orderDraftUpdated,
6600
+ params: { offer_id: draftId },
6601
+ });
6602
+ cachedItem?.setValue(offer);
6603
+ }));
6604
+ }
6605
+ /**
6606
+ * Удаляет коммерческое предложение/черновик.
6607
+ *
6608
+ * @param offerId Идентификатор записи.
6609
+ */
6610
+ delete$(offerId) {
6611
+ return this.http.delete(`${this.urls.apiUrl}/orders/offers/${offerId}`).pipe(tap(() => {
6612
+ this.userMetrikaService.emitUserMetrikaEvent({
6613
+ target: ScUserMetrikaGoalsEnum.orderDraftDeleted,
6614
+ params: { offer_id: offerId },
6615
+ });
6616
+ this.offerMap.delete(offerId);
6617
+ }));
6618
+ }
6619
+ /**
6620
+ * Создаёт заказ на основе коммерческого предложения/черновика.
6621
+ *
6622
+ * @param offerId Идентификатор записи.
6623
+ * @param data Данные заказа.
6624
+ */
6625
+ createOrder$(offerId, data) {
6626
+ return this.http.post(`${this.urls.apiUrl}/orders/offers/${offerId}/create-order`, data).pipe(map((orders) => orders.map((item) => new ScOrderShort(item))), tap((orders) => {
6627
+ orders.forEach((order) => {
6628
+ this.userMetrikaService.emitUserMetrikaEvent({
6629
+ target: ScUserMetrikaGoalsEnum.orderCreatedFromDraft,
6630
+ params: { offer_id: offerId, order_id: order.id },
6631
+ });
6632
+ });
6633
+ }));
6634
+ }
6635
+ /**
6636
+ * Добавляет продукт в коммерческое предложение/черновик.
6637
+ *
6638
+ * @param productData Данные продукта для добавления.
6639
+ * @param offerId Идентификатор коммерческого предложения/черновика.
6640
+ */
6641
+ addProduct$(productData, offerId) {
6642
+ return this.http.post(`${this.urls.apiUrl}/orders/offers/${offerId}/products`, productData).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6643
+ this.offerMap.set(offerId, new ScCachedItem(this.updateInterval.orderData, of(offer), loadingPlaceholder));
6644
+ }));
6645
+ }
6646
+ /**
6647
+ * Изменяет продукт в коммерческом предложении/черновике.
6648
+ *
6649
+ * @param productId Идентификатор продукта в корзине.
6650
+ * @param patch Частичные данные для обновления.
6651
+ * @param offerId Идентификатор коммерческого предложения/черновика.
6652
+ */
6653
+ updateProduct$(productId, patch, offerId) {
6654
+ return this.http.patch(`${this.urls.apiUrl}/orders/offers/${offerId}/products/${productId}`, patch).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6655
+ this.offerMap.set(offerId, new ScCachedItem(this.updateInterval.orderData, of(offer), loadingPlaceholder));
6656
+ }));
6657
+ }
6658
+ /**
6659
+ * Удаляет продукт из коммерческого предложения/черновика.
6660
+ *
6661
+ * @param item Удаляемая позиция.
6662
+ * @param offerId Идентификатор коммерческого предложения/черновика.
6663
+ */
6664
+ deleteProduct$(item, offerId) {
6665
+ return this.http.delete(`${this.urls.apiUrl}/orders/offers/${offerId}/products/${item.id}`).pipe(map((offerDTO) => new ScOrderDraft(offerDTO)), tap((offer) => {
6666
+ this.offerMap.set(offerId, new ScCachedItem(this.updateInterval.orderData, of(offer), loadingPlaceholder));
6667
+ }));
6385
6668
  }
6669
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderDraftsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
6670
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderDraftsService, providedIn: 'root' }); }
6386
6671
  }
6672
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ScOrderDraftsService, decorators: [{
6673
+ type: Injectable,
6674
+ args: [{
6675
+ providedIn: 'root',
6676
+ }]
6677
+ }], ctorParameters: () => [] });
6387
6678
 
6388
6679
  /* eslint-disable no-param-reassign */
6389
6680
  /**
6390
- * Сервис для работы с заказами.
6681
+ * Данные о сервисе заказов.
6391
6682
  */
6392
6683
  class ScOrdersService {
6393
6684
  /**
@@ -6425,13 +6716,13 @@ class ScOrdersService {
6425
6716
  /**
6426
6717
  * Коллекция пар ключ-значение для заказов пользователя.
6427
6718
  */
6428
- this.idOrderMap = new Map();
6719
+ this.orderMap = new Map();
6429
6720
  /**
6430
6721
  * Формат дат.
6431
6722
  */
6432
6723
  this.dateFormats = inject(SC_DATE_FORMAT);
6433
6724
  this.user$.pipe(filter((user) => user.isGuest)).subscribe(() => {
6434
- this.idOrderMap.clear();
6725
+ this.orderMap.clear();
6435
6726
  });
6436
6727
  }
6437
6728
  /**
@@ -6477,15 +6768,6 @@ class ScOrdersService {
6477
6768
  return this.http.get(`${this.urls.apiUrl}/orders`, { params: params }).pipe(map((ordersPaginateDTO) => {
6478
6769
  ordersPaginateDTO.data = ordersPaginateDTO.data.map((item) => new ScOrderShort(item));
6479
6770
  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
6771
  }));
6490
6772
  }
6491
6773
  /**
@@ -6494,18 +6776,27 @@ class ScOrdersService {
6494
6776
  * @param orderId Идентификатор заказа.
6495
6777
  * @param cacheable Признак возможности получения заказа из кэшированных данных.
6496
6778
  */
6497
- getOrder$(orderId, cacheable = true) {
6498
- const orderMap = this.idOrderMap.get(orderId);
6499
- if (cacheable && orderMap?.cachedDataIsActual(this.updateInterval.orderData)) {
6500
- return of(orderMap);
6779
+ get$(orderId, cacheable = true) {
6780
+ let cachedItem = this.orderMap.get(orderId);
6781
+ if (!cachedItem) {
6782
+ cachedItem = new ScCachedItem(this.updateInterval.orderData, this.http.get(`${this.urls.apiUrl}/orders/${orderId}`).pipe(map((data) => new ScOrder(data))), loadingPlaceholder);
6783
+ if (cacheable) {
6784
+ this.orderMap.set(orderId, cachedItem);
6785
+ }
6501
6786
  }
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)));
6787
+ if (cacheable && !cachedItem.cachedDataIsActual()) {
6788
+ cachedItem.update();
6789
+ }
6790
+ return cachedItem.item$;
6791
+ }
6792
+ /**
6793
+ * Возвращает список элементов заказа.
6794
+ *
6795
+ * @param id Идентификатор заказа.
6796
+ * @param cacheable Признак возможности получения списка элементов заказа из кэшированных данных.
6797
+ */
6798
+ getItems$(id, cacheable = true) {
6799
+ return this.get$(id, cacheable).pipe(map((order) => (order === loadingPlaceholder ? loadingPlaceholder : order.products)));
6509
6800
  }
6510
6801
  /**
6511
6802
  * Копирует товары заказа в корзину текущего пользователя.
@@ -6518,7 +6809,9 @@ class ScOrdersService {
6518
6809
  target: ScUserMetrikaGoalsEnum.orderCloned,
6519
6810
  params: { order_id: orderId },
6520
6811
  });
6521
- }), switchMap(() => this.cartService.updateCart$()));
6812
+ }), tap(() => {
6813
+ this.cartService.updateCart();
6814
+ }));
6522
6815
  }
6523
6816
  /**
6524
6817
  * Отменяет заказ.
@@ -6533,33 +6826,6 @@ class ScOrdersService {
6533
6826
  });
6534
6827
  }));
6535
6828
  }
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
6829
  /**
6564
6830
  * Возвращает информацию о стоимости доставки.
6565
6831
  *
@@ -6915,6 +7181,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
6915
7181
  args: [SC_URLS]
6916
7182
  }] }] });
6917
7183
 
7184
+ /**
7185
+ * Данные об элементе навигационной цепочки.
7186
+ */
7187
+ class ScIBreadcrumbItem {
7188
+ constructor() {
7189
+ /**
7190
+ * Формат дополнительного заголовка.
7191
+ */
7192
+ this.subLabelFormat = 'base';
7193
+ }
7194
+ }
7195
+
6918
7196
  /**
6919
7197
  * Механизмы генерации схем данных Schema.org.
6920
7198
  */
@@ -6998,7 +7276,7 @@ class SchemaOrgFactory {
6998
7276
  // Основной контент страницы - список товаров и подкатегорий.
6999
7277
  mainEntity: this.createCategoryMainEntity(category, products, categoryPath, productPath),
7000
7278
  // Навигационные хлебные крошки (Schema.org: breadcrumb).
7001
- breadcrumb: breadcrumbs,
7279
+ breadcrumb: this.createCatalogBreadcrumbsList(breadcrumbs, categoryPath),
7002
7280
  // Дополнительные метаданные для SEO.
7003
7281
  about: {
7004
7282
  '@type': 'CategoryCode',
@@ -7168,6 +7446,44 @@ class SchemaOrgFactory {
7168
7446
  ],
7169
7447
  };
7170
7448
  }
7449
+ /**
7450
+ * Преобразует массив LinkData в BreadcrumbList для каталога.
7451
+ *
7452
+ * @param breadcrumbs Массив хлебных крошек.
7453
+ * @param categoryPath Url путь к категориям товаров. В пути должен присутствовать шаблон ':id', обозначающий идентификатор категории для подстановки.
7454
+ */
7455
+ createCatalogBreadcrumbsList(breadcrumbs, categoryPath) {
7456
+ const breadcrumbItems = [
7457
+ // Всегда добавляем главную страницу.
7458
+ {
7459
+ '@type': 'ListItem',
7460
+ position: 1,
7461
+ name: 'Главная',
7462
+ item: this.urls.siteUrl,
7463
+ },
7464
+ // Добавляем каталог.
7465
+ {
7466
+ '@type': 'ListItem',
7467
+ position: 2,
7468
+ name: 'Каталог',
7469
+ item: `${this.urls.siteUrl}/${categoryPath}`,
7470
+ },
7471
+ ];
7472
+ // Добавляем существующие breadcrumbs с корректировкой позиций.
7473
+ breadcrumbs.forEach((item, index) => {
7474
+ const link = isArray(item.routerLink) ? item.routerLink.join('/') : item.routerLink;
7475
+ breadcrumbItems.push({
7476
+ '@type': 'ListItem',
7477
+ position: index + 3, // Начинаем с позиции 3 (после Главная и Каталог).
7478
+ name: item.label,
7479
+ item: link ? `${this.urls.siteUrl}/${link}` : undefined,
7480
+ });
7481
+ });
7482
+ return {
7483
+ '@type': 'BreadcrumbList',
7484
+ itemListElement: breadcrumbItems,
7485
+ };
7486
+ }
7171
7487
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SchemaOrgFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
7172
7488
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SchemaOrgFactory, providedIn: 'root' }); }
7173
7489
  }
@@ -7281,7 +7597,7 @@ class ScSeoService {
7281
7597
  * @param urlPath Url путь к элементу каталога. В пути должен присутствовать шаблон ':id', обозначающий идентификатор элемента каталога для подстановки.
7282
7598
  * @param schemaOrgData Данные Schema.org элемента каталога
7283
7599
  */
7284
- setForCategoryItem(item, urlPath, schemaOrgData) {
7600
+ setForCatalogItem(item, urlPath, schemaOrgData) {
7285
7601
  const url = `${this.urls.siteUrl}${urlPath.replace(':id', this.idOrSlugPipe.transform(item).toString())}`;
7286
7602
  const title = item.seo?.title ?? `${item.name} - Купить в ${this.companyInfo.name}`;
7287
7603
  const description = item.seo?.description ?? `${item.name} - Купить по выгодным ценам в ${this.companyInfo.name}`;
@@ -7357,9 +7673,18 @@ class ScSeoService {
7357
7673
  * @param data Данные Schema.org для встраивания на странице.
7358
7674
  */
7359
7675
  setSchemaOrgData(data) {
7676
+ const projectAttributeName = 'data-sc-schema-org';
7677
+ // Удаляем все ранее созданные скрипты Schema.org (по уникальному атрибуту проекта).
7678
+ const existingScripts = this.document.head.querySelectorAll(`script[${projectAttributeName}]`);
7679
+ existingScripts.forEach((existingScript) => {
7680
+ if (existingScript.parentNode) {
7681
+ this.renderer.removeChild(existingScript.parentNode, existingScript);
7682
+ }
7683
+ });
7360
7684
  // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
7361
7685
  const script = this.renderer.createElement('script');
7362
7686
  this.renderer.setAttribute(script, 'type', 'application/ld+json');
7687
+ this.renderer.setAttribute(script, projectAttributeName, '');
7363
7688
  this.renderer.appendChild(script, this.document.createTextNode(JSON.stringify(data)));
7364
7689
  this.renderer.appendChild(this.document.head, script);
7365
7690
  }
@@ -7752,5 +8077,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
7752
8077
  * Generated bundle index. Do not edit.
7753
8078
  */
7754
8079
 
7755
- 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, 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 };
8080
+ 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 };
7756
8081
  //# sourceMappingURL=snabcentr-client-core.mjs.map