Merge pull request #29118 from woocommerce/packages/api/product-properties

Separate product properties into property groups
This commit is contained in:
Greg 2021-02-19 14:24:14 -07:00 committed by GitHub
commit 6f9c00cd1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 781 additions and 309 deletions

View File

@ -1,14 +1,12 @@
import { Model } from '../model';
import { MetaData, PostStatus } from '../shared-types';
import { Model } from '../../model';
import { MetaData, PostStatus } from '../../shared-types';
import {
BackorderStatus,
CatalogVisibility,
ProductAttribute,
ProductDownload,
ProductImage,
ProductTerm, StockStatus,
Taxability,
} from './shared-types';
ProductTerm,
ProductLinks,
} from '../shared';
/**
* The common parameters that all products can use in search.
@ -16,20 +14,7 @@ import {
export type ProductSearchParams = { search: string };
/**
* The common parameters that all products can update.
*/
export type ProductUpdateParams = 'name' | 'slug' | 'created' | 'postStatus' | 'shortDescription'
| 'description' | 'sku' | 'categories' | 'tags' | 'isFeatured'
| 'isVirtual' | 'attributes' | 'images' | 'catalogVisibility'
| 'regularPrice' | 'onePerOrder' | 'taxStatus' | 'taxClass'
| 'salePrice' | 'saleStart' | 'saleEnd' | 'isDownloadable'
| 'downloadLimit' | 'daysToDownload' | 'weight' | 'length'
| 'width' | 'height' | 'trackInventory' | 'remainingStock'
| 'stockStatus' | 'backorderStatus' | 'allowReviews'
| 'metaData';
/**
* The base class for all product types.
* The base for all product types.
*/
export abstract class AbstractProduct extends Model {
/**
@ -53,6 +38,27 @@ export abstract class AbstractProduct extends Model {
*/
public readonly permalink: string = '';
/**
* The Id of the product.
*
* @type {number}
*/
public readonly id: number = 0;
/**
* The parent Id of the product.
*
* @type {number}
*/
public readonly parentId: number = 0;
/**
* The menu order assigned to the product.
*
* @type {number}
*/
public readonly menuOrder: number = 0;
/**
* The GMT datetime when the product was created.
*
@ -123,13 +129,6 @@ export abstract class AbstractProduct extends Model {
*/
public readonly isFeatured: boolean = false;
/**
* Indicates that the product is delivered virtually.
*
* @type {boolean}
*/
public readonly isVirtual: boolean = false;
/**
* The attributes for the product.
*
@ -158,6 +157,13 @@ export abstract class AbstractProduct extends Model {
*/
public readonly price: string = '';
/**
* The rendered HTML for the current price of the product.
*
* @type {string}
*/
public readonly priceHtml: string = '';
/**
* The regular price of the product when not discounted.
*
@ -165,27 +171,6 @@ export abstract class AbstractProduct extends Model {
*/
public readonly regularPrice: string = '';
/**
* Indicates that only one of a product may be held in the order at a time.
*
* @type {boolean}
*/
public readonly onePerOrder: boolean = false;
/**
* The taxability of the product.
*
* @type {Taxability}
*/
public readonly taxStatus: Taxability = Taxability.ProductAndShipping;
/**
* The tax class of the product
*
* @type {string}
*/
public readonly taxClass: string = '';
/**
* Indicates whether or not the product is currently on sale.
*
@ -215,123 +200,11 @@ export abstract class AbstractProduct extends Model {
public readonly saleEnd: Date | null = null;
/**
* Indicates whether or not the product is downloadable.
*
* @type {boolean}
*/
public readonly isDownloadable: boolean = false;
/**
* The downloads available for the product.
*
* @type {ReadonlyArray.<ProductDownload>}
*/
public readonly downloads: readonly ProductDownload[] = [];
/**
* The maximum number of times a customer may download the product's contents.
* The count of sales of the product
*
* @type {number}
*/
public readonly downloadLimit: number = -1;
/**
* The number of days after purchase that a customer may still download the product's contents.
*
* @type {number}
*/
public readonly daysToDownload: number = -1;
/**
* The weight of the product in the store's current units.
*
* @type {string}
*/
public readonly weight: string = '';
/**
* The length of the product in the store's current units.
*
* @type {string}
*/
public readonly length: string = '';
/**
* The width of the product in the store's current units.
*
* @type {string}
*/
public readonly width: string = '';
/**
* The height of the product in the store's current units.
*
* @type {string}
*/
public readonly height: string = '';
/**
* Indicates that the product must be shipped.
*
* @type {boolean}
*/
public readonly requiresShipping: boolean = false;
/**
* Indicates that the product's shipping is taxable.
*
* @type {boolean}
*/
public readonly isShippingTaxable: boolean = false;
/**
* The shipping class for the product.
*
* @type {string}
*/
public readonly shippingClass: string = '';
/**
* Indicates that a product should use the inventory system.
*
* @type {boolean}
*/
public readonly trackInventory: boolean = false;
/**
* The number of inventory units remaining for this product.
*
* @type {number}
*/
public readonly remainingStock: number = -1;
/**
* The product's stock status.
*
* @type {StockStatus}
*/
public readonly stockStatus: StockStatus = ''
/**
* The status of backordering for a product.
*
* @type {BackorderStatus}
*/
public readonly backorderStatus: BackorderStatus = BackorderStatus.Allowed;
/**
* Indicates whether or not a product can be backordered.
*
* @type {boolean}
*/
public readonly canBackorder: boolean = false;
/**
* Indicates whether or not a product is on backorder.
*
* @type {boolean}
*/
public readonly isOnBackorder: boolean = false;
public readonly totalSales: number = 0;
/**
* Indicates whether or not a product allows reviews.
@ -354,10 +227,29 @@ export abstract class AbstractProduct extends Model {
*/
public readonly numRatings: number = -1;
/**
* An array of IDs of related products.
*
* @type {ReadonlyArray.<number>}
*/
public readonly relatedIds: Array<number> = [];
/**
* The extra metadata for the product.
*
* @type {ReadonlyArray.<MetaData>}
*/
public readonly metaData: readonly MetaData[] = [];
/**
* The products links.
*
* @type {ReadonlyArray.<ProductLinks>}
*/
public readonly links: ProductLinks = {
collection: [ { href: '' } ],
self: [ { href: '' } ],
};
}
export interface IProductCommon extends AbstractProduct {}

View File

@ -0,0 +1,15 @@
import { Model } from '../../model';
/**
* The base for cross sells.
*/
abstract class AbstractProductCrossSells extends Model {
/**
* An array of cross sell product ids.
*
* @type {ReadonlyArray.<number>}
*/
public readonly crossSellIds: Array<number> = [];
}
export interface IProductCrossSells extends AbstractProductCrossSells {}

View File

@ -0,0 +1,51 @@
import { Model } from '../../model';
import { ProductDownload } from '../shared';
/**
* The base for Delivery products.
*/
abstract class AbstractProductDelivery extends Model {
/**
* Indicates that the product is delivered virtually.
*
* @type {boolean}
*/
public readonly isVirtual: boolean = false;
/**
* Indicates whether or not the product is downloadable.
*
* @type {boolean}
*/
public readonly isDownloadable: boolean = false;
/**
* The downloads available for the product.
*
* @type {ReadonlyArray.<ProductDownload>}
*/
public readonly downloads: readonly ProductDownload[] = [];
/**
* The maximum number of times a customer may download the product's contents.
*
* @type {number}
*/
public readonly downloadLimit: number = -1;
/**
* The number of days after purchase that a customer may still download the product's contents.
*
* @type {number}
*/
public readonly daysToDownload: number = -1;
/**
* The text shown to the customer on completing the purchase of this product.
*
* @type {string}
*/
public readonly purchaseNote: string = '';
}
export interface IProductDelivery extends AbstractProductDelivery {}

View File

@ -0,0 +1,7 @@
export * from './common';
export * from './cross-sell';
export * from './delivery';
export * from './inventory';
export * from './sales-tax';
export * from './shipping';
export * from './upsell';

View File

@ -0,0 +1,61 @@
import { Model } from '../../model';
import {
BackorderStatus,
StockStatus,
} from '../shared';
/**
* The base for inventory products.
*/
abstract class AbstractProductInventory extends Model {
/**
* Indicates that only one of a product may be held in the order at a time.
*
* @type {boolean}
*/
public readonly onePerOrder: boolean = false;
/**
* Indicates that a product should use the inventory system.
*
* @type {boolean}
*/
public readonly trackInventory: boolean = false;
/**
* The number of inventory units remaining for this product.
*
* @type {number}
*/
public readonly remainingStock: number = -1;
/**
* The product's stock status.
*
* @type {StockStatus}
*/
public readonly stockStatus: StockStatus = ''
/**
* The status of backordering for a product.
*
* @type {BackorderStatus}
*/
public readonly backorderStatus: BackorderStatus = BackorderStatus.Allowed;
/**
* Indicates whether or not a product can be backordered.
*
* @type {boolean}
*/
public readonly canBackorder: boolean = false;
/**
* Indicates whether or not a product is on backorder.
*
* @type {boolean}
*/
public readonly isOnBackorder: boolean = false;
}
export interface IProductInventory extends AbstractProductInventory {}

View File

@ -0,0 +1,23 @@
import { Model } from '../../model';
import { Taxability } from '../shared';
/**
* The base for products with sales tax.
*/
abstract class AbstractProductSalesTax extends Model {
/**
* The taxability of the product.
*
* @type {Taxability}
*/
public readonly taxStatus: Taxability = Taxability.ProductAndShipping;
/**
* The tax class of the product
*
* @type {string}
*/
public readonly taxClass: string = '';
}
export interface IProductSalesTax extends AbstractProductSalesTax {}

View File

@ -0,0 +1,64 @@
import { Model } from '../../model';
/**
* The base class for product shipping.
*/
abstract class AbstractProductShipping extends Model {
/**
* The weight of the product in the store's current units.
*
* @type {string}
*/
public readonly weight: string = '';
/**
* The length of the product in the store's current units.
*
* @type {string}
*/
public readonly length: string = '';
/**
* The width of the product in the store's current units.
*
* @type {string}
*/
public readonly width: string = '';
/**
* The height of the product in the store's current units.
*
* @type {string}
*/
public readonly height: string = '';
/**
* Indicates that the product must be shipped.
*
* @type {boolean}
*/
public readonly requiresShipping: boolean = false;
/**
* Indicates that the product's shipping is taxable.
*
* @type {boolean}
*/
public readonly isShippingTaxable: boolean = false;
/**
* The shipping class for the product.
*
* @type {string}
*/
public readonly shippingClass: string = '';
/**
* The shipping class ID for the product.
*
* @type {number}
*/
public readonly shippingClassId: number = 0;
}
export interface IProductShipping extends AbstractProductShipping {}

View File

@ -0,0 +1,15 @@
import { Model } from '../../model';
/**
* The base for upsells.
*/
abstract class AbstractProductUpSells extends Model {
/**
* An array of upsell product ids.
*
* @type {ReadonlyArray.<number>}
*/
public readonly upSellIds: Array<number> = [];
}
export interface IProductUpSells extends AbstractProductUpSells {}

View File

@ -1,3 +1,3 @@
export * from './abstract-product';
export * from './shared-types';
export * from './abstract';
export * from './shared';
export * from './simple-product';

View File

@ -1,82 +1,3 @@
/**
* An enum describing the catalog visibility options for products.
*
* @enum {string}
*/
export enum CatalogVisibility {
/**
* The product should be visible everywhere.
*/
Everywhere = 'visible',
/**
* The product should only be visible in the shop catalog.
*/
ShopOnly = 'catalog',
/**
* The product should only be visible in search results.
*/
SearchOnly = 'search',
/**
* The product should be hidden everywhere.
*/
Hidden = 'hidden'
}
/**
* Indicates the taxability of a product.
*
* @enum {string}
*/
export enum Taxability {
/**
* The product and shipping are both taxable.
*/
ProductAndShipping = 'taxable',
/**
* Only the product's shipping is taxable.
*/
ShippingOnly = 'shipping',
/**
* The product and shipping are not taxable.
*/
None = 'none'
}
/**
* Indicates the status for backorders for a product.
*
* @enum {string}
*/
export enum BackorderStatus {
/**
* The product is allowed to be backordered.
*/
Allowed = 'yes',
/**
* The product is allowed to be backordered but it will notify the customer of that fact.
*/
AllowedWithNotification = 'notify',
/**
* The product is not allowed to be backordered.
*/
NotAllowed = 'no'
}
/**
* A product's stock status.
*
* @typedef StockStatus
* @alias 'instock'|'outofstock'|'onbackorder'|string
*/
export type StockStatus = 'instock' | 'outofstock' | 'onbackorder' | string
/**
* A products taxonomy term such as categories or tags.
*/
@ -259,3 +180,52 @@ export class ProductImage {
Object.assign( this, properties );
}
}
/**
* A product link item.
*/
class ProductLinkItem {
/**
* The options which are available for the attribute.
*
* @type {ReadonlyArray.<string>}
*/
public readonly href: string = '';
/**
* Creates a new product link item.
*
* @param {Partial.<ProductLinkItem>} properties The properties to set.
*/
public constructor( properties?: Partial< ProductLinkItem > ) {
Object.assign( this, properties );
}
}
/**
* A product's links.
*/
export class ProductLinks {
/**
* The collection containing the product.
*
* @type {ReadonlyArray.<ProductLinkItem>}
*/
public readonly collection: readonly ProductLinkItem[] = [];
/**
* Self referential link to the product.
*
* @type {ReadonlyArray.<ProductLinkItem>}
*/
public readonly self: readonly ProductLinkItem[] = [];
/**
* Creates a new product link list.
*
* @param {Partial.<ProductLinks>} properties The properties to set.
*/
public constructor( properties?: Partial< ProductLinks > ) {
Object.assign( this, properties );
}
}

View File

@ -0,0 +1,70 @@
/**
* An enum describing the catalog visibility options for products.
*
* @enum {string}
*/
export enum CatalogVisibility {
/**
* The product should be visible everywhere.
*/
Everywhere = 'visible',
/**
* The product should only be visible in the shop catalog.
*/
ShopOnly = 'catalog',
/**
* The product should only be visible in search results.
*/
SearchOnly = 'search',
/**
* The product should be hidden everywhere.
*/
Hidden = 'hidden'
}
/**
* Indicates the taxability of a product.
*
* @enum {string}
*/
export enum Taxability {
/**
* The product and shipping are both taxable.
*/
ProductAndShipping = 'taxable',
/**
* Only the product's shipping is taxable.
*/
ShippingOnly = 'shipping',
/**
* The product and shipping are not taxable.
*/
None = 'none'
}
/**
* Indicates the status for backorders for a product.
*
* @enum {string}
*/
export enum BackorderStatus {
/**
* The product is allowed to be backordered.
*/
Allowed = 'yes',
/**
* The product is allowed to be backordered but it will notify the customer of that fact.
*/
AllowedWithNotification = 'notify',
/**
* The product is not allowed to be backordered.
*/
NotAllowed = 'no'
}

View File

@ -0,0 +1,3 @@
export * from './enums';
export * from './types';
export * from './classes';

View File

@ -0,0 +1,66 @@
/**
* A product's stock status.
*
* @typedef StockStatus
* @alias 'instock'|'outofstock'|'onbackorder'|string
*/
export type StockStatus = 'instock' | 'outofstock' | 'onbackorder' | string
/**
* Properties common to all product types.
*/
export type ProductCommonUpdateParams = 'name' | 'slug' | 'created' | 'postStatus' | 'shortDescription'
| 'id' | 'permalink' | 'price' | 'priceHtml' | 'type'
| 'description' | 'sku' | 'categories' | 'tags' | 'isFeatured'
| 'attributes' | 'images' | 'catalogVisibility' | 'allowReviews'
| 'regularPrice' | 'salePrice' | 'saleStart' | 'saleEnd'
| 'metaData' | 'menuOrder' | 'parentId' | 'relatedIds' | 'upsellIds'
| 'links' | 'relatedIds' | 'menuOrder' | 'parentId';
/**
* Cross sells property.
*/
export type ProductCrossUpdateParams = 'crossSellIds';
/**
* Upsells property.
*/
export type ProductUpSellUpdateParams = 'upSellIds';
/**
* Properties exclusive to the External product type.
*/
export type ProductExternalTypeUpdateParams = 'buttonText' | 'externalUrl';
/**
* Properties exclusive to the Grouped product type.
*/
export type ProductGroupedTypeUpdateParams = 'groupedProducts';
/**
* Properties related to tracking inventory.
*/
export type ProductInventoryUpdateParams = 'backorderStatus' | 'canBackorder' | 'trackInventory'
| 'onePerOrder' | 'remainingStock';
/**
* Properties related to sales tax.
*/
export type ProductSalesTaxUpdateParams = 'taxClass' | 'taxStatus';
/**
* Properties related to shipping.
*/
export type ProductShippingUpdateParams = 'height' | 'length' | 'weight' | 'width'
| 'shippingClass' | 'shippingClassId';
/**
* Properties exclusive to the Simple product type.
*/
export type ProductDeliveryUpdateParams = 'daysToDownload' | 'downloadLimit' | 'downloads'
| 'purchaseNote' | 'isVirtual';
/**
* Properties exclusive to the Variable product type.
*/
export type ProductVariableTypeUpdateParams = 'defaultAttributes' | 'variations';

View File

@ -1,4 +1,27 @@
import { AbstractProduct, ProductSearchParams, ProductUpdateParams } from './abstract-product';
import {
AbstractProduct,
IProductCommon,
IProductCrossSells,
IProductDelivery,
IProductInventory,
IProductSalesTax,
IProductShipping,
IProductUpSells,
ProductSearchParams,
} from './abstract';
import {
ProductDeliveryUpdateParams,
ProductInventoryUpdateParams,
ProductCommonUpdateParams,
ProductSalesTaxUpdateParams,
ProductCrossUpdateParams,
ProductShippingUpdateParams,
ProductUpSellUpdateParams,
ProductDownload,
StockStatus,
BackorderStatus,
Taxability,
} from './shared';
import { HTTPClient } from '../../http';
import { simpleProductRESTRepository } from '../../repositories';
import {
@ -10,11 +33,21 @@ import {
UpdatesModels,
} from '../../framework';
/**
* The parameters that simple products can update.
*/
type SimpleProductUpdateParams = ProductDeliveryUpdateParams
& ProductCommonUpdateParams
& ProductCrossUpdateParams
& ProductInventoryUpdateParams
& ProductSalesTaxUpdateParams
& ProductShippingUpdateParams
& ProductUpSellUpdateParams;
/**
* The parameters embedded in this generic can be used in the ModelRepository in order to give
* type-safety in an incredibly granular way.
*/
export type SimpleProductRepositoryParams = ModelRepositoryParams< SimpleProduct, never, ProductSearchParams, ProductUpdateParams >;
export type SimpleProductRepositoryParams = ModelRepositoryParams< SimpleProduct, never, ProductSearchParams, SimpleProductUpdateParams >;
/**
* An interface for listing simple products using the repository.
@ -57,9 +90,65 @@ export type UpdatesSimpleProducts = UpdatesModels< SimpleProductRepositoryParams
export type DeletesSimpleProducts = DeletesModels< SimpleProductRepositoryParams >;
/**
* A simple product object.
* The base for the simple product object.
*/
export class SimpleProduct extends AbstractProduct {
export class SimpleProduct extends AbstractProduct implements
IProductCommon,
IProductCrossSells,
IProductDelivery,
IProductInventory,
IProductSalesTax,
IProductShipping,
IProductUpSells {
/**
* @see ./abstracts/cross-sells.ts
*/
public readonly crossSellIds: Array<number> = [];
/**
* @see ./abstracts/upsell.ts
*/
public readonly upSellIds: Array<number> = [];
/**
* @see ./abstracts/delivery.ts
*/
public readonly isVirtual: boolean = false;
public readonly isDownloadable: boolean = false;
public readonly downloads: readonly ProductDownload[] = [];
public readonly downloadLimit: number = -1;
public readonly daysToDownload: number = -1;
public readonly purchaseNote: string = '';
/**
* @see ./abstracts/inventory.ts
*/
public readonly onePerOrder: boolean = false;
public readonly trackInventory: boolean = false;
public readonly remainingStock: number = -1;
public readonly stockStatus: StockStatus = ''
public readonly backorderStatus: BackorderStatus = BackorderStatus.Allowed;
public readonly canBackorder: boolean = false;
public readonly isOnBackorder: boolean = false;
/**
* @see ./abstracts/sales-tax.ts
*/
public readonly taxStatus: Taxability = Taxability.ProductAndShipping;
public readonly taxClass: string = '';
/**
* @see ./abstracts/shipping.ts
*/
public readonly weight: string = '';
public readonly length: string = '';
public readonly width: string = '';
public readonly height: string = '';
public readonly requiresShipping: boolean = false;
public readonly isShippingTaxable: boolean = false;
public readonly shippingClass: string = '';
public readonly shippingClassId: number = 0;
/**
* Creates a new simple product instance with the given properties
*

View File

@ -1,22 +1,28 @@
import {
AddPropertyTransformation,
CustomTransformation,
IgnorePropertyTransformation,
KeyChangeTransformation,
ModelTransformation,
ModelTransformer,
TransformationOrder,
KeyChangeTransformation,
AddPropertyTransformation,
IgnorePropertyTransformation,
ModelTransformerTransformation,
PropertyType,
PropertyTypeTransformation,
CustomTransformation,
ModelTransformerTransformation,
TransformationOrder,
} from '../../../framework';
import {
AbstractProduct,
IProductCrossSells,
IProductDelivery,
IProductInventory,
IProductSalesTax,
IProductShipping,
IProductUpSells,
MetaData,
ProductAttribute,
ProductDownload,
ProductImage,
ProductTerm,
MetaData,
} from '../../../models';
import { createMetaDataTransformer } from '../shared';
@ -130,8 +136,168 @@ export function createProductTransformer< T extends AbstractProduct >(
new ModelTransformerTransformation( 'tags', ProductTerm, createProductTermTransformer() ),
new ModelTransformerTransformation( 'attributes', ProductAttribute, createProductAttributeTransformer() ),
new ModelTransformerTransformation( 'images', ProductImage, createProductImageTransformer() ),
new ModelTransformerTransformation( 'downloads', ProductDownload, createProductDownloadTransformer() ),
new ModelTransformerTransformation( 'metaData', MetaData, createMetaDataTransformer() ),
new PropertyTypeTransformation(
{
created: PropertyType.Date,
modified: PropertyType.Date,
isPurchasable: PropertyType.Boolean,
isFeatured: PropertyType.Boolean,
onSale: PropertyType.Boolean,
saleStart: PropertyType.Date,
saleEnd: PropertyType.Date,
allowReviews: PropertyType.Boolean,
averageRating: PropertyType.Integer,
numRatings: PropertyType.Integer,
totalSales: PropertyType.Integer,
parentId: PropertyType.Integer,
menuOrder: PropertyType.Integer,
permalink: PropertyType.String,
priceHtml: PropertyType.String,
relatedIds: PropertyType.Integer,
},
),
new KeyChangeTransformation< AbstractProduct >(
{
created: 'date_created_gmt',
modified: 'date_modified_gmt',
postStatus: 'status',
shortDescription: 'short_description',
isPurchasable: 'purchasable',
isFeatured: 'featured',
catalogVisibility: 'catalog_visibility',
regularPrice: 'regular_price',
onSale: 'on_sale',
salePrice: 'sale_price',
saleStart: 'date_on_sale_from_gmt',
saleEnd: 'date_on_sale_to_gmt',
allowReviews: 'reviews_allowed',
averageRating: 'average_rating',
numRatings: 'rating_count',
metaData: 'meta_data',
totalSales: 'total_sales',
parentId: 'parent_id',
menuOrder: 'menu_order',
priceHtml: 'price_html',
relatedIds: 'related_ids',
links: '_links',
},
),
);
return new ModelTransformer( transformations );
}
export function createProductCrossSellsTransformation(): ModelTransformation[] {
const transformations = [
new PropertyTypeTransformation(
{
crossSellIds: PropertyType.Integer,
},
),
new KeyChangeTransformation< IProductCrossSells >(
{
crossSellIds: 'cross_sell_ids',
},
),
];
return transformations;
}
export function createProductUpSellsTransformation(): ModelTransformation[] {
const transformations = [
new PropertyTypeTransformation(
{
upSellIds: PropertyType.Integer,
},
),
new KeyChangeTransformation< IProductUpSells >(
{
upSellIds: 'upsell_ids',
},
),
];
return transformations;
}
export function createProductDeliveryTransformation(): ModelTransformation[] {
const transformations = [
new ModelTransformerTransformation( 'downloads', ProductDownload, createProductDownloadTransformer() ),
new PropertyTypeTransformation(
{
isVirtual: PropertyType.Boolean,
isDownloadable: PropertyType.Boolean,
downloadLimit: PropertyType.Integer,
daysToDownload: PropertyType.Integer,
purchaseNote: PropertyType.String,
},
),
new KeyChangeTransformation< IProductDelivery >(
{
isVirtual: 'virtual',
isDownloadable: 'downloadable',
downloadLimit: 'download_limit',
daysToDownload: 'download_expiry',
purchaseNote: 'purchase_note',
},
),
];
return transformations;
}
export function createProductInventoryTransformation(): ModelTransformation[] {
const transformations = [
new PropertyTypeTransformation(
{
trackInventory: PropertyType.Boolean,
remainingStock: PropertyType.Integer,
canBackorder: PropertyType.Boolean,
isOnBackorder: PropertyType.Boolean,
onePerOrder: PropertyType.Boolean,
stockStatus: PropertyType.String,
backOrderStatus: PropertyType.String,
},
),
new KeyChangeTransformation< IProductInventory >(
{
trackInventory: 'manage_stock',
remainingStock: 'stock_quantity',
stockStatus: 'stock_status',
onePerOrder: 'sold_individually',
backorderStatus: 'backorders',
canBackorder: 'backorders_allowed',
isOnBackorder: 'backordered',
},
),
];
return transformations;
}
export function createProductSalesTaxTransformation(): ModelTransformation[] {
const transformations = [
new PropertyTypeTransformation(
{
taxClass: PropertyType.String,
taxStatus: PropertyType.String,
},
),
new KeyChangeTransformation< IProductSalesTax >(
{
taxStatus: 'tax_status',
taxClass: 'tax_class',
},
),
];
return transformations;
}
export function createProductShippingTransformation(): ModelTransformation[] {
const transformations = [
new CustomTransformation(
TransformationOrder.Normal,
( properties: any ) => {
@ -163,66 +329,22 @@ export function createProductTransformer< T extends AbstractProduct >(
),
new PropertyTypeTransformation(
{
created: PropertyType.Date,
modified: PropertyType.Date,
isPurchasable: PropertyType.Boolean,
isFeatured: PropertyType.Boolean,
isVirtual: PropertyType.Boolean,
onePerOrder: PropertyType.Boolean,
onSale: PropertyType.Boolean,
saleStart: PropertyType.Date,
saleEnd: PropertyType.Date,
isDownloadable: PropertyType.Boolean,
downloadLimit: PropertyType.Integer,
daysToDownload: PropertyType.Integer,
requiresShipping: PropertyType.Boolean,
isShippingTaxable: PropertyType.Boolean,
trackInventory: PropertyType.Boolean,
remainingStock: PropertyType.Integer,
canBackorder: PropertyType.Boolean,
isOnBackorder: PropertyType.Boolean,
allowReviews: PropertyType.Boolean,
averageRating: PropertyType.Integer,
numRatings: PropertyType.Integer,
shippingClass: PropertyType.String,
shippingClassId: PropertyType.Integer,
weight: PropertyType.String,
},
),
new KeyChangeTransformation< AbstractProduct >(
new KeyChangeTransformation< IProductShipping >(
{
created: 'date_created_gmt',
modified: 'date_modified_gmt',
postStatus: 'status',
shortDescription: 'short_description',
isPurchasable: 'purchasable',
isFeatured: 'featured',
isVirtual: 'virtual',
catalogVisibility: 'catalog_visibility',
regularPrice: 'regular_price',
onePerOrder: 'sold_individually',
taxStatus: 'tax_status',
taxClass: 'tax_class',
onSale: 'on_sale',
salePrice: 'sale_price',
saleStart: 'date_on_sale_from_gmt',
saleEnd: 'date_on_sale_to_gmt',
isDownloadable: 'downloadable',
downloadLimit: 'download_limit',
daysToDownload: 'download_expiry',
requiresShipping: 'shipping_required',
isShippingTaxable: 'shipping_taxable',
shippingClass: 'shipping_class',
trackInventory: 'manage_stock',
remainingStock: 'stock_quantity',
stockStatus: 'stock_status',
backorderStatus: 'backorders',
canBackorder: 'backorders_allowed',
isOnBackorder: 'backordered',
allowReviews: 'reviews_allowed',
averageRating: 'average_rating',
numRatings: 'rating_count',
metaData: 'meta_data',
shippingClassId: 'shipping_class_id',
},
),
);
];
return new ModelTransformer( transformations );
return transformations;
}

View File

@ -10,7 +10,15 @@ import {
SimpleProductRepositoryParams,
UpdatesSimpleProducts,
} from '../../../models';
import { createProductTransformer } from './shared';
import {
createProductTransformer,
createProductCrossSellsTransformation,
createProductDeliveryTransformation,
createProductInventoryTransformation,
createProductSalesTaxTransformation,
createProductShippingTransformation,
createProductUpSellsTransformation,
} from './shared';
import {
restCreate,
restDelete,
@ -37,7 +45,23 @@ export function simpleProductRESTRepository( httpClient: HTTPClient ): ListsSimp
& UpdatesSimpleProducts
& DeletesSimpleProducts {
const buildURL = ( id: ModelID ) => '/wc/v3/products/' + id;
const transformer = createProductTransformer( 'simple' );
const crossSells = createProductCrossSellsTransformation();
const delivery = createProductDeliveryTransformation();
const inventory = createProductInventoryTransformation();
const salesTax = createProductSalesTaxTransformation();
const shipping = createProductShippingTransformation();
const upsells = createProductUpSellsTransformation();
const transformations = [
...crossSells,
...delivery,
...inventory,
...salesTax,
...shipping,
...upsells,
];
const transformer = createProductTransformer<SimpleProduct>( 'simple', transformations );
return new ModelRepository(
restList< SimpleProductRepositoryParams >( () => '/wc/v3/products', SimpleProduct, httpClient, transformer ),