Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaakko Heusala committed Jul 17, 2024
1 parent a029359 commit 36b82a0
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 44 deletions.
106 changes: 67 additions & 39 deletions store/types/product/Product.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,58 @@
// Copyright (c) 2022. Heusala Group Oy <info@heusalagroup.fi>. All rights reserved.
// Copyright (c) 2022-2024. Sendanor <info@sendanor.fi>. All rights reserved.

import {
explainBooleanOrUndefined,
isBooleanOrUndefined,
} from "../../../types/Boolean";
import { explainProductType, isProductType, ProductType } from "./ProductType";
import { explainProductFeature, isProductFeature, ProductFeature } from "./features/ProductFeature";
import { ProductPrice, isProductPrice, explainProductPrice } from "./ProductPrice";
import { CompositeProductSelection } from "./CompositeProductSelection";
import { explain, explainProperty } from "../../../types/explain";
import { explainString, isString } from "../../../types/String";
import { explainNumberOrUndefined, isNumberOrUndefined } from "../../../types/Number";
import {
explainNumberOrUndefined,
isNumberOrUndefined,
} from "../../../types/Number";
import { explainRegularObject, isRegularObject } from "../../../types/RegularObject";
import { explainNoOtherKeys, hasNoOtherKeys } from "../../../types/OtherKeys";
import { explainArrayOf, isArrayOf } from "../../../types/Array";

/**
* In the legacy database this will be a row in `product_group` table.
*
* See {@see ProductPrice} for `product` table!
*/
export interface Product {
readonly id : string;
readonly type : ProductType;
readonly title : string;
readonly summary : string;
readonly features : readonly ProductFeature[];
readonly prices : readonly ProductPrice[];
readonly stockAmount ?: number;

/**
* If defined, this product is a special product combined from other products
* based on customer's choices
* This is the `slug` property in the database.
*/
readonly composite ?: readonly CompositeProductSelection[];
readonly id : string;

readonly type : ProductType;

/**
* This is the `name` property in the database.
*/
readonly title : string;

/**
* This is the `description` property in the database.
*/
readonly summary : string;

readonly stockSold ?: number;
readonly stockAmount ?: number;
readonly stockEnabled ?: boolean;
readonly onHold ?: boolean;
readonly published ?: boolean;

/**
* Prices come from from `product` table, mapped by the `slug` property.
*/
readonly prices : readonly ProductPrice[];

readonly features : readonly ProductFeature[];

}

Expand All @@ -35,7 +63,10 @@ export function createProduct (
summary : string,
features : readonly ProductFeature[],
prices : readonly ProductPrice[],
stockAmount : number = 0
stockAmount : number,
stockEnabled : boolean,
onHold : boolean,
published : boolean,
) : Product {
return {
id,
Expand All @@ -44,31 +75,13 @@ export function createProduct (
summary,
features,
prices,
stockAmount
stockAmount,
stockEnabled,
onHold,
published,
};
}

export function createCompositeProduct (
id : string,
type : ProductType,
title : string,
summary : string,
composite : readonly CompositeProductSelection[],
stockAmount : number = 0
) : Product {
return {
id,
type,
title,
summary,
features: [],
prices: [],
composite,
stockAmount
};
}


export function isProduct (value: any): value is Product {
return (
isRegularObject(value)
Expand All @@ -79,15 +92,23 @@ export function isProduct (value: any): value is Product {
'summary',
'features',
'prices',
'stockAmount'
'stockSold',
'stockAmount',
'stockEnabled',
'onHold',
'published',
])
&& isString(value?.id)
&& isProductType(value?.type)
&& isString(value?.title)
&& isString(value?.summary)
&& isNumberOrUndefined(value?.stockSold)
&& isNumberOrUndefined(value?.stockAmount)
&& isArrayOf<ProductFeature>(value?.features, isProductFeature)
&& isArrayOf<ProductPrice>(value?.prices, isProductPrice)
&& isBooleanOrUndefined(value?.stockEnabled)
&& isBooleanOrUndefined(value?.onHold)
&& isBooleanOrUndefined(value?.published)
);
}

Expand All @@ -102,20 +123,27 @@ export function explainProduct (value: any) : string {
'summary',
'features',
'prices',
'stockAmount'
'stockSold',
'stockAmount',
'stockEnabled',
'onHold',
'published',
]),
explainProperty("isArrayOf", explainString(value?.isArrayOf)),
explainProperty("type", explainProductType(value?.type)),
explainProperty("title", explainString(value?.title)),
explainProperty("summary", explainString(value?.summary)),
explainProperty("stockSold", explainNumberOrUndefined(value?.stockSold)),
explainProperty("stockAmount", explainNumberOrUndefined(value?.stockAmount)),
explainProperty("features", explainArrayOf<ProductFeature>("ProductFeature", explainProductFeature, value?.features)),
explainProperty("prices", explainArrayOf<ProductPrice>("ProductPrice", explainProductPrice, value?.prices)),
explainProperty("stockEnabled", explainBooleanOrUndefined(value?.stockEnabled)),
explainProperty("onHold", explainBooleanOrUndefined(value?.onHold)),
explainProperty("published", explainBooleanOrUndefined(value?.published)),
]
);
}


export function isProductOrUndefined (value: any): value is Product | undefined {
return value === undefined || isProduct(value);
}
Expand Down
57 changes: 52 additions & 5 deletions store/types/product/ProductPrice.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,39 @@
// Copyright (c) 2022. Heusala Group Oy <info@heusalagroup.fi>. All rights reserved.
// Copyright (c) 2022-2024. Sendanor <info@sendanor.fi>. All rights reserved.

import {
explainBooleanOrUndefined,
isBooleanOrUndefined,
} from "../../../types/Boolean";
import { explainProductPriceType, isProductPriceType, ProductPriceType } from "./ProductPriceType";
import { explain, explainProperty } from "../../../types/explain";
import { explainStringOrUndefined, isStringOrUndefined } from "../../../types/String";
import { explainNumber, explainNumberOrUndefined, isNumber, isNumberOrUndefined } from "../../../types/Number";
import { explainRegularObject, isRegularObject } from "../../../types/RegularObject";
import { explainNoOtherKeys, hasNoOtherKeys } from "../../../types/OtherKeys";

/**
* In the legacy database this will be a row in `product` table.
*
* See {@see Product} for `product_group` table!
*/
export interface ProductPrice {

/** Must be a number like `1234[.5678]`. In the legacy database it will be stored in the `product`.`number` field which is `decimal(20,10)`. */
readonly id ?: string;

readonly sum : number;
readonly vatPercent : number;
readonly type : ProductPriceType;
readonly buyUrl ?: string;
readonly discountPercent ?: number;
readonly discountFrom ?: string;
readonly discountTo ?: string;
readonly stockSold ?: number;
readonly stockAmount ?: number;
readonly stockEnabled ?: boolean;
readonly onHold ?: boolean;
readonly published ?: boolean;
readonly expenseSum ?: number;
}

export function createProductPrice (
Expand Down Expand Up @@ -42,21 +61,35 @@ export function isProductPrice (value: any): value is ProductPrice {
return (
isRegularObject(value)
&& hasNoOtherKeys(value, [
'id',
'sum',
'vatPercent',
'type',
'discountPercent',
'discountFrom',
'discountTo',
'buyUrl'
'buyUrl',
'stockSold',
'stockAmount',
'stockEnabled',
'onHold',
'published',
'expenseSum',
])
&& isStringOrUndefined(value?.id)
&& isNumber(value?.sum)
&& isNumber(value?.vatPercent)
&& isNumberOrUndefined(value?.discountPercent)
&& isStringOrUndefined(value?.discountFrom)
&& isStringOrUndefined(value?.discountTo)
&& isProductPriceType(value?.type)
&& isStringOrUndefined(value?.buyUrl)
&& isNumberOrUndefined(value?.stockSold)
&& isNumberOrUndefined(value?.stockAmount)
&& isBooleanOrUndefined(value?.stockEnabled)
&& isNumberOrUndefined(value?.expenseSum)
&& isBooleanOrUndefined(value?.onHold)
&& isBooleanOrUndefined(value?.published)
);
}

Expand All @@ -65,21 +98,35 @@ export function explainProductPrice (value: any) : string {
[
explainRegularObject(value),
explainNoOtherKeys(value, [
'id',
'sum',
'vatPercent',
'type',
'discountPercent',
'discountFrom',
'discountTo',
'buyUrl'
'buyUrl',
'stockSold',
'stockAmount',
'stockEnabled',
'onHold',
'published',
'expenseSum',
]),
explainProperty("id", explainStringOrUndefined(value?.id)),
explainProperty("sum", explainNumber(value?.sum)),
explainProperty("vatPercent", explainNumber(value?.vatPercent)),
explainProperty("type", explainProductPriceType(value?.type)),
explainProperty("buyUrl", explainStringOrUndefined(value?.buyUrl)),
explainProperty("discountPercent", explainNumberOrUndefined(value?.discountPercent)),
explainProperty("discountFrom", explainStringOrUndefined(value?.discountFrom)),
explainProperty("discountTo", explainStringOrUndefined(value?.discountTo))
explainProperty("discountTo", explainStringOrUndefined(value?.discountTo)),
explainProperty("buyUrl", explainStringOrUndefined(value?.buyUrl)),
explainProperty("stockSold", explainNumberOrUndefined(value?.stockSold)),
explainProperty("stockAmount", explainNumberOrUndefined(value?.stockAmount)),
explainProperty("stockEnabled", explainBooleanOrUndefined(value?.stockEnabled)),
explainProperty("onHold", explainBooleanOrUndefined(value?.onHold)),
explainProperty("published", explainBooleanOrUndefined(value?.published)),
explainProperty("expenseSum", explainNumberOrUndefined(value?.expenseSum)),
]
);
}
Expand Down

0 comments on commit 36b82a0

Please sign in to comment.