store-scrapper-js-common 1.0.224 → 1.0.225
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.
- package/dist/entities/index.d.ts +2 -2
- package/dist/entities/index.js.map +1 -1
- package/dist/entities/product.d.ts +7 -0
- package/dist/entities/product.js +4 -0
- package/dist/entities/product.js.map +1 -1
- package/dist/utils/product.utils.coupon.spec.d.ts +1 -0
- package/dist/utils/product.utils.coupon.spec.js +25 -0
- package/dist/utils/product.utils.coupon.spec.js.map +1 -0
- package/dist/utils/product.utils.js +2 -1
- package/dist/utils/product.utils.js.map +1 -1
- package/package.json +1 -1
- package/src/entities/index.ts +2 -2
- package/src/entities/product.ts +10 -0
- package/src/utils/product.utils.coupon.spec.ts +28 -0
- package/src/utils/product.utils.ts +2 -0
package/dist/entities/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Store, CountryEnum, PriorityEnum } from './store';
|
|
2
|
-
import { Product, UpdateReasonEnum, CurrencyEnum, ProductAttributes, ConditionalPrice } from './product';
|
|
2
|
+
import { Product, UpdateReasonEnum, CurrencyEnum, ProductAttributes, ConditionalPrice, ProductCoupon } from './product';
|
|
3
3
|
import { Price, MeasurementUnitEnum } from './price';
|
|
4
4
|
import { Category } from './category';
|
|
5
5
|
import { AbstractBase } from './abstract-base';
|
|
@@ -9,4 +9,4 @@ import { AlertConditions } from './alert-conditions';
|
|
|
9
9
|
import { PricesStats } from './prices-stats';
|
|
10
10
|
import { CategoryEntity } from './category-entity';
|
|
11
11
|
export declare const Entities: (typeof Keyword | typeof Price | typeof Product | typeof Store | typeof User)[];
|
|
12
|
-
export { Store, Product, Price, Category, CategoryEntity, AbstractBase, Keyword, CONDITION_FIELD_ENUM, CONDITION_SCOPE, CONDITION_ENUM, CATEGORY_ENUM, User, AlertConditions, CountryEnum, PriorityEnum, CurrencyEnum, UpdateReasonEnum, ConditionalPrice, ProductAttributes, MeasurementUnitEnum, PricesStats, };
|
|
12
|
+
export { Store, Product, Price, Category, CategoryEntity, AbstractBase, Keyword, CONDITION_FIELD_ENUM, CONDITION_SCOPE, CONDITION_ENUM, CATEGORY_ENUM, User, AlertConditions, CountryEnum, PriorityEnum, CurrencyEnum, UpdateReasonEnum, ConditionalPrice, ProductAttributes, MeasurementUnitEnum, PricesStats, ProductCoupon, };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"/","sources":["entities/index.ts"],"names":[],"mappings":";;;AAAA,mCAA2D;AAoBzD,sFApBO,aAAK,OAoBP;AACiD,4FArBxC,mBAAW,OAqBwC;AAAE,6FArBxC,oBAAY,OAqBwC;AApBjF,uCAEmB;AAiBV,wFAlBP,iBAAO,OAkBO;AAEA,iGApBL,0BAAgB,OAoBK;AAA9B,6FApB2B,sBAAY,OAoB3B;AAlBd,mCAAqD;AAgBnC,sFAhBT,aAAK,OAgBS;AAEgD,oGAlBvD,2BAAmB,OAkBuD;AAjB1F,yCAAsC;AAeb,yFAfhB,mBAAQ,OAegB;AAdjC,mDAA+C;AAcI,6FAd1C,4BAAY,OAc0C;AAb/D,uCAEmB;AAW8C,wFAZ/D,iBAAO,OAY+D;AACtD,8FAbP,uBAAa,OAaO;AAA7B,+FAbwB,wBAAc,OAaxB;AAD0D,qGAZhC,8BAAoB,OAYgC;AAAE,gGAZhC,yBAAe,OAYgC;AAV/G,iCAA8B;AAWG,qFAXxB,WAAI,OAWwB;AAVrC,yDAAqD;AAUd,gGAV9B,kCAAe,OAU8B;AATtD,iDAA6C;AAU+C,4FAVnF,0BAAW,OAUmF;AATvG,uDAAmD;AAOhB,+FAP1B,gCAAc,OAO0B;AALpC,QAAA,QAAQ,GAAG;IACtB,aAAK,EAAE,iBAAO,EAAE,aAAK,EAAE,iBAAO,EAAE,WAAI;CACrC,CAAC","sourcesContent":["import { Store, CountryEnum, PriorityEnum } from './store';\nimport {\n Product, UpdateReasonEnum, CurrencyEnum, ProductAttributes, ConditionalPrice,\n} from './product';\nimport { Price, MeasurementUnitEnum } from './price';\nimport { Category } from './category';\nimport { AbstractBase } from './abstract-base';\nimport {\n Keyword, CATEGORY_ENUM, CONDITION_ENUM, CONDITION_FIELD_ENUM, CONDITION_SCOPE,\n} from './keyword';\nimport { User } from './user';\nimport { AlertConditions } from './alert-conditions';\nimport { PricesStats } from './prices-stats';\nimport { CategoryEntity } from './category-entity';\n\nexport const Entities = [\n Store, Product, Price, Keyword, User,\n];\n\nexport {\n Store, Product, Price, Category, CategoryEntity, AbstractBase, Keyword, CONDITION_FIELD_ENUM, CONDITION_SCOPE,\n CONDITION_ENUM, CATEGORY_ENUM, User, AlertConditions, CountryEnum, PriorityEnum,\n CurrencyEnum, UpdateReasonEnum, ConditionalPrice, ProductAttributes, MeasurementUnitEnum, PricesStats,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"/","sources":["entities/index.ts"],"names":[],"mappings":";;;AAAA,mCAA2D;AAoBzD,sFApBO,aAAK,OAoBP;AACiD,4FArBxC,mBAAW,OAqBwC;AAAE,6FArBxC,oBAAY,OAqBwC;AApBjF,uCAEmB;AAiBV,wFAlBP,iBAAO,OAkBO;AAEA,iGApBL,0BAAgB,OAoBK;AAA9B,6FApB2B,sBAAY,OAoB3B;AAlBd,mCAAqD;AAgBnC,sFAhBT,aAAK,OAgBS;AAEgD,oGAlBvD,2BAAmB,OAkBuD;AAjB1F,yCAAsC;AAeb,yFAfhB,mBAAQ,OAegB;AAdjC,mDAA+C;AAcI,6FAd1C,4BAAY,OAc0C;AAb/D,uCAEmB;AAW8C,wFAZ/D,iBAAO,OAY+D;AACtD,8FAbP,uBAAa,OAaO;AAA7B,+FAbwB,wBAAc,OAaxB;AAD0D,qGAZhC,8BAAoB,OAYgC;AAAE,gGAZhC,yBAAe,OAYgC;AAV/G,iCAA8B;AAWG,qFAXxB,WAAI,OAWwB;AAVrC,yDAAqD;AAUd,gGAV9B,kCAAe,OAU8B;AATtD,iDAA6C;AAU+C,4FAVnF,0BAAW,OAUmF;AATvG,uDAAmD;AAOhB,+FAP1B,gCAAc,OAO0B;AALpC,QAAA,QAAQ,GAAG;IACtB,aAAK,EAAE,iBAAO,EAAE,aAAK,EAAE,iBAAO,EAAE,WAAI;CACrC,CAAC","sourcesContent":["import { Store, CountryEnum, PriorityEnum } from './store';\nimport {\n Product, UpdateReasonEnum, CurrencyEnum, ProductAttributes, ConditionalPrice, ProductCoupon,\n} from './product';\nimport { Price, MeasurementUnitEnum } from './price';\nimport { Category } from './category';\nimport { AbstractBase } from './abstract-base';\nimport {\n Keyword, CATEGORY_ENUM, CONDITION_ENUM, CONDITION_FIELD_ENUM, CONDITION_SCOPE,\n} from './keyword';\nimport { User } from './user';\nimport { AlertConditions } from './alert-conditions';\nimport { PricesStats } from './prices-stats';\nimport { CategoryEntity } from './category-entity';\n\nexport const Entities = [\n Store, Product, Price, Keyword, User,\n];\n\nexport {\n Store, Product, Price, Category, CategoryEntity, AbstractBase, Keyword, CONDITION_FIELD_ENUM, CONDITION_SCOPE,\n CONDITION_ENUM, CATEGORY_ENUM, User, AlertConditions, CountryEnum, PriorityEnum,\n CurrencyEnum, UpdateReasonEnum, ConditionalPrice, ProductAttributes, MeasurementUnitEnum, PricesStats, ProductCoupon,\n};\n"]}
|
|
@@ -59,6 +59,12 @@ export interface ConditionalPrice {
|
|
|
59
59
|
createdAt?: Date;
|
|
60
60
|
updatedAt?: Date;
|
|
61
61
|
}
|
|
62
|
+
export interface ProductCoupon {
|
|
63
|
+
code: string;
|
|
64
|
+
discountType?: 'percentage' | 'amount' | 'unknown';
|
|
65
|
+
discountValue?: number | null;
|
|
66
|
+
rawLabel?: string;
|
|
67
|
+
}
|
|
62
68
|
export declare class Product extends AbstractBase {
|
|
63
69
|
name: string;
|
|
64
70
|
displayName?: string;
|
|
@@ -93,6 +99,7 @@ export declare class Product extends AbstractBase {
|
|
|
93
99
|
userRank?: number;
|
|
94
100
|
description?: string;
|
|
95
101
|
attributes?: ProductAttributes;
|
|
102
|
+
coupon?: ProductCoupon;
|
|
96
103
|
stockHistory?: {
|
|
97
104
|
stock: number;
|
|
98
105
|
updatedAt: string;
|
package/dist/entities/product.js
CHANGED
|
@@ -186,6 +186,10 @@ __decorate([
|
|
|
186
186
|
(0, typeorm_1.Column)(),
|
|
187
187
|
__metadata("design:type", Object)
|
|
188
188
|
], Product.prototype, "attributes", void 0);
|
|
189
|
+
__decorate([
|
|
190
|
+
(0, typeorm_1.Column)(),
|
|
191
|
+
__metadata("design:type", Object)
|
|
192
|
+
], Product.prototype, "coupon", void 0);
|
|
189
193
|
__decorate([
|
|
190
194
|
(0, typeorm_1.Column)(),
|
|
191
195
|
__metadata("design:type", Array)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product.js","sourceRoot":"/","sources":["entities/product.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAGiB;AACjB,qDAA6C;AAC7C,mDAA+C;AAC/C,mCAAgC;AAChC,iDAA6C;AAE7C,0DAAsD;AAGtD,IAAY,YAaX;AAbD,WAAY,YAAY;IACpB,2BAAW,CAAA;IACX,mCAAmB,CAAA;IACnB,uCAAuB,CAAA;IACvB,yCAAyB,CAAA;IACzB,8CAA8B,CAAA;IAC9B,2BAAW,CAAA;IACX,2BAAW,CAAA;IACX,2BAAW,CAAA;IACX,2BAAW,CAAA;IACX,2BAAW,CAAA;IACX,2BAAW,CAAA;IACX,2BAAW,CAAA;AACf,CAAC,EAbW,YAAY,4BAAZ,YAAY,QAavB;AAED,IAAY,gBAyBX;AAzBD,WAAY,gBAAgB;IACxB,iCAAa,CAAA;IACb,2CAAuB,CAAA;IACvB,6CAAyB,CAAA;IACzB,yCAAqB,CAAA;IACrB,mEAA+C,CAAA;IAC/C,yCAAqB,CAAA;IACrB,+CAA2B,CAAA;IAC3B,2CAAuB,CAAA;IACvB,yCAAqB,CAAA;IACrB,6CAAyB,CAAA;IACzB,iDAA6B,CAAA;IAC7B,yCAAqB,CAAA;IACrB,6CAAyB,CAAA;IACzB,iDAA6B,CAAA;IAE7B,6DAAyC,CAAA;IACzC,qFAAiE,CAAA;IACjE,2DAAuC,CAAA;IACvC,iEAA6C,CAAA;IAC7C,6DAAyC,CAAA;IACzC,mEAA+C,CAAA;IAC/C,2DAAuC,CAAA;IACvC,+DAA2C,CAAA;IAC3C,mEAA+C,CAAA;AACnD,CAAC,EAzBW,gBAAgB,gCAAhB,gBAAgB,QAyB3B;
|
|
1
|
+
{"version":3,"file":"product.js","sourceRoot":"/","sources":["entities/product.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n Column,\n Entity, Index, Unique,\n} from 'typeorm';\nimport { IsNotEmpty } from 'class-validator';\nimport { AbstractBase } from './abstract-base';\nimport { Price } from './price';\nimport { PricesStats } from './prices-stats';\nimport { Keyword } from './keyword';\nimport { HttpRequest } from '../classes/http-request';\nimport { ImageTypeEnum } from '../enums/image-type.enum';\n\nexport enum CurrencyEnum {\n CLP = 'clp',\n CMR_PTS = 'cmr_pts',\n PARIS_PTS = 'paris_pts',\n RIPLEY_PTS = 'ripley_pts',\n GENERAL_POINTS = 'general_pts',\n BRL = 'brl',\n PEN = 'pen',\n ARS = 'ars',\n EUR = 'eur',\n USD = 'usd',\n MXN = 'mxn',\n COP = 'cop',\n}\n\nexport enum UpdateReasonEnum {\n TIME = 'time',\n NEW_PRICE = 'new_price',\n PRICE_DOWN = 'price_down',\n PRICE_UP = 'price_up',\n NEW_CONDITIONAL_PRICE = 'new_conditional_price',\n NEW_NAME = 'new_name',\n NEW_LISTING = 'new_listing',\n NEW_STOCK = 'new_stock',\n STOCK_UP = 'stock_up',\n STOCK_DOWN = 'stock_down',\n MISSING_DATA = 'missing_data',\n FIX_DATA = 'fix_data',\n RE_LISTING = 're_listing',\n OUT_OF_STOCK = 'out_of_stock',\n\n CHILDREN_NEW_PRICE = 'children_new_price',\n CHILDREN_NEW_CONDITIONAL_PRICE = 'children_conditional_new_price',\n CHILDREN_NEW_NAME = 'children_new_name',\n CHILDREN_NEW_LISTING = 'children_new_listing',\n CHILDREN_NEW_STOCK = 'children_new_stock',\n CHILDREN_MISSING_DATA = 'children_missing_data',\n CHILDREN_FIX_DATA = 'children_fix_data',\n CHILDREN_RE_LISTING = 'children_re_listing',\n CHILDREN_OUT_OF_STOCK = 'children_out_of_stock'\n}\n\nexport interface ProductAttributes {\n stock?: number;\n\n // TODO: Add enum\n color?: string;\n\n // TODO: Add enum\n size?: string;\n\n // currently used, should be replaced by productTypes ( str[] )\n productType?: string;\n\n // to be implemented with inferred data\n productTypes?: string[];\n\n // to be implemented with inferred data\n genders?: string[];\n\n [key: string]: any;\n}\n\nexport interface ConditionalPrice {\n minAmount?: number;\n price?:number;\n cardRequired?: boolean;\n createdAt?: Date;\n updatedAt?: Date;\n}\n\nexport interface ProductCoupon {\n code: string;\n discountType?: 'percentage' | 'amount' | 'unknown';\n discountValue?: number | null;\n rawLabel?: string;\n}\n\n@Entity({ name: 'products' })\n@Unique('store_ref_sku', ['storeRef', 'sku'])\nexport class Product extends AbstractBase {\n @Column()\n name: string;\n\n @Column()\n displayName?: string;\n\n @Column()\n brandName?: string;\n\n @Column()\n normalizedBrandName?: string;\n\n @Column()\n modelName?: string;\n\n @Column()\n @IsNotEmpty()\n @Index()\n sku: string;\n\n @Column()\n internalId?: string;\n\n @Column()\n ean?: string;\n\n @Column()\n @IsNotEmpty()\n url: string;\n\n @Column()\n @IsNotEmpty()\n @Index()\n storeRef: string;\n\n @Column()\n storeName?: string;\n\n @Column()\n branchStoreName?: string;\n\n @Column()\n sellerName?: string;\n\n @Column()\n normalizedSellerName?: string;\n\n @Column()\n @IsNotEmpty()\n price?: Price;\n\n @Column()\n conditionalPrice?: ConditionalPrice;\n\n @Column()\n conditionalPriceHistory?: ConditionalPrice[];\n\n @Column()\n previousPrice?: Price;\n\n @Column()\n bestPrice?: Price;\n\n @Column()\n priceStats?: PricesStats;\n\n @Column()\n priceHistory?: Price[];\n\n @Column()\n rank?: number;\n\n @Column()\n image?: string;\n\n @Column()\n images?: { type: ImageTypeEnum, url: string }[]\n\n @Column()\n category?: string;\n\n @Column()\n categoryPath?: string;\n\n @Column()\n page?: number;\n\n @Column()\n userRank?: number;\n\n @Column()\n description?: string;\n\n @Column()\n attributes?: ProductAttributes;\n\n @Column()\n coupon?: ProductCoupon;\n\n @Column()\n stockHistory?: {\n stock: number,\n updatedAt: string,\n }[];\n\n @Column()\n homeDeliveryShipping?: boolean;\n\n @Column()\n pickUpFromStoreShipping?: boolean;\n\n @Column()\n fastDelivery?: boolean;\n\n @Column()\n enabled?: boolean;\n\n @Column()\n enabledHistory?: {enabled: boolean, updatedAt?:Date, createdAt?: Date}[];\n\n @Column()\n sourceUrl?: string;\n\n @Column()\n request? : HttpRequest;\n\n @Column()\n @Index()\n updatedAt?: Date;\n\n @Column()\n @Index()\n categoryKeywordNames?: string[];\n\n @Column()\n categoryKeywords?: Keyword[];\n\n // Categories using ext. service such as openai\n @Index()\n @Column()\n inferredCategories?: string[];\n\n // Can be used for facets.\n @Column()\n inferredCategoriesLvl?: {lvl0?: string[], lvl1?: string[], lvl2?: string[], lvl3?: string[], lvl4?: string[], lvl5?: string[]};\n\n // Inferred attributes such as product types\n @Column()\n inferredAttributes?: ProductAttributes;\n\n @Column()\n @Index()\n processedPricesAt?: Date;\n\n @Column()\n isMarketplace?: boolean;\n\n @Column()\n addToCartLink?: string;\n\n @Column()\n currency?: CurrencyEnum;\n\n @Column()\n updateReason?: UpdateReasonEnum[];\n\n @Column()\n nameHistory?: {\n name: string,\n updatedAt: string,\n }[];\n\n @Column()\n availableLocations?: string[];\n\n @Column()\n refurbished?: boolean;\n\n @Column()\n parentProductIdRef?: string;\n\n @Column()\n parentProductSkuRef?: string;\n\n @Column()\n children?: Product[]\n\n @Column()\n extractedAt?: Date;\n\n // should set this when price is a validated 0 ex Number(null) === 0\n @Column()\n isFree?: boolean;\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const product_1 = require("../entities/product");
|
|
4
|
+
const product_utils_1 = require("./product.utils");
|
|
5
|
+
function makeProduct(overrides = {}) {
|
|
6
|
+
const price = { offerPrice: 50000, normalPrice: 80000 };
|
|
7
|
+
const base = {
|
|
8
|
+
name: 'Taladro', storeRef: '5f27437dabd4b000086cd698', sku: 'SKU1',
|
|
9
|
+
url: 'https://x', price,
|
|
10
|
+
};
|
|
11
|
+
return Object.assign(new product_1.Product(), base, overrides);
|
|
12
|
+
}
|
|
13
|
+
describe('parseProductDtoToTypesenseDocument — coupon fields', () => {
|
|
14
|
+
it('emits couponCode and hasCoupon=true when the product has a coupon', () => {
|
|
15
|
+
const doc = (0, product_utils_1.parseProductDtoToTypesenseDocument)(makeProduct({ coupon: { code: 'NOTHING10', discountType: 'percentage', discountValue: 10, rawLabel: 'Cupón 10%: NOTHING10' } }));
|
|
16
|
+
expect(doc.couponCode).toBe('NOTHING10');
|
|
17
|
+
expect(doc.hasCoupon).toBe(true);
|
|
18
|
+
});
|
|
19
|
+
it('emits empty couponCode and hasCoupon=false when there is no coupon', () => {
|
|
20
|
+
const doc = (0, product_utils_1.parseProductDtoToTypesenseDocument)(makeProduct());
|
|
21
|
+
expect(doc.couponCode).toBe('');
|
|
22
|
+
expect(doc.hasCoupon).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=product.utils.coupon.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"product.utils.coupon.spec.js","sourceRoot":"/","sources":["utils/product.utils.coupon.spec.ts"],"names":[],"mappings":";;AAAA,iDAA8C;AAE9C,mDAAqE;AAErE,SAAS,WAAW,CAAC,YAA8B,EAAE;IACnD,MAAM,KAAK,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW,EAAE,KAAK,EAAW,CAAC;IACjE,MAAM,IAAI,GAAqB;QAC7B,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,0BAA0B,EAAE,GAAG,EAAE,MAAM;QAClE,GAAG,EAAE,WAAW,EAAE,KAAK;KACxB,CAAC;IACF,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,iBAAO,EAAE,EAAE,IAAI,EAAE,SAAS,CAAY,CAAC;AAClE,CAAC;AAED,QAAQ,CAAC,oDAAoD,EAAE,GAAG,EAAE;IAClE,EAAE,CAAC,mEAAmE,EAAE,GAAG,EAAE;QAC3E,MAAM,GAAG,GAAG,IAAA,kDAAkC,EAC5C,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,EAAE,EAAE,QAAQ,EAAE,sBAAsB,EAAE,EAAE,CAAC,CAChI,CAAC;QACF,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,GAAG,GAAG,IAAA,kDAAkC,EAAC,WAAW,EAAE,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAChC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["import { Product } from '../entities/product';\nimport { Price } from '../entities/price';\nimport { parseProductDtoToTypesenseDocument } from './product.utils';\n\nfunction makeProduct(overrides: Partial<Product> = {}): Product {\n const price = { offerPrice: 50000, normalPrice: 80000 } as Price;\n const base: Partial<Product> = {\n name: 'Taladro', storeRef: '5f27437dabd4b000086cd698', sku: 'SKU1',\n url: 'https://x', price,\n };\n return Object.assign(new Product(), base, overrides) as Product;\n}\n\ndescribe('parseProductDtoToTypesenseDocument — coupon fields', () => {\n it('emits couponCode and hasCoupon=true when the product has a coupon', () => {\n const doc = parseProductDtoToTypesenseDocument(\n makeProduct({ coupon: { code: 'NOTHING10', discountType: 'percentage', discountValue: 10, rawLabel: 'Cupón 10%: NOTHING10' } }),\n );\n expect(doc.couponCode).toBe('NOTHING10');\n expect(doc.hasCoupon).toBe(true);\n });\n\n it('emits empty couponCode and hasCoupon=false when there is no coupon', () => {\n const doc = parseProductDtoToTypesenseDocument(makeProduct());\n expect(doc.couponCode).toBe('');\n expect(doc.hasCoupon).toBe(false);\n });\n});\n"]}
|
|
@@ -21,6 +21,7 @@ exports.getStoreName = getStoreName;
|
|
|
21
21
|
const hasUpdateReason = (enums, search) => (0, array_utils_1.hasElementInArray)(enums, search);
|
|
22
22
|
exports.hasUpdateReason = hasUpdateReason;
|
|
23
23
|
const parseProductDtoToTypesenseDocument = (product) => {
|
|
24
|
+
var _a, _b, _c;
|
|
24
25
|
if (!product) {
|
|
25
26
|
return null;
|
|
26
27
|
}
|
|
@@ -96,7 +97,7 @@ const parseProductDtoToTypesenseDocument = (product) => {
|
|
|
96
97
|
}
|
|
97
98
|
const updatedAtDate = new Date(ref.updatedAt || ref.extractedAt || Date.now());
|
|
98
99
|
const bucketData = (0, time_utils_1.getBucketTime)(customBucketTimeDate || updatedAtDate);
|
|
99
|
-
return Object.assign(Object.assign({ id: ref._id }, priceStats), { storeRef: ref.storeRef, storeName: ref.storeName || 'no store name', isMarketplace: ref.isMarketplace === true, name: ref.name || 'no name', sku: ref.sku, ean: ref.ean, url: ref.url, image: ref.image, brandName: ref.brandName ? (0, string_utils_1.normalizeString)(ref.brandName) : undefined, sellerName: ref.sellerName, category: ref.category, categoryPath: ref.categoryPath, price: ref.price, bestPrice: ref.bestPrice, conditionalPrice: ref.conditionalPrice, priceHistory: ref.priceHistory, currency: ref.currency || entities_1.CurrencyEnum.CLP, enabled: ref.enabled === true || typeof ref.enabled === 'undefined' || ref.enabled === null, categoryKeywordNames: foundCategories, inferredCategories: inferredCategories, updateReasons: (ref.updateReason || []).filter((e) => e), updatedAt: updatedAtDate.getTime(), priceUpdatedAt: priceUpdatedAt, updatedAtUnixTime: Math.floor(updatedAtDate.getTime() / 1000), priceUpdatedAtUnixTime: Math.floor(priceUpdatedAt / 1000), bucketTime: bucketData && bucketData.bucketTime ? bucketData.bucketTime : undefined, bucketDate: bucketData && bucketData.bucketDate ? bucketData.bucketDate : undefined });
|
|
100
|
+
return Object.assign(Object.assign({ id: ref._id }, priceStats), { storeRef: ref.storeRef, storeName: ref.storeName || 'no store name', isMarketplace: ref.isMarketplace === true, name: ref.name || 'no name', sku: ref.sku, ean: ref.ean, url: ref.url, image: ref.image, brandName: ref.brandName ? (0, string_utils_1.normalizeString)(ref.brandName) : undefined, sellerName: ref.sellerName, couponCode: (_b = (_a = ref.coupon) === null || _a === void 0 ? void 0 : _a.code) !== null && _b !== void 0 ? _b : '', hasCoupon: !!((_c = ref.coupon) === null || _c === void 0 ? void 0 : _c.code), category: ref.category, categoryPath: ref.categoryPath, price: ref.price, bestPrice: ref.bestPrice, conditionalPrice: ref.conditionalPrice, priceHistory: ref.priceHistory, currency: ref.currency || entities_1.CurrencyEnum.CLP, enabled: ref.enabled === true || typeof ref.enabled === 'undefined' || ref.enabled === null, categoryKeywordNames: foundCategories, inferredCategories: inferredCategories, updateReasons: (ref.updateReason || []).filter((e) => e), updatedAt: updatedAtDate.getTime(), priceUpdatedAt: priceUpdatedAt, updatedAtUnixTime: Math.floor(updatedAtDate.getTime() / 1000), priceUpdatedAtUnixTime: Math.floor(priceUpdatedAt / 1000), bucketTime: bucketData && bucketData.bucketTime ? bucketData.bucketTime : undefined, bucketDate: bucketData && bucketData.bucketDate ? bucketData.bucketDate : undefined });
|
|
100
101
|
};
|
|
101
102
|
exports.parseProductDtoToTypesenseDocument = parseProductDtoToTypesenseDocument;
|
|
102
103
|
//# sourceMappingURL=product.utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product.utils.js","sourceRoot":"/","sources":["utils/product.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import {hasElementInArray, isArrayEmpty} from './array-utils';\nimport {CATEGORY_ENUM, CurrencyEnum, Product, Store, UpdateReasonEnum} from '../entities';\nimport {ObjectLiteral} from \"../classes\";\nimport {getMinPrice} from \"./price-utils\";\nimport {getCategoryFacetLabel} from \"./facet-categories-map\";\nimport {getBucketTime} from \"./time-utils\";\nimport {getStringsAsStrArr, normalizeString} from \"./string-utils\";\n\nexport const getStoreName = (product: Product, stores: Store[]): string => {\n if ((!stores || stores.length === 0) && product) {\n return product.storeName;\n }\n\n // eslint-disable-next-line no-underscore-dangle\n const store = stores.find((storeElement) => storeElement._id.toString() === product.storeRef);\n if (store) {\n return store.displayName || store.name;\n }\n\n return null;\n};\n\nexport const hasUpdateReason = (enums: UpdateReasonEnum[], search: UpdateReasonEnum[]): boolean => hasElementInArray<UpdateReasonEnum>(enums, search);\n\nexport const parseProductDtoToTypesenseDocument = (product: Product): ObjectLiteral => {\n if (!product) {\n return null;\n }\n\n const ref: Product = JSON.parse(JSON.stringify(product));\n\n let priceStats = null;\n\n let priceUpdatedAt = new Date(\n ref.price.updatedAt || ref.price.createdAt || ref.extractedAt || ref.updatedAt,\n ).getTime();\n\n if (ref.priceStats) {\n // TODO: Search how to look for specific pivot prices in Typesense search\n // Slice 3 pivot prices\n const pivotPrices = (ref.priceStats.pivotPrices || []).slice(0, 3);\n\n // Add max discount single field\n // Prioritize Current Offer and Conditional Price\n // If neither of those exists then use previous price\n let maxDiscount = 0;\n if (ref.priceStats.currentMinPriceMaxPriceDiffPct > 0) {\n maxDiscount = ref.priceStats.currentMinPriceMaxPriceDiffPct;\n }\n\n // TODO: Was updated to use currentMaxPrice, update or create a new field\n if (ref.priceStats.conditionalPriceMinPriceDiffPct) {\n if (\n maxDiscount === 0 ||\n ref.priceStats.conditionalPriceMinPriceDiffPct > ref.priceStats.currentMinPriceMaxPriceDiffPct\n ) {\n maxDiscount = ref.priceStats.conditionalPriceMinPriceDiffPct;\n\n // don't use conditional price createdAt as it is not persisted with dates on products svc\n // const useDate = ref.conditionalPrice && ref.conditionalPrice.createdAt ? ref.conditionalPrice.createdAt : ref.extractedAt;\n // if (useDate) {\n // priceUpdatedAt = new Date(useDate).getTime();\n // }\n }\n }\n\n if (maxDiscount === 0 && ref.priceStats.currentPricePrevPriceDiffPct > 0) {\n let hasFakePrevPrice = false;\n\n // Pedidos Ya CL set to only use current price\n if (product.storeRef === '634b4c2ebf4c49e4b3672aba') {\n hasFakePrevPrice = true;\n }\n\n if (!hasFakePrevPrice && (!product.currency || product.currency === CurrencyEnum.CLP)) {\n const minPrevPrice = getMinPrice(ref.previousPrice);\n const minPrevPriceStr = minPrevPrice.toString();\n if (minPrevPrice > 0) {\n if (product.isMarketplace && minPrevPriceStr.endsWith('000')) {\n hasFakePrevPrice = true;\n }\n\n if (minPrevPrice === 9999999 || minPrevPrice === 10000000) {\n hasFakePrevPrice = true;\n }\n } else {\n hasFakePrevPrice = true;\n }\n }\n\n if (!hasFakePrevPrice) {\n maxDiscount = ref.priceStats.currentPricePrevPriceDiffPct;\n }\n }\n\n priceStats = {\n priceStats_pricesCount: ref.priceStats.pricesCount,\n priceStats_avgMinPrice: ref.priceStats.avgMinPrice,\n priceStats_currentMinPrice: ref.priceStats.currentMinPrice,\n priceStats_currentMaxPrice: ref.priceStats.currentMaxPrice,\n priceStats_currentPriceBestPriceDiffPct: ref.priceStats.currentPriceBestPriceDiffPct,\n priceStats_currentPricePrevPriceDiffPct: ref.priceStats.currentPricePrevPriceDiffPct,\n priceStats_currentMinPriceMaxPriceDiffPct: ref.priceStats.currentMinPriceMaxPriceDiffPct,\n priceStats_conditionalPriceMinPriceDiffPct: ref.priceStats.conditionalPriceMinPriceDiffPct || 0,\n priceStats_currentPriceAvgMinPriceDiffPct: ref.priceStats.currentPriceAvgMinPriceDiffPct,\n priceStats_maxDiscountPct: maxDiscount,\n priceStats_pivotPrices: pivotPrices,\n };\n }\n\n // If it doesn't have a price down or relisted or new listing then use current time - 30m to show to all users in web\n let customBucketTimeDate: Date | null = null;\n if (\n !hasUpdateReason(\n [UpdateReasonEnum.PRICE_DOWN, UpdateReasonEnum.RE_LISTING, UpdateReasonEnum.NEW_LISTING],\n product.updateReason,\n )\n ) {\n customBucketTimeDate = new Date(Date.now() - 1000 * 60 * 30);\n }\n\n // TODO: Append inferred categories to ref.categoryKeywordNames\n // TODO: Only append categories found in categoriesEnEsMap\n let foundCategories: string[] = [...(ref.categoryKeywordNames || [])];\n if (!isArrayEmpty(ref.inferredCategories)) {\n ref.inferredCategories.forEach((inferredCategory) => {\n if (getCategoryFacetLabel({ key: inferredCategory })) {\n foundCategories.push(inferredCategory);\n }\n });\n\n // remove CATEGORY_NOT_FOUND\n // as it found inferred categories\n foundCategories = foundCategories.filter((category) => category !== CATEGORY_ENUM.CATEGORY_NOT_FOUND);\n }\n\n let inferredCategories: string[] = [];\n if (!isArrayEmpty(ref.inferredCategories)) {\n inferredCategories = getStringsAsStrArr(ref.inferredCategories);\n }\n\n const updatedAtDate = new Date(ref.updatedAt || ref.extractedAt || Date.now());\n const bucketData = getBucketTime(customBucketTimeDate || updatedAtDate);\n\n return <ObjectLiteral>{\n id: ref._id,\n ...priceStats,\n storeRef: ref.storeRef,\n storeName: ref.storeName || 'no store name',\n isMarketplace: ref.isMarketplace === true,\n name: ref.name || 'no name',\n sku: ref.sku,\n ean: ref.ean,\n url: ref.url,\n image: ref.image,\n brandName: ref.brandName ? normalizeString(ref.brandName) : undefined,\n sellerName: ref.sellerName,\n // priceStats: priceStats,\n category: ref.category,\n categoryPath: ref.categoryPath,\n price: ref.price,\n bestPrice: ref.bestPrice,\n conditionalPrice: ref.conditionalPrice,\n priceHistory: ref.priceHistory,\n currency: ref.currency || CurrencyEnum.CLP,\n enabled: ref.enabled === true || typeof ref.enabled === 'undefined' || ref.enabled === null,\n categoryKeywordNames: foundCategories, // ref.categoryKeywordNames,\n inferredCategories: inferredCategories,\n updateReasons: (ref.updateReason || []).filter((e) => e),\n updatedAt: updatedAtDate.getTime(),\n priceUpdatedAt: priceUpdatedAt,\n updatedAtUnixTime: Math.floor(updatedAtDate.getTime() / 1000),\n priceUpdatedAtUnixTime: Math.floor(priceUpdatedAt / 1000),\n bucketTime: bucketData && bucketData.bucketTime ? bucketData.bucketTime : undefined,\n bucketDate: bucketData && bucketData.bucketDate ? bucketData.bucketDate : undefined,\n };\n};\n"]}
|
|
1
|
+
{"version":3,"file":"product.utils.js","sourceRoot":"/","sources":["utils/product.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import {hasElementInArray, isArrayEmpty} from './array-utils';\nimport {CATEGORY_ENUM, CurrencyEnum, Product, Store, UpdateReasonEnum} from '../entities';\nimport {ObjectLiteral} from \"../classes\";\nimport {getMinPrice} from \"./price-utils\";\nimport {getCategoryFacetLabel} from \"./facet-categories-map\";\nimport {getBucketTime} from \"./time-utils\";\nimport {getStringsAsStrArr, normalizeString} from \"./string-utils\";\n\nexport const getStoreName = (product: Product, stores: Store[]): string => {\n if ((!stores || stores.length === 0) && product) {\n return product.storeName;\n }\n\n // eslint-disable-next-line no-underscore-dangle\n const store = stores.find((storeElement) => storeElement._id.toString() === product.storeRef);\n if (store) {\n return store.displayName || store.name;\n }\n\n return null;\n};\n\nexport const hasUpdateReason = (enums: UpdateReasonEnum[], search: UpdateReasonEnum[]): boolean => hasElementInArray<UpdateReasonEnum>(enums, search);\n\nexport const parseProductDtoToTypesenseDocument = (product: Product): ObjectLiteral => {\n if (!product) {\n return null;\n }\n\n const ref: Product = JSON.parse(JSON.stringify(product));\n\n let priceStats = null;\n\n let priceUpdatedAt = new Date(\n ref.price.updatedAt || ref.price.createdAt || ref.extractedAt || ref.updatedAt,\n ).getTime();\n\n if (ref.priceStats) {\n // TODO: Search how to look for specific pivot prices in Typesense search\n // Slice 3 pivot prices\n const pivotPrices = (ref.priceStats.pivotPrices || []).slice(0, 3);\n\n // Add max discount single field\n // Prioritize Current Offer and Conditional Price\n // If neither of those exists then use previous price\n let maxDiscount = 0;\n if (ref.priceStats.currentMinPriceMaxPriceDiffPct > 0) {\n maxDiscount = ref.priceStats.currentMinPriceMaxPriceDiffPct;\n }\n\n // TODO: Was updated to use currentMaxPrice, update or create a new field\n if (ref.priceStats.conditionalPriceMinPriceDiffPct) {\n if (\n maxDiscount === 0 ||\n ref.priceStats.conditionalPriceMinPriceDiffPct > ref.priceStats.currentMinPriceMaxPriceDiffPct\n ) {\n maxDiscount = ref.priceStats.conditionalPriceMinPriceDiffPct;\n\n // don't use conditional price createdAt as it is not persisted with dates on products svc\n // const useDate = ref.conditionalPrice && ref.conditionalPrice.createdAt ? ref.conditionalPrice.createdAt : ref.extractedAt;\n // if (useDate) {\n // priceUpdatedAt = new Date(useDate).getTime();\n // }\n }\n }\n\n if (maxDiscount === 0 && ref.priceStats.currentPricePrevPriceDiffPct > 0) {\n let hasFakePrevPrice = false;\n\n // Pedidos Ya CL set to only use current price\n if (product.storeRef === '634b4c2ebf4c49e4b3672aba') {\n hasFakePrevPrice = true;\n }\n\n if (!hasFakePrevPrice && (!product.currency || product.currency === CurrencyEnum.CLP)) {\n const minPrevPrice = getMinPrice(ref.previousPrice);\n const minPrevPriceStr = minPrevPrice.toString();\n if (minPrevPrice > 0) {\n if (product.isMarketplace && minPrevPriceStr.endsWith('000')) {\n hasFakePrevPrice = true;\n }\n\n if (minPrevPrice === 9999999 || minPrevPrice === 10000000) {\n hasFakePrevPrice = true;\n }\n } else {\n hasFakePrevPrice = true;\n }\n }\n\n if (!hasFakePrevPrice) {\n maxDiscount = ref.priceStats.currentPricePrevPriceDiffPct;\n }\n }\n\n priceStats = {\n priceStats_pricesCount: ref.priceStats.pricesCount,\n priceStats_avgMinPrice: ref.priceStats.avgMinPrice,\n priceStats_currentMinPrice: ref.priceStats.currentMinPrice,\n priceStats_currentMaxPrice: ref.priceStats.currentMaxPrice,\n priceStats_currentPriceBestPriceDiffPct: ref.priceStats.currentPriceBestPriceDiffPct,\n priceStats_currentPricePrevPriceDiffPct: ref.priceStats.currentPricePrevPriceDiffPct,\n priceStats_currentMinPriceMaxPriceDiffPct: ref.priceStats.currentMinPriceMaxPriceDiffPct,\n priceStats_conditionalPriceMinPriceDiffPct: ref.priceStats.conditionalPriceMinPriceDiffPct || 0,\n priceStats_currentPriceAvgMinPriceDiffPct: ref.priceStats.currentPriceAvgMinPriceDiffPct,\n priceStats_maxDiscountPct: maxDiscount,\n priceStats_pivotPrices: pivotPrices,\n };\n }\n\n // If it doesn't have a price down or relisted or new listing then use current time - 30m to show to all users in web\n let customBucketTimeDate: Date | null = null;\n if (\n !hasUpdateReason(\n [UpdateReasonEnum.PRICE_DOWN, UpdateReasonEnum.RE_LISTING, UpdateReasonEnum.NEW_LISTING],\n product.updateReason,\n )\n ) {\n customBucketTimeDate = new Date(Date.now() - 1000 * 60 * 30);\n }\n\n // TODO: Append inferred categories to ref.categoryKeywordNames\n // TODO: Only append categories found in categoriesEnEsMap\n let foundCategories: string[] = [...(ref.categoryKeywordNames || [])];\n if (!isArrayEmpty(ref.inferredCategories)) {\n ref.inferredCategories.forEach((inferredCategory) => {\n if (getCategoryFacetLabel({ key: inferredCategory })) {\n foundCategories.push(inferredCategory);\n }\n });\n\n // remove CATEGORY_NOT_FOUND\n // as it found inferred categories\n foundCategories = foundCategories.filter((category) => category !== CATEGORY_ENUM.CATEGORY_NOT_FOUND);\n }\n\n let inferredCategories: string[] = [];\n if (!isArrayEmpty(ref.inferredCategories)) {\n inferredCategories = getStringsAsStrArr(ref.inferredCategories);\n }\n\n const updatedAtDate = new Date(ref.updatedAt || ref.extractedAt || Date.now());\n const bucketData = getBucketTime(customBucketTimeDate || updatedAtDate);\n\n return <ObjectLiteral>{\n id: ref._id,\n ...priceStats,\n storeRef: ref.storeRef,\n storeName: ref.storeName || 'no store name',\n isMarketplace: ref.isMarketplace === true,\n name: ref.name || 'no name',\n sku: ref.sku,\n ean: ref.ean,\n url: ref.url,\n image: ref.image,\n brandName: ref.brandName ? normalizeString(ref.brandName) : undefined,\n sellerName: ref.sellerName,\n couponCode: ref.coupon?.code ?? '',\n hasCoupon: !!ref.coupon?.code,\n // priceStats: priceStats,\n category: ref.category,\n categoryPath: ref.categoryPath,\n price: ref.price,\n bestPrice: ref.bestPrice,\n conditionalPrice: ref.conditionalPrice,\n priceHistory: ref.priceHistory,\n currency: ref.currency || CurrencyEnum.CLP,\n enabled: ref.enabled === true || typeof ref.enabled === 'undefined' || ref.enabled === null,\n categoryKeywordNames: foundCategories, // ref.categoryKeywordNames,\n inferredCategories: inferredCategories,\n updateReasons: (ref.updateReason || []).filter((e) => e),\n updatedAt: updatedAtDate.getTime(),\n priceUpdatedAt: priceUpdatedAt,\n updatedAtUnixTime: Math.floor(updatedAtDate.getTime() / 1000),\n priceUpdatedAtUnixTime: Math.floor(priceUpdatedAt / 1000),\n bucketTime: bucketData && bucketData.bucketTime ? bucketData.bucketTime : undefined,\n bucketDate: bucketData && bucketData.bucketDate ? bucketData.bucketDate : undefined,\n };\n};\n"]}
|
package/package.json
CHANGED
package/src/entities/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Store, CountryEnum, PriorityEnum } from './store';
|
|
2
2
|
import {
|
|
3
|
-
Product, UpdateReasonEnum, CurrencyEnum, ProductAttributes, ConditionalPrice,
|
|
3
|
+
Product, UpdateReasonEnum, CurrencyEnum, ProductAttributes, ConditionalPrice, ProductCoupon,
|
|
4
4
|
} from './product';
|
|
5
5
|
import { Price, MeasurementUnitEnum } from './price';
|
|
6
6
|
import { Category } from './category';
|
|
@@ -20,5 +20,5 @@ export const Entities = [
|
|
|
20
20
|
export {
|
|
21
21
|
Store, Product, Price, Category, CategoryEntity, AbstractBase, Keyword, CONDITION_FIELD_ENUM, CONDITION_SCOPE,
|
|
22
22
|
CONDITION_ENUM, CATEGORY_ENUM, User, AlertConditions, CountryEnum, PriorityEnum,
|
|
23
|
-
CurrencyEnum, UpdateReasonEnum, ConditionalPrice, ProductAttributes, MeasurementUnitEnum, PricesStats,
|
|
23
|
+
CurrencyEnum, UpdateReasonEnum, ConditionalPrice, ProductAttributes, MeasurementUnitEnum, PricesStats, ProductCoupon,
|
|
24
24
|
};
|
package/src/entities/product.ts
CHANGED
|
@@ -81,6 +81,13 @@ export interface ConditionalPrice {
|
|
|
81
81
|
updatedAt?: Date;
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
export interface ProductCoupon {
|
|
85
|
+
code: string;
|
|
86
|
+
discountType?: 'percentage' | 'amount' | 'unknown';
|
|
87
|
+
discountValue?: number | null;
|
|
88
|
+
rawLabel?: string;
|
|
89
|
+
}
|
|
90
|
+
|
|
84
91
|
@Entity({ name: 'products' })
|
|
85
92
|
@Unique('store_ref_sku', ['storeRef', 'sku'])
|
|
86
93
|
export class Product extends AbstractBase {
|
|
@@ -180,6 +187,9 @@ export class Product extends AbstractBase {
|
|
|
180
187
|
@Column()
|
|
181
188
|
attributes?: ProductAttributes;
|
|
182
189
|
|
|
190
|
+
@Column()
|
|
191
|
+
coupon?: ProductCoupon;
|
|
192
|
+
|
|
183
193
|
@Column()
|
|
184
194
|
stockHistory?: {
|
|
185
195
|
stock: number,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Product } from '../entities/product';
|
|
2
|
+
import { Price } from '../entities/price';
|
|
3
|
+
import { parseProductDtoToTypesenseDocument } from './product.utils';
|
|
4
|
+
|
|
5
|
+
function makeProduct(overrides: Partial<Product> = {}): Product {
|
|
6
|
+
const price = { offerPrice: 50000, normalPrice: 80000 } as Price;
|
|
7
|
+
const base: Partial<Product> = {
|
|
8
|
+
name: 'Taladro', storeRef: '5f27437dabd4b000086cd698', sku: 'SKU1',
|
|
9
|
+
url: 'https://x', price,
|
|
10
|
+
};
|
|
11
|
+
return Object.assign(new Product(), base, overrides) as Product;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
describe('parseProductDtoToTypesenseDocument — coupon fields', () => {
|
|
15
|
+
it('emits couponCode and hasCoupon=true when the product has a coupon', () => {
|
|
16
|
+
const doc = parseProductDtoToTypesenseDocument(
|
|
17
|
+
makeProduct({ coupon: { code: 'NOTHING10', discountType: 'percentage', discountValue: 10, rawLabel: 'Cupón 10%: NOTHING10' } }),
|
|
18
|
+
);
|
|
19
|
+
expect(doc.couponCode).toBe('NOTHING10');
|
|
20
|
+
expect(doc.hasCoupon).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('emits empty couponCode and hasCoupon=false when there is no coupon', () => {
|
|
24
|
+
const doc = parseProductDtoToTypesenseDocument(makeProduct());
|
|
25
|
+
expect(doc.couponCode).toBe('');
|
|
26
|
+
expect(doc.hasCoupon).toBe(false);
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -155,6 +155,8 @@ export const parseProductDtoToTypesenseDocument = (product: Product): ObjectLite
|
|
|
155
155
|
image: ref.image,
|
|
156
156
|
brandName: ref.brandName ? normalizeString(ref.brandName) : undefined,
|
|
157
157
|
sellerName: ref.sellerName,
|
|
158
|
+
couponCode: ref.coupon?.code ?? '',
|
|
159
|
+
hasCoupon: !!ref.coupon?.code,
|
|
158
160
|
// priceStats: priceStats,
|
|
159
161
|
category: ref.category,
|
|
160
162
|
categoryPath: ref.categoryPath,
|