@snabcentr/client-core 4.18.0 → 4.21.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.
@@ -1,17 +1,18 @@
1
1
  import * as i1 from 'rxjs';
2
- import { of, startWith as startWith$1, Subject, ReplaySubject, partition, combineLatest, map as map$1, debounceTime, switchMap, tap, filter, shareReplay, distinctUntilChanged, BehaviorSubject, materialize, dematerialize, merge, distinctUntilKeyChanged, skip, first, catchError as catchError$1, throwError, expand, takeWhile, toArray, EMPTY, take, defaultIfEmpty, concatMap, finalize, takeUntil, timeout, interval, share, scan, defer, from, lastValueFrom, TimeoutError } from 'rxjs';
2
+ import { of, startWith as startWith$1, Subject, ReplaySubject, partition, combineLatest, map as map$1, debounceTime, switchMap, tap, filter, shareReplay, distinctUntilChanged, BehaviorSubject, materialize, dematerialize, merge, distinctUntilKeyChanged, skip, first, catchError as catchError$1, throwError, expand, takeWhile, toArray, EMPTY, take, defaultIfEmpty, concatMap, finalize, takeUntil, timeout, ignoreElements, interval, share, scan, defer, from, lastValueFrom, TimeoutError } from 'rxjs';
3
3
  import { map, startWith, catchError } from 'rxjs/operators';
4
4
  import { parseISO, parse, isValid, format } from 'date-fns';
5
5
  import { isString, constant, isNil, isObject, isDate, isMatch, isArray, omit, get, isNumber, isBoolean } from 'lodash-es';
6
6
  import * as i0 from '@angular/core';
7
- import { InjectionToken, inject, PLATFORM_ID, Inject, Optional, Injectable, EventEmitter, DestroyRef, LOCALE_ID, Pipe, RESPONSE_INIT, assertInInjectionContext, RendererFactory2, makeEnvironmentProviders } from '@angular/core';
7
+ import { InjectionToken, inject, PLATFORM_ID, Inject, Optional, Injectable, EventEmitter, DestroyRef, LOCALE_ID, Pipe, RESPONSE_INIT, provideAppInitializer, assertInInjectionContext, RendererFactory2, makeEnvironmentProviders } from '@angular/core';
8
8
  import { WA_LOCAL_STORAGE, WA_USER_AGENT, WA_WINDOW } from '@ng-web-apis/common';
9
9
  import { filterByKey, toValue, WA_STORAGE_EVENT, WaStorageService } from '@ng-web-apis/storage';
10
10
  import { isPlatformBrowser, isPlatformServer, DOCUMENT, formatDate } from '@angular/common';
11
11
  import * as i1$1 from '@angular/common/http';
12
12
  import { HttpContextToken, HttpContext, HttpHeaders, HttpClient, HttpParams, HttpErrorResponse, HttpResponse, FetchBackend, HttpXhrBackend, HttpStatusCode, HttpBackend } from '@angular/common/http';
13
13
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
14
- import { tuiIsPresent, TuiDay, TUI_TRUE_HANDLER } from '@taiga-ui/cdk';
14
+ import { tuiRound, tuiIsPresent, TuiDay, TUI_TRUE_HANDLER } from '@taiga-ui/cdk';
15
+ import { tuiFormatNumber } from '@taiga-ui/core';
15
16
  import { tuiCleanObject } from '@taiga-ui/addon-doc/utils';
16
17
  import * as i2 from '@angular/router';
17
18
  import { Router, NavigationEnd, ActivatedRoute } from '@angular/router';
@@ -1203,6 +1204,214 @@ class ScBanner {
1203
1204
  }
1204
1205
  }
1205
1206
 
1207
+ /**
1208
+ * Класс-помощник для работы с дробными числами.
1209
+ *
1210
+ * Округляет с учётом погрешности дробной арифметики, считает кратность шагу и задаёт настройки вывода чисел.
1211
+ */
1212
+ class ScNumberHelper {
1213
+ /**
1214
+ * Наибольшее количество знаков после запятой в проценте на экране.
1215
+ */
1216
+ static { this.percentDisplayFractionDigits = 2; }
1217
+ /**
1218
+ * Наибольшее количество знаков после запятой в площади, м².
1219
+ */
1220
+ static { this.areaFractionDigits = 4; }
1221
+ /**
1222
+ * Количество знаков после запятой в географических координатах.
1223
+ */
1224
+ static { this.coordinateFractionDigits = 6; }
1225
+ /**
1226
+ * Количество значащих цифр, до которого обрезается погрешность дробной арифметики.
1227
+ */
1228
+ static { this.significantDigits = 12; }
1229
+ /**
1230
+ * Допустимая погрешность сравнения дробных чисел.
1231
+ */
1232
+ static { this.epsilon = 0.000001; }
1233
+ /**
1234
+ * Настройки вывода площади.
1235
+ */
1236
+ static { this.areaFormat = {
1237
+ precision: ScNumberHelper.areaFractionDigits,
1238
+ decimalSeparator: ',',
1239
+ decimalMode: 'not-zero',
1240
+ rounding: 'round',
1241
+ }; }
1242
+ /**
1243
+ * Настройки вывода целых чисел.
1244
+ */
1245
+ static { this.integerFormat = {
1246
+ precision: 0,
1247
+ rounding: 'round',
1248
+ }; }
1249
+ /**
1250
+ * Настройки вывода процентов.
1251
+ */
1252
+ static { this.percentFormat = {
1253
+ precision: ScNumberHelper.percentDisplayFractionDigits,
1254
+ decimalSeparator: ',',
1255
+ decimalMode: 'not-zero',
1256
+ rounding: 'round',
1257
+ }; }
1258
+ /**
1259
+ * Настройки вывода денежных сумм по точности валюты.
1260
+ */
1261
+ static { this.moneyFormatsByPrecision = new Map(); }
1262
+ /**
1263
+ * Точность рубля из справочника валют ({@link ScICurrency.precision}) или undefined, если справочник не загружен.
1264
+ */
1265
+ static get rubPrecision() {
1266
+ return ScNumberHelper.rubPrecisionValue;
1267
+ }
1268
+ /**
1269
+ * Возвращает количество знаков после запятой в указанном числе с учётом экспоненциальной записи.
1270
+ *
1271
+ * @param value Число, для которого нужно определить количество знаков после запятой.
1272
+ */
1273
+ static getDecimalsCount(value) {
1274
+ if (!Number.isFinite(value) || Number.isInteger(value)) {
1275
+ return 0;
1276
+ }
1277
+ const [mantissa, exponent] = value.toString().split('e');
1278
+ const mantissaParts = mantissa.split('.');
1279
+ const decimals = mantissaParts.length > 1 ? mantissaParts[1].length : 0;
1280
+ return Math.max(decimals - (Number(exponent) || 0), 0);
1281
+ }
1282
+ /**
1283
+ * Возвращает число без погрешности дробной арифметики.
1284
+ *
1285
+ * @param value Число с возможной погрешностью.
1286
+ */
1287
+ static normalize(value) {
1288
+ return Number.isFinite(value) ? Number(value.toPrecision(ScNumberHelper.significantDigits)) : value;
1289
+ }
1290
+ /**
1291
+ * Возвращает значение, округлённое до указанного количества знаков после запятой.
1292
+ *
1293
+ * @param value Округляемое значение.
1294
+ * @param fractionDigits Количество знаков после запятой.
1295
+ */
1296
+ static round(value, fractionDigits) {
1297
+ return tuiRound(value, fractionDigits);
1298
+ }
1299
+ /**
1300
+ * Запоминает точность рубля из справочника валют.
1301
+ *
1302
+ * @param precision Точность рубля ({@link ScICurrency.precision}).
1303
+ */
1304
+ static setRubPrecision(precision) {
1305
+ ScNumberHelper.rubPrecisionValue = precision;
1306
+ }
1307
+ /**
1308
+ * Возвращает денежную сумму, округлённую до точности валюты.
1309
+ *
1310
+ * Без известной точности убирает только погрешность дробной арифметики.
1311
+ *
1312
+ * @param value Денежная сумма.
1313
+ * @param precision Точность валюты суммы ({@link ScICurrency.precision}), по умолчанию точность рубля.
1314
+ */
1315
+ static roundMoney(value, precision = ScNumberHelper.rubPrecision) {
1316
+ return precision === undefined ? ScNumberHelper.normalize(value) : ScNumberHelper.round(value, precision);
1317
+ }
1318
+ /**
1319
+ * Возвращает географическую координату, округлённую до точности хранения.
1320
+ *
1321
+ * @param value Координата.
1322
+ */
1323
+ static roundCoordinate(value) {
1324
+ return ScNumberHelper.round(value, ScNumberHelper.coordinateFractionDigits);
1325
+ }
1326
+ /**
1327
+ * Возвращает произведение значения на шаг, округлённое до точности множителей.
1328
+ *
1329
+ * @param value Множитель, обычно количество.
1330
+ * @param step Шаг.
1331
+ */
1332
+ static multiplyByStep(value, step) {
1333
+ return ScNumberHelper.round(value * step, ScNumberHelper.getDecimalsCount(step) + ScNumberHelper.getDecimalsCount(value));
1334
+ }
1335
+ /**
1336
+ * Возвращает частное от деления значения на шаг без погрешности дробной арифметики.
1337
+ *
1338
+ * @param value Делимое, обычно длина или количество.
1339
+ * @param step Шаг.
1340
+ */
1341
+ static divideByStep(value, step) {
1342
+ return ScNumberHelper.withoutNegativeZero(ScNumberHelper.normalize(value / step));
1343
+ }
1344
+ /**
1345
+ * Возвращает сумму значения и шага, округлённую до точности слагаемых.
1346
+ *
1347
+ * @param value Значение.
1348
+ * @param step Шаг.
1349
+ */
1350
+ static addStep(value, step) {
1351
+ return ScNumberHelper.round(value + step, Math.max(ScNumberHelper.getDecimalsCount(value), ScNumberHelper.getDecimalsCount(step)));
1352
+ }
1353
+ /**
1354
+ * Возвращает остаток от деления значения на шаг без погрешности дробной арифметики.
1355
+ *
1356
+ * @param value Значение.
1357
+ * @param step Шаг.
1358
+ */
1359
+ static remainder(value, step) {
1360
+ const quotient = Math.floor(ScNumberHelper.divideByStep(value, step));
1361
+ return ScNumberHelper.round(value - quotient * step, Math.max(ScNumberHelper.getDecimalsCount(value), ScNumberHelper.getDecimalsCount(step)));
1362
+ }
1363
+ /**
1364
+ * Возвращает значение, приведённое к ближайшему кратному шагу, с точностью шага.
1365
+ *
1366
+ * @param value Значение.
1367
+ * @param step Шаг.
1368
+ */
1369
+ static snapToStep(value, step) {
1370
+ return ScNumberHelper.multiplyByStep(Math.round(ScNumberHelper.divideByStep(value, step)), step);
1371
+ }
1372
+ /**
1373
+ * Возвращает признак того, что значение кратно шагу с учётом погрешности дробной арифметики.
1374
+ *
1375
+ * @param value Значение.
1376
+ * @param step Шаг.
1377
+ */
1378
+ static isMultipleOf(value, step) {
1379
+ const quotient = value / step;
1380
+ return Math.abs(quotient - Math.round(quotient)) < ScNumberHelper.epsilon;
1381
+ }
1382
+ /**
1383
+ * Возвращает настройки вывода денежной суммы с числом знаков после запятой, равным точности валюты.
1384
+ *
1385
+ * @param precision Точность валюты суммы ({@link ScICurrency.precision}), по умолчанию точность рубля.
1386
+ */
1387
+ static getMoneyFormat(precision = ScNumberHelper.rubPrecision) {
1388
+ const formatPrecision = precision ?? Number.POSITIVE_INFINITY;
1389
+ let format = ScNumberHelper.moneyFormatsByPrecision.get(formatPrecision);
1390
+ if (!format) {
1391
+ format = { precision: formatPrecision, decimalSeparator: ',', decimalMode: 'always', rounding: 'round' };
1392
+ ScNumberHelper.moneyFormatsByPrecision.set(formatPrecision, format);
1393
+ }
1394
+ return format;
1395
+ }
1396
+ /**
1397
+ * Возвращает денежную сумму в виде строки с разделителями разрядов и числом знаков после запятой, равным точности валюты.
1398
+ *
1399
+ * @param value Денежная сумма.
1400
+ * @param precision Точность валюты суммы ({@link ScICurrency.precision}), по умолчанию точность рубля.
1401
+ */
1402
+ static formatMoney(value, precision = ScNumberHelper.rubPrecision) {
1403
+ return tuiFormatNumber(ScNumberHelper.roundMoney(value, precision), ScNumberHelper.getMoneyFormat(precision));
1404
+ }
1405
+ /**
1406
+ * Возвращает число, в котором отрицательный ноль заменён на ноль.
1407
+ *
1408
+ * @param value Число.
1409
+ */
1410
+ static withoutNegativeZero(value) {
1411
+ return value === 0 ? 0 : value;
1412
+ }
1413
+ }
1414
+
1206
1415
  /**
1207
1416
  * Перечисление типов клиента.
1208
1417
  */
@@ -1273,10 +1482,10 @@ class ScUser {
1273
1482
  return this.userType === ScUserType.guest;
1274
1483
  }
1275
1484
  /**
1276
- * Округлённая задолженность. В шаблоне не определён {@link Math}.
1485
+ * Задолженность по модулю, округлённая до точности рубля.
1277
1486
  */
1278
1487
  get absDebt() {
1279
- return Math.abs(this.debt ?? 0);
1488
+ return ScNumberHelper.roundMoney(Math.abs(this.debt ?? 0));
1280
1489
  }
1281
1490
  }
1282
1491
 
@@ -1487,7 +1696,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
1487
1696
  }]
1488
1697
  }] });
1489
1698
 
1490
- const EMPTY_CART = { items: [], result_sum: { rub: 0 }, directions_sum: {} };
1699
+ const EMPTY_CART = { items: [], result_sum: { rub: 0 } };
1491
1700
 
1492
1701
  /**
1493
1702
  * Данные об итоговой сумме.
@@ -1738,6 +1947,7 @@ class ScProduct extends ScCatalogItem {
1738
1947
  else {
1739
1948
  this.image = data.images?.find((img) => img.isDefault)?.image ?? data.properties?.image;
1740
1949
  this.supplierSku = data.supplierSku;
1950
+ this.brand = data.brand;
1741
1951
  this.cost = data.cost;
1742
1952
  this.costRub = data.costRub;
1743
1953
  this.costDate = data.costDate;
@@ -1761,19 +1971,19 @@ class ScProduct extends ScCatalogItem {
1761
1971
  * Стоимость товара или услуги с валютой и единицей измерения.
1762
1972
  */
1763
1973
  get costString() {
1764
- return this.cost ? `${this.cost.toLocaleString()} ${this.currency.symbol} / ${this.unit.name}` : '';
1974
+ return this.cost ? `${ScNumberHelper.formatMoney(this.cost, this.currency.precision)} ${this.currency.symbol} / ${this.unit.name}` : '';
1765
1975
  }
1766
1976
  /**
1767
1977
  * Стоимость товара или услуги в рублях и с единицей измерения.
1768
1978
  */
1769
1979
  get costRubString() {
1770
- return this.costRub ? `${this.costRub.toLocaleString()} ₽ / ${this.unit.name}` : '';
1980
+ return this.costRub ? `${ScNumberHelper.formatMoney(this.costRub)} ₽ / ${this.unit.name}` : '';
1771
1981
  }
1772
1982
  /**
1773
1983
  * Стоимость товара или услуги с валютой и единицей измерения до применения скидки.
1774
1984
  */
1775
1985
  get discountCostString() {
1776
- return this.discount?.oldCost ? `${this.discount.oldCost.toLocaleString()} ${this.currency.symbol} / ${this.unit.name}` : '';
1986
+ return this.discount?.oldCost ? `${ScNumberHelper.formatMoney(this.discount.oldCost, this.currency.precision)} ${this.currency.symbol} / ${this.unit.name}` : '';
1777
1987
  }
1778
1988
  /**
1779
1989
  * Признак, что товар продаётся в рублях.
@@ -1879,7 +2089,6 @@ class ScOrderItem {
1879
2089
  this.length = data.length;
1880
2090
  this.width = data.width;
1881
2091
  this.logicGroupId = data.logicGroupId;
1882
- this.salesDirection = data.salesDirection;
1883
2092
  this.specificationImgUrl = data.specificationImgUrl;
1884
2093
  this.configurator = data.configurator;
1885
2094
  this.configuratorParams = data.configuratorParams;
@@ -1888,25 +2097,25 @@ class ScOrderItem {
1888
2097
  * @inheritDoc
1889
2098
  */
1890
2099
  getCostPerItem() {
1891
- return this.costOne > 0 ? `${this.costOne.toLocaleString()} ${this.product.currency.symbol}` : '-';
2100
+ return this.costOne > 0 ? `${ScNumberHelper.formatMoney(this.costOne, this.product.currency.precision)} ${this.product.currency.symbol}` : '-';
1892
2101
  }
1893
2102
  /**
1894
2103
  * @inheritDoc
1895
2104
  */
1896
2105
  getCostInCurrencyDescPerItem() {
1897
- return this.costOne > 0 ? `${this.costOne.toLocaleString()} ${this.product.currency.symbol} / ${this.product.unit.name}` : '-';
2106
+ return this.costOne > 0 ? `${ScNumberHelper.formatMoney(this.costOne, this.product.currency.precision)} ${this.product.currency.symbol} / ${this.product.unit.name}` : '-';
1898
2107
  }
1899
2108
  /**
1900
2109
  * @inheritDoc
1901
2110
  */
1902
2111
  getCostInRubDescPerItem() {
1903
- return this.costOneRub > 0 ? `${this.costOneRub.toLocaleString()} ₽ / ${this.product.unit.name}` : '-';
2112
+ return this.costOneRub > 0 ? `${ScNumberHelper.formatMoney(this.costOneRub)} ₽ / ${this.product.unit.name}` : '-';
1904
2113
  }
1905
2114
  /**
1906
2115
  * @inheritDoc
1907
2116
  */
1908
2117
  getCostRubStr() {
1909
- return this.costRub > 0 ? `${this.costRub.toLocaleString()} ₽` : '-';
2118
+ return this.costRub > 0 ? `${ScNumberHelper.formatMoney(this.costRub)} ₽` : '-';
1910
2119
  }
1911
2120
  /**
1912
2121
  * @inheritDoc
@@ -1926,10 +2135,9 @@ class ScCart {
1926
2135
  * @param data Данные для первоначальной инициализации.
1927
2136
  */
1928
2137
  // eslint-disable-next-line unicorn/no-object-as-default-parameter
1929
- constructor(data = { items: [], resultSum: { rub: 0 }, directionsSum: {} }) {
2138
+ constructor(data = { items: [], resultSum: { rub: 0 } }) {
1930
2139
  this.items = data.items.map((item) => new ScOrderItem(item));
1931
2140
  this.resultSum = data.resultSum;
1932
- this.directionsSum = data.directionsSum;
1933
2141
  }
1934
2142
  }
1935
2143
 
@@ -2070,15 +2278,14 @@ class ScUserMetadata {
2070
2278
  * Вид отображения плиток товаров.
2071
2279
  */
2072
2280
  this.productTileType = ScProductTileType.grid;
2073
- /**
2074
- * Метаданные не оформленных заказов.
2075
- */
2076
- this.newOrdersMetadata = [];
2077
2281
  /**
2078
2282
  * Формат отображения каталога.
2079
2283
  */
2080
2284
  this.catalogFormat = ScCatalogFormat.normal;
2081
- Object.assign(this, data);
2285
+ const metadata = { ...data };
2286
+ // Устаревший ключ черновика заказа по направлениям, не переносится в актуальные метаданные.
2287
+ delete metadata['newOrdersMetadata'];
2288
+ Object.assign(this, metadata);
2082
2289
  }
2083
2290
  }
2084
2291
 
@@ -2186,54 +2393,28 @@ class ScUIService {
2186
2393
  this.setMetadataByKey('paginatePageSize', paginatePageSize);
2187
2394
  }
2188
2395
  /**
2189
- * Возвращает {@link Observable} метаданных неоформленного заказа по направлению продаж.
2190
- *
2191
- * @param directionsId Идентификатор направления продаж.
2396
+ * Возвращает {@link Observable} метаданных неоформленного заказа.
2192
2397
  */
2193
- getNewOrderMetadata$(directionsId) {
2194
- // Данные представлены массивом объектов, поэтому не используется getMetadataChangeByKey$().
2195
- return this.userMetadataSubject.pipe(map$1((metadata) => metadata.newOrdersMetadata), distinctUntilChanged(), map$1((ordersMetadata) => ordersMetadata[directionsId]), distinctUntilChanged());
2398
+ getNewOrderMetadata$() {
2399
+ return this.getMetadataChangeByKey$('newOrderMetadata');
2196
2400
  }
2197
2401
  /**
2198
- * Устанавливает метаданные неоформленного заказа по направлению продаж.
2402
+ * Устанавливает метаданные неоформленного заказа.
2199
2403
  *
2200
- * @param directionsId Идентификатор направления продаж.
2201
2404
  * @param newOrderMetadata Данные нового неоформленного заказа.
2202
2405
  */
2203
- setNewOrderMetadata(directionsId, newOrderMetadata) {
2406
+ setNewOrderMetadata(newOrderMetadata) {
2204
2407
  // При сохранении изображения выдаёт ошибку 500 'Произошла ошибка при работе с базой данных'.
2205
2408
  // TODO: TASK[#6370]: Доработать после решения задачи.
2206
- if (newOrderMetadata.image) {
2207
- // eslint-disable-next-line no-param-reassign
2208
- delete newOrderMetadata.image;
2209
- }
2210
- this.getMetadataChangeByKey$('newOrdersMetadata')
2211
- .pipe(first())
2212
- .subscribe((ordersMetadata) => {
2213
- // eslint-disable-next-line no-param-reassign
2214
- ordersMetadata[directionsId] = newOrderMetadata;
2215
- this.setMetadataByKey('newOrdersMetadata', structuredClone(ordersMetadata));
2216
- });
2217
- }
2218
- /**
2219
- * Удаляет метаданные неоформленного заказа по направлению продаж.
2220
- *
2221
- * @param directionsId Идентификатор направления продаж.
2222
- */
2223
- removeNewOrderMetadata(directionsId) {
2224
- this.getMetadataChangeByKey$('newOrdersMetadata')
2225
- .pipe(first())
2226
- .subscribe((ordersMetadata) => {
2227
- // eslint-disable-next-line @typescript-eslint/no-dynamic-delete,no-param-reassign
2228
- delete ordersMetadata[directionsId];
2229
- this.setMetadataByKey('newOrdersMetadata', structuredClone(ordersMetadata));
2230
- });
2409
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2410
+ const { image, ...newOrderMetadataWithoutImage } = newOrderMetadata;
2411
+ this.setMetadataByKey('newOrderMetadata', newOrderMetadataWithoutImage);
2231
2412
  }
2232
2413
  /**
2233
- * Удаляет метаданные не оформленных заказов по всем направлениям продаж.
2414
+ * Удаляет метаданные неоформленного заказа.
2234
2415
  */
2235
- removeAllNewOrdersMetadata() {
2236
- this.setMetadataByKey('newOrdersMetadata', []);
2416
+ removeNewOrderMetadata() {
2417
+ this.setMetadataByKey('newOrderMetadata', undefined);
2237
2418
  }
2238
2419
  /**
2239
2420
  * Возвращает дату последнего открытия опросников.
@@ -2958,7 +3139,7 @@ class ScCartService {
2958
3139
  target: ScUserMetrikaGoalsEnum.cartCleared,
2959
3140
  });
2960
3141
  }), tap(() => {
2961
- this.uiService.removeAllNewOrdersMetadata();
3142
+ this.uiService.removeNewOrderMetadata();
2962
3143
  this.cartCachedItem$.setValue(new ScCart());
2963
3144
  }));
2964
3145
  }
@@ -2976,19 +3157,6 @@ class ScCartService {
2976
3157
  getNullCartItems$() {
2977
3158
  return this.get$().pipe(map$1((cart) => (cart === loadingPlaceholder ? loadingPlaceholder : cart.items.filter((item) => item.product.isNull || item.product.isHidden))));
2978
3159
  }
2979
- /**
2980
- * Возвращает объект {@link ScCart} корзины, созданный из объекта заказа.
2981
- *
2982
- * @param order Данные о заказе.
2983
- */
2984
- // eslint-disable-next-line class-methods-use-this
2985
- getCartByOrder(order) {
2986
- return {
2987
- items: order.products,
2988
- resultSum: { rub: order.sum },
2989
- directionsSum: { [order.salesDirection.id]: new ScSum(order.sum) },
2990
- };
2991
- }
2992
3160
  /**
2993
3161
  * Возвращает пример CSV файла для добавления продуктов в корзину.
2994
3162
  */
@@ -6276,6 +6444,22 @@ var ScReclamationStatus;
6276
6444
  ScReclamationStatus[ScReclamationStatus["completed"] = 4] = "completed";
6277
6445
  })(ScReclamationStatus || (ScReclamationStatus = {}));
6278
6446
 
6447
+ /**
6448
+ * Загружает точность рубля из справочника валют при старте приложения.
6449
+ */
6450
+ function loadRubPrecision() {
6451
+ return inject(ScReferencesService).currencies$.pipe(tap((currencies) => {
6452
+ ScNumberHelper.setRubPrecision(currencies.find((currency) => currency.signature === 'RUB')?.precision);
6453
+ }), ignoreElements(), catchError$1(() => EMPTY));
6454
+ }
6455
+ /**
6456
+ * Возвращает провайдеры загрузки точности рубля из справочника валют при старте приложения.
6457
+ * По этой точности {@link ScNumberHelper} округляет и выводит рублёвые суммы.
6458
+ */
6459
+ function provideRubPrecision() {
6460
+ return provideAppInitializer(loadRubPrecision);
6461
+ }
6462
+
6279
6463
  /**
6280
6464
  * Сервис для получения списков стран, регионов, городов.
6281
6465
  */
@@ -6742,8 +6926,8 @@ class ScDeliveryCost {
6742
6926
  constructor(deliveryCost, deliveryDate) {
6743
6927
  if (deliveryCost.freeShippingTerms?.minOrdersSum !== undefined && deliveryCost.freeShippingTerms.currentOrdersSum !== undefined) {
6744
6928
  this.freeShippingTerms = { minOrdersSum: deliveryCost.freeShippingTerms.minOrdersSum, currentOrdersSum: deliveryCost.freeShippingTerms.currentOrdersSum };
6745
- this.message = `Для оформления бесплатной доставки сумма заказов на ${deliveryDate} должна быть более ${this.freeShippingTerms.minOrdersSum.toLocaleString()} руб.<br>
6746
- Текущая сумма заказов составляет ${this.freeShippingTerms.currentOrdersSum.toLocaleString()} руб`;
6929
+ this.message = `Для оформления бесплатной доставки сумма заказов на ${deliveryDate} должна быть более ${ScNumberHelper.formatMoney(this.freeShippingTerms.minOrdersSum)} руб.<br>
6930
+ Текущая сумма заказов составляет ${ScNumberHelper.formatMoney(this.freeShippingTerms.currentOrdersSum)} руб`;
6747
6931
  }
6748
6932
  }
6749
6933
  }
@@ -6766,7 +6950,7 @@ class ScOrderBase {
6766
6950
  * @inheritDoc
6767
6951
  */
6768
6952
  getSumStr() {
6769
- return this.sum && this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6953
+ return this.sum && this.sum > 0 ? `${ScNumberHelper.formatMoney(this.sum)} ₽` : '-';
6770
6954
  }
6771
6955
  /**
6772
6956
  * @inheritDoc
@@ -6801,7 +6985,7 @@ class ScOrderDraft {
6801
6985
  * @inheritDoc
6802
6986
  */
6803
6987
  getSumStr() {
6804
- return this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6988
+ return this.sum > 0 ? `${ScNumberHelper.formatMoney(this.sum)} ₽` : '-';
6805
6989
  }
6806
6990
  /**
6807
6991
  * @inheritDoc
@@ -7205,7 +7389,7 @@ class ScOrderDraftsService {
7205
7389
  }
7206
7390
  const updatedDraft = new ScOrderDraft(currentDraft);
7207
7391
  updatedDraft.products = remainingProducts;
7208
- updatedDraft.sum = remainingProducts.reduce((sum, product) => sum + product.costRub, 0);
7392
+ updatedDraft.sum = ScNumberHelper.roundMoney(remainingProducts.reduce((sum, product) => sum + product.costRub, 0));
7209
7393
  cachedItem.setValue(updatedDraft);
7210
7394
  });
7211
7395
  }
@@ -7309,13 +7493,12 @@ class ScOrdersService {
7309
7493
  });
7310
7494
  }
7311
7495
  /**
7312
- * Создаёт запрос нового заказа по указанному направлению продаж.
7496
+ * Создаёт заказы из выбранных позиций корзины.
7313
7497
  *
7314
- * @param directionId Идентификатор направления продаж.
7315
7498
  * @param newOrder Данные нового заказа.
7316
7499
  */
7317
- createOrder$(directionId, newOrder) {
7318
- return this.http.post(`${this.urls.apiUrl}/orders/${directionId}`, newOrder).pipe(map$1((orders) => orders.map((item) => new ScOrderShort(item))), tap((orders) => {
7500
+ createOrder$(newOrder) {
7501
+ return this.http.post(`${this.urls.apiUrl}/orders/from-cart`, newOrder).pipe(map$1((orders) => orders.map((item) => new ScOrderShort(item))), tap((orders) => {
7319
7502
  orders.forEach((order) => {
7320
7503
  this.userMetrikaService.emitUserMetrikaEvent({
7321
7504
  target: ScUserMetrikaGoalsEnum.orderCreated,
@@ -7323,7 +7506,7 @@ class ScOrdersService {
7323
7506
  });
7324
7507
  });
7325
7508
  }), tap(() => {
7326
- this.uiService.removeNewOrderMetadata(directionId);
7509
+ this.uiService.removeNewOrderMetadata();
7327
7510
  }));
7328
7511
  }
7329
7512
  /**
@@ -7958,7 +8141,6 @@ class SchemaOrgFactory {
7958
8141
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
7959
8142
  const image = this.mediaImageTransformerPipe.transform(product?.getImagePreview?.() ?? product.image, true);
7960
8143
  const description = product.properties?.description;
7961
- const priceValidUntil = this.normalizePriceValidUntil(product.discount?.expiredAt);
7962
8144
  return {
7963
8145
  '@context': 'https://schema.org',
7964
8146
  '@type': 'Product',
@@ -7966,21 +8148,16 @@ class SchemaOrgFactory {
7966
8148
  name: product.name,
7967
8149
  ...(image && { image }),
7968
8150
  ...(description && { description: this.stripHtml(description) }),
7969
- mpn: product.code,
7970
- url: productUrl,
7971
- offers: {
7972
- '@type': 'Offer',
7973
- priceCurrency: 'RUB',
7974
- ...(priceValidUntil && { priceValidUntil }),
7975
- price: product.costRub,
7976
- availability: this.getAvailability(product),
7977
- itemCondition: 'https://schema.org/NewCondition',
7978
- seller: {
7979
- '@type': 'Organization',
7980
- name: this.companyInfo.name,
8151
+ sku: product.code,
8152
+ ...(product.supplierSku && { mpn: product.supplierSku }),
8153
+ ...(product.brand && {
8154
+ brand: {
8155
+ '@type': 'Brand',
8156
+ name: product.brand,
7981
8157
  },
7982
- url: productUrl,
7983
- },
8158
+ }),
8159
+ url: productUrl,
8160
+ offers: this.createOffer(product, productUrl),
7984
8161
  };
7985
8162
  }
7986
8163
  /**
@@ -8064,6 +8241,7 @@ class SchemaOrgFactory {
8064
8241
  // eslint-disable-next-line sonarjs/function-return-type
8065
8242
  generateForOrganization() {
8066
8243
  const postalAddress = this.createPostalAddress(this.companyInfo.address);
8244
+ const merchantReturnPolicy = this.createMerchantReturnPolicy();
8067
8245
  return {
8068
8246
  '@context': 'https://schema.org',
8069
8247
  '@type': 'OnlineStore',
@@ -8093,6 +8271,13 @@ class SchemaOrgFactory {
8093
8271
  address: warehouseAddress,
8094
8272
  })),
8095
8273
  }),
8274
+ ...(merchantReturnPolicy && {
8275
+ // Тип возмещения Google принимает только в политике организации, в предложениях его нет.
8276
+ hasMerchantReturnPolicy: {
8277
+ ...merchantReturnPolicy,
8278
+ refundType: 'https://schema.org/FullRefund',
8279
+ },
8280
+ }),
8096
8281
  };
8097
8282
  }
8098
8283
  /**
@@ -8228,6 +8413,22 @@ class SchemaOrgFactory {
8228
8413
  }
8229
8414
  return contactPoints;
8230
8415
  }
8416
+ /**
8417
+ * Формирует MerchantReturnPolicy по условиям возврата из данных о компании.
8418
+ */
8419
+ createMerchantReturnPolicy() {
8420
+ if (!this.companyInfo.returnPolicy) {
8421
+ return undefined;
8422
+ }
8423
+ return {
8424
+ '@type': 'MerchantReturnPolicy',
8425
+ applicableCountry: 'RU',
8426
+ returnPolicyCategory: 'https://schema.org/MerchantReturnFiniteReturnWindow',
8427
+ merchantReturnDays: this.companyInfo.returnPolicy.returnDays,
8428
+ returnMethod: 'https://schema.org/ReturnInStore',
8429
+ returnFees: 'https://schema.org/FreeReturn',
8430
+ };
8431
+ }
8231
8432
  /**
8232
8433
  * Удаляет HTML-разметку из текста.
8233
8434
  *
@@ -8321,6 +8522,30 @@ class SchemaOrgFactory {
8321
8522
  const path = categoryPath.replace(':id', id);
8322
8523
  return `${this.urls.siteUrl}${path}`;
8323
8524
  }
8525
+ /**
8526
+ * Создаёт Offer о продаже товара.
8527
+ *
8528
+ * @param product Данные о продукте.
8529
+ * @param productUrl Полный URL страницы товара.
8530
+ */
8531
+ createOffer(product, productUrl) {
8532
+ const priceValidUntil = this.normalizePriceValidUntil(product.discount?.expiredAt);
8533
+ const merchantReturnPolicy = this.createMerchantReturnPolicy();
8534
+ return {
8535
+ '@type': 'Offer',
8536
+ priceCurrency: 'RUB',
8537
+ ...(priceValidUntil && { priceValidUntil }),
8538
+ price: product.costRub,
8539
+ availability: this.getAvailability(product),
8540
+ itemCondition: 'https://schema.org/NewCondition',
8541
+ seller: {
8542
+ '@type': 'Organization',
8543
+ name: this.companyInfo.name,
8544
+ },
8545
+ url: productUrl,
8546
+ ...(merchantReturnPolicy && { hasMerchantReturnPolicy: merchantReturnPolicy }),
8547
+ };
8548
+ }
8324
8549
  /**
8325
8550
  * Создаёт элемент списка ItemList с кратким Product для страницы категории.
8326
8551
  *
@@ -8333,7 +8558,6 @@ class SchemaOrgFactory {
8333
8558
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
8334
8559
  const image = this.mediaImageTransformerPipe.transform(product?.getImagePreview?.() ?? product.image, true);
8335
8560
  const description = product.seo?.description ?? product.properties?.description;
8336
- const priceValidUntil = this.normalizePriceValidUntil(product.discount?.expiredAt);
8337
8561
  return {
8338
8562
  '@type': 'ListItem',
8339
8563
  position,
@@ -8343,19 +8567,7 @@ class SchemaOrgFactory {
8343
8567
  url: productUrl,
8344
8568
  ...(image && { image }),
8345
8569
  ...(description && { description: this.stripHtml(description) }),
8346
- offers: {
8347
- '@type': 'Offer',
8348
- priceCurrency: 'RUB',
8349
- ...(priceValidUntil && { priceValidUntil }),
8350
- price: product.costRub,
8351
- availability: this.getAvailability(product),
8352
- itemCondition: 'https://schema.org/NewCondition',
8353
- seller: {
8354
- '@type': 'Organization',
8355
- name: this.companyInfo.name,
8356
- },
8357
- url: productUrl,
8358
- },
8570
+ offers: this.createOffer(product, productUrl),
8359
8571
  },
8360
8572
  };
8361
8573
  }
@@ -9280,5 +9492,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
9280
9492
  * Generated bundle index. Do not edit.
9281
9493
  */
9282
9494
 
9283
- export { CATEGORY_PROVIDERS, EMPTY_CART, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, 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_CANONICAL_REDIRECT_ENABLED, SC_CATALOG_ITEM_PAGE_META, SC_CATALOG_ROOT_PAGE_META, SC_CATEGORY_INFO, SC_CATEGORY_STATE, 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_PAGE_QUERY_PARAM, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCTS_PAGINATION_LOADER, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_SSR_HTTP_TIMEOUT, SC_SSR_RESPONSE_CACHE, SC_SSR_RESPONSE_CACHE_SETTINGS, 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, ScCatalogRedirectService, ScCatalogService, ScCatalogableItem, ScCategory, ScClientType, ScCodedIdentity, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDateFormatInterceptor, ScDeletableNamedIdentity, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorRequestState, ScErrorsInterceptor, ScFavoriteService, ScFeedbackForms, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScHiddenCatalogableItem, ScIBreadcrumbItem, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScIdentity, ScImage, ScImageHelper, ScLoadingRequestState, ScLocationsService, ScMediaImageTransformerPipe, ScMimeTypes, ScNamedIdentity, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderBase, ScOrderDraft, ScOrderDraftShort, ScOrderDraftType, ScOrderDraftsService, ScOrderItem, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationPageQueryParamService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScPrimaryCatalogableItem, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScRedirectStatusEnum, ScReference, ScReferenceName, ScReferencesService, ScRequestStateStatusEnum, ScRequisitesService, ScRouteKeys, ScSearchService, ScSeoService, ScSocialType, ScSsrResponseCache, ScSsrResponseCacheBackend, ScSsrTimeoutInterceptor, ScSuccessRequestState, 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, mapRequestStateToDataOrNull, mapToRequestState, provideSsrResponseCache, runningOnTerminalFactory, scGetCurrentRoute, scGetPageQueryParamChanges, scOrderIsLoaded, scParsePageQueryParam, searchTermFactory };
9495
+ export { CATEGORY_PROVIDERS, EMPTY_CART, IS_BROWSER, IS_RUNNING_ON_TERMINAL, IS_SERVER, 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_CANONICAL_REDIRECT_ENABLED, SC_CATALOG_ITEM_PAGE_META, SC_CATALOG_ROOT_PAGE_META, SC_CATEGORY_INFO, SC_CATEGORY_STATE, 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_PAGE_QUERY_PARAM, SC_PATH_IMAGE_NOT_FOUND, SC_PRODUCTS_PAGINATION_LOADER, SC_PRODUCT_PAGINATION_DEFAULT_OPTIONS, SC_PRODUCT_PAGINATION_OPTIONS, SC_REFRESH_AUTH_TOKEN_STORAGE_KEY, SC_RELEASE, SC_SSR_HTTP_TIMEOUT, SC_SSR_RESPONSE_CACHE, SC_SSR_RESPONSE_CACHE_SETTINGS, 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, ScCatalogRedirectService, ScCatalogService, ScCatalogableItem, ScCategory, ScClientType, ScCodedIdentity, ScConfiguratorService, ScContactsService, ScContragentService, ScConvertInterceptor, ScConvertersService, ScDateFormatInterceptor, ScDeletableNamedIdentity, ScDeliveryAddressService, ScDeliveryCost, ScDeliveryType, ScDocumentInfoNode, ScDocumentInfoTypesEnum, ScErrorRequestState, ScErrorsInterceptor, ScFavoriteService, ScFeedbackForms, ScFeedbackService, ScFilesService, ScFrequentlyAskedQuestionsService, ScGuestInterceptor, ScHiddenCatalogableItem, ScIBreadcrumbItem, ScISuggestionType, ScIconTypesEnum, ScIdOrSlugGuard, ScIdOrSlugPipe, ScIdentity, ScImage, ScImageHelper, ScLoadingRequestState, ScLocationsService, ScMediaImageTransformerPipe, ScMimeTypes, ScNamedIdentity, ScNews, ScNewsService, ScNotificationActionTypes, ScNotificationLevelNames, ScNotificationsService, ScNumberHelper, ScOpfList, ScOptionsInterceptor, ScOrder, ScOrderBase, ScOrderDraft, ScOrderDraftShort, ScOrderDraftType, ScOrderDraftsService, ScOrderItem, ScOrderShort, ScOrderStateStatus, ScOrdersService, ScPaginationPageQueryParamService, ScPaginationService, ScPaymentStatus, ScPaymentType, ScPhoneService, ScPrimaryCatalogableItem, ScProduct, ScProductTileType, ScQuestionnaireService, ScQuestionnaireStatusEnum, ScReclamationService, ScReclamationStatus, ScRecommendationService, ScRedirectStatusEnum, ScReference, ScReferenceName, ScReferencesService, ScRequestStateStatusEnum, ScRequisitesService, ScRouteKeys, ScSearchService, ScSeoService, ScSocialType, ScSsrResponseCache, ScSsrResponseCacheBackend, ScSsrTimeoutInterceptor, ScSuccessRequestState, 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, mapRequestStateToDataOrNull, mapToRequestState, provideRubPrecision, provideSsrResponseCache, runningOnTerminalFactory, scGetCurrentRoute, scGetPageQueryParamChanges, scOrderIsLoaded, scParsePageQueryParam, searchTermFactory };
9284
9496
  //# sourceMappingURL=snabcentr-client-core.mjs.map