63 lines
1.8 KiB
TypeScript
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,
|
|
};
|
|
}
|
|
} |