Skip to content

Commit

Permalink
feat: added match product
Browse files Browse the repository at this point in the history
- added product properties
  • Loading branch information
schaechinger committed Aug 22, 2021
1 parent a6934b4 commit 8f92b13
Show file tree
Hide file tree
Showing 11 changed files with 1,187 additions and 155 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.9.0] - Unreleased

### Added

- Product matching based on content information
- Paper and envelope calculations for product matching
- Product now have a `properties` key with various information about the usage
and features of the product as well as flags for registered, priority and
tracking ability

### Changed

- Product structure for weight and dimension ranges changed

## [0.8.0] - 2021-08-20

### Added
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "internetmarke",
"version": "0.8.0",
"version": "0.9.0",
"description": "A node implementation to use the Internetmarke web service of Deutsche Post.",
"keywords": [
"internetmarke",
Expand Down
25 changes: 24 additions & 1 deletion src/Internetmarke.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
PortokasseServiceOptions
} from './portokasse/Service';
import { Catalog } from './prodWs/catalog';
import { Product } from './prodWs/product';
import { matchProduct, MatchProductOptions, Product } from './prodWs/product';
import { ProductService, ProductServiceOptions, ProdWS } from './prodWs/Service';
import { UserInfo } from './User';
import { Amount } from './utils/amount';
Expand Down Expand Up @@ -64,6 +64,18 @@ export { PaymentMethod, PaymentResponse, PortokasseServiceOptions } from './port
// ProdWS
export { Catalog, CatalogItem } from './prodWs/catalog';
export { ClientCredentials } from './prodWs/Client';
export {
Dimension,
DinEnvelope,
DinFormat,
DinPaper,
LengthUnit,
MeasurementSystem,
PaperDetailOptions,
PaperDetails,
Weight,
WeightUnit
} from './prodWs/paper';
export { Product } from './prodWs/product';
export { ProductServiceOptions } from './prodWs/Service';

Expand Down Expand Up @@ -298,6 +310,17 @@ export class Internetmarke implements OneClickForApp, Portokasse, ProdWS {
return this.productService.getProduct(id);
}

/**
* Matches the given options to the right product.
*
* @param options Match options to retrieve the right product.
*/
public async matchProduct(options: MatchProductOptions): Promise<Product | null> {
const products = await this.productService.getProductList();

return matchProduct(products, options);
}

//
// Portokasse
//
Expand Down
40 changes: 3 additions & 37 deletions src/prodWs/catalog.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { parsePropertyList } from './propertyList';

export interface CatalogItem {
name: string;
value: string | string[];
Expand All @@ -11,25 +13,6 @@ export interface Catalog {
items: CatalogItem[];
}

const getPropertyValue = (prop: any): any => {
let value: any;
if (undefined !== prop.alphanumericValue) {
value = prop.alphanumericValue.attributes.fixValue;
} else if (undefined !== prop.numericValue) {
value = +prop.numericValue.attributes.fixValue;
} else if (undefined !== prop.booleanValue) {
value = 'true' === prop.booleanValue;
} else if (undefined !== prop.dateValue) {
value = (prop.dateValue && new Date(prop.dateValue.attributes.fixDate)) || null;
} else {
const key = Object.keys(prop)[0];
value = prop[key].attributes?.fixValue || prop[key];
// throw new Error(`Unknown prop type: ${Object.keys(prop)[0]}`);
}

return value;
};

export const parseCatalog = (data: any): Catalog | null => {
if (!data?.catalogValueList) {
return null;
Expand Down Expand Up @@ -63,24 +46,7 @@ export const parseCatalog = (data: any): Catalog | null => {
}

if (value.propertyList) {
catalogValue.properties = {};
const propertyList = Array.isArray(value.propertyList.property)
? value.propertyList.property
: [value.propertyList.property];

propertyList.forEach(prop => {
const { name } = prop.attributes;
const val = getPropertyValue(prop.propertyValue);
if (!catalogValue.properties![name]) {
catalogValue.properties![name] = val;
} else {
if (!Array.isArray(catalogValue.properties![name])) {
catalogValue.properties![name] = [catalogValue.properties![name]];
}

catalogValue.properties![name].push(val);
}
});
catalogValue.properties = parsePropertyList(value.propertyList);
}

catalog.items.push(catalogValue);
Expand Down
130 changes: 90 additions & 40 deletions src/prodWs/paper.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,36 @@
import { PageFormatDimension } from '../1c4a/pageFormat';

export enum DinAPaper {
Din4A0,
Din2A0,
DinA0,
DinA1,
DinA2,
DinA3,
DinA4,
DinA5,
DinA6,
DinA7,
DinA8,
DinA9,
DinA10
export enum DinPaper {
DinA0 = 'A0',
DinA1 = 'A1',
DinA2 = 'A2',
DinA3 = 'A3',
DinA4 = 'A4',
DinA5 = 'A5',
DinA6 = 'A6',
DinA7 = 'A7',
DinA8 = 'A8',
DinA9 = 'A9',
DinA10 = 'A10'
}

export enum DinEnvelope {
DinB4 = 'B4',
DinB5 = 'B5',
DinB6 = 'B6',
DinC4 = 'C4',
DinC5 = 'C5',
DinC6 = 'C6',
DinLang = 'DL',
None = 'NONE'
}

export type DinFormat = DinPaper | DinEnvelope;

export type MeasurementSystem = 'METRIC' | 'IMPERIAL';
export type LengthUnit = 'mm' | 'in';
export type WeightUnit = 'g' | 'oz';
export type WeightUnit = 'g' | 'oz' | 'g/m²';

export interface PaperDimensions extends PageFormatDimension {
export interface Dimension {
size: number[];
unit: LengthUnit;
}

Expand All @@ -30,54 +40,93 @@ export interface Weight {
}

export interface PaperDetailOptions {
weight?: number;
/** The paper strength in g/m². Defaults to 80 for paper, 90 for envelopes and 150 for postcards. */
grammage?: number;
/** The applied measurement system for the ouput. Defaults to 'METRIC'. */
system?: MeasurementSystem;
}

const IMP_SIZE_FACTOR = 25.4;
const IMP_WEIGHT_FACTOR = 0.035274;

const SeriesInit = {
A: [841, 1189],
B: [1000, 1414],
C: [917, 1297],
// D: [771, 1091],
DL: [110, 220]
};

export interface PaperDetails {
format: DinAPaper;
dimensions: PaperDimensions;
format: DinFormat;
dimensions: Dimension;
weight: Weight;
grammage: Weight;
}

const getPaperDimensions = (format: DinFormat): Dimension => {
const match = format.match(/^([A-C]|DL)(\d*)$/i)!;
const formatId = match[2] ? +match[2] : 0;

const dimensions: Dimension = {
size: SeriesInit[match[1]],
unit: 'mm'
};

for (let i = formatId; 0 < i; i -= 1) {
const [x, y] = dimensions.size;
dimensions.size = [Math.floor(y / 2), x];
}

return dimensions;
};

export const getPaperDetails = (
format: DinAPaper,
format: DinFormat,
options: PaperDetailOptions = {}
): PaperDetails => {
): PaperDetails | null => {
if (DinEnvelope.None === format) {
return null;
}

const paperOptions: PaperDetailOptions = {
weight: 80,
grammage: 80,
system: 'METRIC',
...options
};

const series = format.match(/^[A-C]|DL/i)!;
const isEnvelope = ['B', 'C', 'DL'].includes(series[0]);

// envelopes
if (isEnvelope) {
if (!options.grammage) {
paperOptions.grammage = 90;
}
}

const isImperial = 'IMPERIAL' === paperOptions.system;

// TODO: convert custom weight for imperial

// DIN 4A0 init
const dimensions: PaperDimensions = {
x: 1682,
y: 2378,
unit: 'mm'
};

for (let i = format; 0 < i; i -= 1) {
const { y } = dimensions;
dimensions.y = dimensions.x;
dimensions.x = Math.floor(y / 2);
}
const dimensions = getPaperDimensions(format);

const weight: Weight = {
value: (dimensions.x * dimensions.y * paperOptions.weight!) / 1000000,
value: (dimensions.size[0] * dimensions.size[1] * paperOptions.grammage!) / 1000000,
unit: 'g'
};
if (isEnvelope) {
weight.value *= 2;
}

const grammage: Weight = {
value: paperOptions.grammage!,
unit: 'g/m²'
};

if (isImperial) {
dimensions.x = +(dimensions.x / IMP_SIZE_FACTOR).toFixed(1);
dimensions.y = +(dimensions.y / IMP_SIZE_FACTOR).toFixed(1);
dimensions.size[0] = +(dimensions.size[0] / IMP_SIZE_FACTOR).toFixed(1);
dimensions.size[1] = +(dimensions.size[1] / IMP_SIZE_FACTOR).toFixed(1);
dimensions.unit = 'in';

weight.value = +(weight.value * IMP_WEIGHT_FACTOR).toFixed(3);
Expand All @@ -89,6 +138,7 @@ export const getPaperDetails = (
return {
format,
dimensions,
weight
weight,
grammage
};
};
Loading

0 comments on commit 8f92b13

Please sign in to comment.