@snabcentr/client-core 4.19.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
 
@@ -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
  * Признак, что товар продаётся в рублях.
@@ -1887,25 +2097,25 @@ class ScOrderItem {
1887
2097
  * @inheritDoc
1888
2098
  */
1889
2099
  getCostPerItem() {
1890
- 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}` : '-';
1891
2101
  }
1892
2102
  /**
1893
2103
  * @inheritDoc
1894
2104
  */
1895
2105
  getCostInCurrencyDescPerItem() {
1896
- 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}` : '-';
1897
2107
  }
1898
2108
  /**
1899
2109
  * @inheritDoc
1900
2110
  */
1901
2111
  getCostInRubDescPerItem() {
1902
- return this.costOneRub > 0 ? `${this.costOneRub.toLocaleString()} ₽ / ${this.product.unit.name}` : '-';
2112
+ return this.costOneRub > 0 ? `${ScNumberHelper.formatMoney(this.costOneRub)} ₽ / ${this.product.unit.name}` : '-';
1903
2113
  }
1904
2114
  /**
1905
2115
  * @inheritDoc
1906
2116
  */
1907
2117
  getCostRubStr() {
1908
- return this.costRub > 0 ? `${this.costRub.toLocaleString()} ₽` : '-';
2118
+ return this.costRub > 0 ? `${ScNumberHelper.formatMoney(this.costRub)} ₽` : '-';
1909
2119
  }
1910
2120
  /**
1911
2121
  * @inheritDoc
@@ -6234,6 +6444,22 @@ var ScReclamationStatus;
6234
6444
  ScReclamationStatus[ScReclamationStatus["completed"] = 4] = "completed";
6235
6445
  })(ScReclamationStatus || (ScReclamationStatus = {}));
6236
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
+
6237
6463
  /**
6238
6464
  * Сервис для получения списков стран, регионов, городов.
6239
6465
  */
@@ -6700,8 +6926,8 @@ class ScDeliveryCost {
6700
6926
  constructor(deliveryCost, deliveryDate) {
6701
6927
  if (deliveryCost.freeShippingTerms?.minOrdersSum !== undefined && deliveryCost.freeShippingTerms.currentOrdersSum !== undefined) {
6702
6928
  this.freeShippingTerms = { minOrdersSum: deliveryCost.freeShippingTerms.minOrdersSum, currentOrdersSum: deliveryCost.freeShippingTerms.currentOrdersSum };
6703
- this.message = `Для оформления бесплатной доставки сумма заказов на ${deliveryDate} должна быть более ${this.freeShippingTerms.minOrdersSum.toLocaleString()} руб.<br>
6704
- Текущая сумма заказов составляет ${this.freeShippingTerms.currentOrdersSum.toLocaleString()} руб`;
6929
+ this.message = `Для оформления бесплатной доставки сумма заказов на ${deliveryDate} должна быть более ${ScNumberHelper.formatMoney(this.freeShippingTerms.minOrdersSum)} руб.<br>
6930
+ Текущая сумма заказов составляет ${ScNumberHelper.formatMoney(this.freeShippingTerms.currentOrdersSum)} руб`;
6705
6931
  }
6706
6932
  }
6707
6933
  }
@@ -6724,7 +6950,7 @@ class ScOrderBase {
6724
6950
  * @inheritDoc
6725
6951
  */
6726
6952
  getSumStr() {
6727
- return this.sum && this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6953
+ return this.sum && this.sum > 0 ? `${ScNumberHelper.formatMoney(this.sum)} ₽` : '-';
6728
6954
  }
6729
6955
  /**
6730
6956
  * @inheritDoc
@@ -6759,7 +6985,7 @@ class ScOrderDraft {
6759
6985
  * @inheritDoc
6760
6986
  */
6761
6987
  getSumStr() {
6762
- return this.sum > 0 ? `${this.sum.toLocaleString()} ₽` : '-';
6988
+ return this.sum > 0 ? `${ScNumberHelper.formatMoney(this.sum)} ₽` : '-';
6763
6989
  }
6764
6990
  /**
6765
6991
  * @inheritDoc
@@ -7163,7 +7389,7 @@ class ScOrderDraftsService {
7163
7389
  }
7164
7390
  const updatedDraft = new ScOrderDraft(currentDraft);
7165
7391
  updatedDraft.products = remainingProducts;
7166
- updatedDraft.sum = remainingProducts.reduce((sum, product) => sum + product.costRub, 0);
7392
+ updatedDraft.sum = ScNumberHelper.roundMoney(remainingProducts.reduce((sum, product) => sum + product.costRub, 0));
7167
7393
  cachedItem.setValue(updatedDraft);
7168
7394
  });
7169
7395
  }
@@ -7915,7 +8141,6 @@ class SchemaOrgFactory {
7915
8141
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
7916
8142
  const image = this.mediaImageTransformerPipe.transform(product?.getImagePreview?.() ?? product.image, true);
7917
8143
  const description = product.properties?.description;
7918
- const priceValidUntil = this.normalizePriceValidUntil(product.discount?.expiredAt);
7919
8144
  return {
7920
8145
  '@context': 'https://schema.org',
7921
8146
  '@type': 'Product',
@@ -7923,21 +8148,16 @@ class SchemaOrgFactory {
7923
8148
  name: product.name,
7924
8149
  ...(image && { image }),
7925
8150
  ...(description && { description: this.stripHtml(description) }),
7926
- mpn: product.code,
7927
- url: productUrl,
7928
- offers: {
7929
- '@type': 'Offer',
7930
- priceCurrency: 'RUB',
7931
- ...(priceValidUntil && { priceValidUntil }),
7932
- price: product.costRub,
7933
- availability: this.getAvailability(product),
7934
- itemCondition: 'https://schema.org/NewCondition',
7935
- seller: {
7936
- '@type': 'Organization',
7937
- 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,
7938
8157
  },
7939
- url: productUrl,
7940
- },
8158
+ }),
8159
+ url: productUrl,
8160
+ offers: this.createOffer(product, productUrl),
7941
8161
  };
7942
8162
  }
7943
8163
  /**
@@ -8021,6 +8241,7 @@ class SchemaOrgFactory {
8021
8241
  // eslint-disable-next-line sonarjs/function-return-type
8022
8242
  generateForOrganization() {
8023
8243
  const postalAddress = this.createPostalAddress(this.companyInfo.address);
8244
+ const merchantReturnPolicy = this.createMerchantReturnPolicy();
8024
8245
  return {
8025
8246
  '@context': 'https://schema.org',
8026
8247
  '@type': 'OnlineStore',
@@ -8050,6 +8271,13 @@ class SchemaOrgFactory {
8050
8271
  address: warehouseAddress,
8051
8272
  })),
8052
8273
  }),
8274
+ ...(merchantReturnPolicy && {
8275
+ // Тип возмещения Google принимает только в политике организации, в предложениях его нет.
8276
+ hasMerchantReturnPolicy: {
8277
+ ...merchantReturnPolicy,
8278
+ refundType: 'https://schema.org/FullRefund',
8279
+ },
8280
+ }),
8053
8281
  };
8054
8282
  }
8055
8283
  /**
@@ -8185,6 +8413,22 @@ class SchemaOrgFactory {
8185
8413
  }
8186
8414
  return contactPoints;
8187
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
+ }
8188
8432
  /**
8189
8433
  * Удаляет HTML-разметку из текста.
8190
8434
  *
@@ -8278,6 +8522,30 @@ class SchemaOrgFactory {
8278
8522
  const path = categoryPath.replace(':id', id);
8279
8523
  return `${this.urls.siteUrl}${path}`;
8280
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
+ }
8281
8549
  /**
8282
8550
  * Создаёт элемент списка ItemList с кратким Product для страницы категории.
8283
8551
  *
@@ -8290,7 +8558,6 @@ class SchemaOrgFactory {
8290
8558
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
8291
8559
  const image = this.mediaImageTransformerPipe.transform(product?.getImagePreview?.() ?? product.image, true);
8292
8560
  const description = product.seo?.description ?? product.properties?.description;
8293
- const priceValidUntil = this.normalizePriceValidUntil(product.discount?.expiredAt);
8294
8561
  return {
8295
8562
  '@type': 'ListItem',
8296
8563
  position,
@@ -8300,19 +8567,7 @@ class SchemaOrgFactory {
8300
8567
  url: productUrl,
8301
8568
  ...(image && { image }),
8302
8569
  ...(description && { description: this.stripHtml(description) }),
8303
- offers: {
8304
- '@type': 'Offer',
8305
- priceCurrency: 'RUB',
8306
- ...(priceValidUntil && { priceValidUntil }),
8307
- price: product.costRub,
8308
- availability: this.getAvailability(product),
8309
- itemCondition: 'https://schema.org/NewCondition',
8310
- seller: {
8311
- '@type': 'Organization',
8312
- name: this.companyInfo.name,
8313
- },
8314
- url: productUrl,
8315
- },
8570
+ offers: this.createOffer(product, productUrl),
8316
8571
  },
8317
8572
  };
8318
8573
  }
@@ -9237,5 +9492,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.16", ngImpo
9237
9492
  * Generated bundle index. Do not edit.
9238
9493
  */
9239
9494
 
9240
- 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 };
9241
9496
  //# sourceMappingURL=snabcentr-client-core.mjs.map