PliWould/lib/product.ts

63 lines
1.8 KiB
TypeScript

import {length as en_length, area as en_area} from "enheter"
import {Measure, LengthUnit, AreaUnit, } from "enheter"
export type Id = string;
export type Currency = "USD";
export class Price<C extends Currency> {
constructor(public value : number) {}
}
export function price(c : Currency, value : number) {
return new Price<typeof c>(value);
}
export type ProductAttributes = {
name?: string,
image?: string,
description?: string,
depth?: string,
[key:string]: any,
}
export abstract class Product {
id?: Id
constructor(public pricePerUnit : Price<Currency>, public attributes : ProductAttributes = {}) {}
public abstract priceFor(measure : Measure<"length"> | Measure<"area">) : Price<Currency>;
}
interface ILength {
length : Measure<"length">
}
interface IArea {
area: Measure<"area">
}
export class LengthProduct extends Product implements ILength {
constructor(public pricePerUnit : Price<Currency>, public length: Measure<"length">, public attributes : ProductAttributes = {}) {
super(pricePerUnit, attributes);
}
public priceFor(length : Measure<"length">): Price<Currency> {
const ratio = length.convertTo(this.length.unit).divideBy(this.length).value;
return {
value: this.pricePerUnit.value * ratio,
};
}
}
export class AreaProduct extends Product implements IArea {
constructor(public pricePerUnit : Price<Currency>, public area : Measure<"area">, public attributes : ProductAttributes = {}) {
super(pricePerUnit, attributes);
}
public priceFor(area : Measure<"area">): Price<Currency> {
const ratio = area.convertTo(this.area.unit).divideBy(this.area).value;
return {
value: this.pricePerUnit.value * ratio,
};
}
}