@tjetak/fortuna 1.0.0-alpha.1

Sign up to get free protection for your applications and to get access to all the features.
package/build/index.js ADDED
@@ -0,0 +1,98 @@
1
+ 'use strict';
2
+ class Frame {
3
+ constructor({material, model, price, discount}) {
4
+ this.material = material;
5
+ this.model = model;
6
+ this.price = price;
7
+ this.discount = discount;
8
+ }
9
+ }
10
+ class QuantityMargin {
11
+ constructor({min, max, qty}) {
12
+ this.min = min;
13
+ this.max = max;
14
+ this.qty = qty;
15
+ }
16
+ }
17
+ function calculateFrameCost(pouch, frame) {
18
+ let pricePerFrame = frame.price;
19
+ let discount = frame.discount;
20
+ let quantity = pouch.quantity;
21
+ let inputtedModel = pouch.model;
22
+ let inputtedHeight = pouch.height;
23
+ let inputtedLength = pouch.length;
24
+ let inputtedWidth = pouch.width;
25
+ let inputtedFin = pouch.fin;
26
+ let productSize = {length:inputtedLength, height:inputtedHeight, };
27
+ let finalPricePerFrame = pricePerFrame - pricePerFrame * discount;
28
+ let upsPerFrame = 0;
29
+ if (inputtedModel === "Standing Pouch" || inputtedModel === "Layflat Pouch") {
30
+ upsPerFrame = Math.floor(74 / (inputtedHeight * 2)) * Math.floor(110 / inputtedLength);
31
+ } else {
32
+ if (inputtedModel === "Center Seal" && inputtedFin) {
33
+ upsPerFrame = Math.floor(74 / ((inputtedLength + inputtedFin) * 2)) * Math.floor(110 / inputtedHeight);
34
+ } else {
35
+ if (inputtedModel === "Gusset" && inputtedFin && inputtedWidth) {
36
+ upsPerFrame = Math.floor(74 / ((inputtedLength + inputtedWidth + inputtedFin) * 2)) * Math.floor(110 / (inputtedHeight + inputtedFin));
37
+ productSize["width"] = inputtedWidth;
38
+ }
39
+ }
40
+ }
41
+ let productPricePerPcs = finalPricePerFrame / upsPerFrame;
42
+ let cost = {formula:"(finalPricePerFrame / upsPerFrame) * quantity", value:productPricePerPcs * quantity, };
43
+ return {upsPerFrame, pricePerFrame, finalPricePerFrame, productPricePerPcs, productSize, cost, };
44
+ }
45
+ class FrameConfig {
46
+ constructor(frame, quantity, pouchInput) {
47
+ this.frame = frame;
48
+ this.quantity = quantity;
49
+ this.frameCalculation = calculateFrameCost(pouchInput, frame);
50
+ this._totalCost = this.frameCalculation.cost.value;
51
+ this._totalUnitCost = this.frameCalculation.productPricePerPcs;
52
+ }
53
+ }
54
+ function generateFrameConfig(pouchInput, frame) {
55
+ let config = new FrameConfig(frame, pouchInput.quantity, pouchInput);
56
+ return config;
57
+ }
58
+ class FlexibleCalculator {
59
+ constructor() {
60
+ this._MAX_POUCH_INPUT_LENGTH = 35;
61
+ this._frames = [];
62
+ this._quantityMargin = [];
63
+ }
64
+ set frames(data) {
65
+ this._frames = data.map(frame => new Frame(frame));
66
+ }
67
+ set quantityMargins(data) {
68
+ this._quantityMargin = data.map(marginPerQty => new QuantityMargin(marginPerQty));
69
+ }
70
+ calculatePouch(pouchInput) {
71
+ let result;
72
+ let frame = this._frames.find(frame => {
73
+ return frame.material === pouchInput.material && frame.model === pouchInput.model;
74
+ });
75
+ if (!frame) {
76
+ throw Error(`Frame '${pouchInput.material}' not found in frames.`);
77
+ }
78
+ if (pouchInput.model === "Standing Pouch" || pouchInput.model === "Layflat Pouch" || pouchInput.model === "Gusset") {
79
+ if (pouchInput.height > this._MAX_POUCH_INPUT_LENGTH) {
80
+ throw Error(`Maximum height is ${this._MAX_POUCH_INPUT_LENGTH}.`);
81
+ }
82
+ }
83
+ if (pouchInput.model === "Center Seal") {
84
+ if (pouchInput.length > this._MAX_POUCH_INPUT_LENGTH) {
85
+ throw Error(`Maximum length is ${this._MAX_POUCH_INPUT_LENGTH}.`);
86
+ }
87
+ }
88
+ let frameConfig = generateFrameConfig(pouchInput, frame);
89
+ return frameConfig;
90
+ }
91
+ calculate(pouchInput) {
92
+ let result = this.calculatePouch(pouchInput);
93
+ return result;
94
+ }
95
+ }
96
+ var index = new FlexibleCalculator;
97
+ module.exports = index
98
+
@@ -0,0 +1,14 @@
1
+ import FrameData from './types/data/Frame';
2
+ import PouchInput from './types/inputs/Pouch';
3
+ import MarginData from './types/data/QuantityMargin';
4
+ import FrameConfig from './configs/Frame';
5
+ export default class FlexibleCalculator {
6
+ private _frames;
7
+ private _quantityMargin;
8
+ private _MAX_POUCH_INPUT_LENGTH;
9
+ constructor();
10
+ set frames(data: FrameData[]);
11
+ set quantityMargins(data: MarginData[]);
12
+ private calculatePouch;
13
+ calculate(pouchInput: PouchInput): FrameConfig;
14
+ }
@@ -0,0 +1,41 @@
1
+ import Frame from './Frame';
2
+ import QuantityMargin from './QuantityMargin';
3
+ import generateFrameConfig from './helpers/generateFrameConfig';
4
+ export default class FlexibleCalculator {
5
+ constructor() {
6
+ this._MAX_POUCH_INPUT_LENGTH = 35;
7
+ this._frames = [];
8
+ this._quantityMargin = [];
9
+ }
10
+ set frames(data) {
11
+ this._frames = data.map((frame) => new Frame(frame));
12
+ }
13
+ set quantityMargins(data) {
14
+ this._quantityMargin = data.map((marginPerQty) => new QuantityMargin(marginPerQty));
15
+ }
16
+ calculatePouch(pouchInput) {
17
+ let result;
18
+ const frame = this._frames.find((frame) => {
19
+ return (frame.material === pouchInput.material &&
20
+ frame.model === pouchInput.model);
21
+ });
22
+ if (!frame)
23
+ throw Error(`Frame '${pouchInput.material}' not found in frames.`);
24
+ if (pouchInput.model === 'Standing Pouch' ||
25
+ pouchInput.model === 'Layflat Pouch' ||
26
+ pouchInput.model === 'Gusset') {
27
+ if (pouchInput.height > this._MAX_POUCH_INPUT_LENGTH)
28
+ throw Error(`Maximum height is ${this._MAX_POUCH_INPUT_LENGTH}.`);
29
+ }
30
+ if (pouchInput.model === 'Center Seal') {
31
+ if (pouchInput.length > this._MAX_POUCH_INPUT_LENGTH)
32
+ throw Error(`Maximum length is ${this._MAX_POUCH_INPUT_LENGTH}.`);
33
+ }
34
+ const frameConfig = generateFrameConfig(pouchInput, frame);
35
+ return frameConfig;
36
+ }
37
+ calculate(pouchInput) {
38
+ const result = this.calculatePouch(pouchInput);
39
+ return result;
40
+ }
41
+ }
@@ -0,0 +1,8 @@
1
+ import FrameData from './types/data/Frame';
2
+ export default class Frame {
3
+ readonly material: string;
4
+ readonly model: string;
5
+ readonly price: number;
6
+ readonly discount: number;
7
+ constructor({ material, model, price, discount }: FrameData);
8
+ }
package/dist/Frame.js ADDED
@@ -0,0 +1,8 @@
1
+ export default class Frame {
2
+ constructor({ material, model, price, discount }) {
3
+ this.material = material;
4
+ this.model = model;
5
+ this.price = price;
6
+ this.discount = discount;
7
+ }
8
+ }
@@ -0,0 +1,7 @@
1
+ import MarginData from './types/data/QuantityMargin';
2
+ export default class QuantityMargin {
3
+ readonly min: number;
4
+ readonly max: number;
5
+ readonly qty: number;
6
+ constructor({ min, max, qty }: MarginData);
7
+ }
@@ -0,0 +1,7 @@
1
+ export default class QuantityMargin {
2
+ constructor({ min, max, qty }) {
3
+ this.min = min;
4
+ this.max = max;
5
+ this.qty = qty;
6
+ }
7
+ }
@@ -0,0 +1,4 @@
1
+ import FrameCalculation from '../types/calculations/Frame';
2
+ import PouchInput from '../types/inputs/Pouch';
3
+ import Frame from '../Frame';
4
+ export default function calculateFrameCost(pouch: PouchInput, frame: Frame): FrameCalculation;
@@ -0,0 +1,44 @@
1
+ export default function calculateFrameCost(pouch, frame) {
2
+ const pricePerFrame = frame.price;
3
+ const discount = frame.discount;
4
+ const quantity = pouch.quantity;
5
+ const inputtedModel = pouch.model;
6
+ const inputtedHeight = pouch.height;
7
+ const inputtedLength = pouch.length;
8
+ const inputtedWidth = pouch.width;
9
+ const inputtedFin = pouch.fin;
10
+ const productSize = {
11
+ length: inputtedLength,
12
+ height: inputtedHeight,
13
+ };
14
+ const finalPricePerFrame = pricePerFrame - pricePerFrame * discount;
15
+ let upsPerFrame = 0;
16
+ if (inputtedModel === 'Standing Pouch' || inputtedModel === 'Layflat Pouch') {
17
+ upsPerFrame =
18
+ Math.floor(74 / (inputtedHeight * 2)) * Math.floor(110 / inputtedLength);
19
+ }
20
+ else if (inputtedModel === 'Center Seal' && inputtedFin) {
21
+ upsPerFrame =
22
+ Math.floor(74 / ((inputtedLength + inputtedFin) * 2)) *
23
+ Math.floor(110 / inputtedHeight);
24
+ }
25
+ else if (inputtedModel === 'Gusset' && inputtedFin && inputtedWidth) {
26
+ upsPerFrame =
27
+ Math.floor(74 / ((inputtedLength + inputtedWidth + inputtedFin) * 2)) *
28
+ Math.floor(110 / (inputtedHeight + inputtedFin));
29
+ productSize['width'] = inputtedWidth;
30
+ }
31
+ const productPricePerPcs = finalPricePerFrame / upsPerFrame;
32
+ const cost = {
33
+ formula: '(finalPricePerFrame / upsPerFrame) * quantity',
34
+ value: productPricePerPcs * quantity,
35
+ };
36
+ return {
37
+ upsPerFrame,
38
+ pricePerFrame,
39
+ finalPricePerFrame,
40
+ productPricePerPcs,
41
+ productSize,
42
+ cost,
43
+ };
44
+ }
@@ -0,0 +1,11 @@
1
+ import Frame from '../Frame';
2
+ import FrameCalculation from '../types/calculations/Frame';
3
+ import PouchInput from '../types/inputs/Pouch';
4
+ export default class FrameConfig {
5
+ readonly frame: Frame;
6
+ readonly quantity: number;
7
+ readonly _totalCost: number;
8
+ readonly _totalUnitCost: number;
9
+ readonly frameCalculation: FrameCalculation;
10
+ constructor(frame: Frame, quantity: number, pouchInput: PouchInput);
11
+ }
@@ -0,0 +1,11 @@
1
+ import calculateFrameCost from '../calculations/frames';
2
+ export default class FrameConfig {
3
+ constructor(frame, quantity, pouchInput) {
4
+ // this.frameCalculation = calculateFrameCost();
5
+ this.frame = frame;
6
+ this.quantity = quantity;
7
+ this.frameCalculation = calculateFrameCost(pouchInput, frame);
8
+ this._totalCost = this.frameCalculation.cost.value;
9
+ this._totalUnitCost = this.frameCalculation.productPricePerPcs;
10
+ }
11
+ }
@@ -0,0 +1,4 @@
1
+ import PouchInput from '../types/inputs/Pouch';
2
+ import FrameConfig from '../configs/Frame';
3
+ import Frame from '../Frame';
4
+ export default function generateFrameConfig(pouchInput: PouchInput, frame: Frame): FrameConfig;
@@ -0,0 +1,5 @@
1
+ import FrameConfig from '../configs/Frame';
2
+ export default function generateFrameConfig(pouchInput, frame) {
3
+ const config = new FrameConfig(frame, pouchInput.quantity, pouchInput);
4
+ return config;
5
+ }
@@ -0,0 +1,3 @@
1
+ import FlexibleCalculator from './FlexibleCalculator';
2
+ declare const _default: FlexibleCalculator;
3
+ export default _default;
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ import FlexibleCalculator from './FlexibleCalculator';
2
+ // import frames from '../src/mocks/frames';
3
+ // let fortuna = new FlexibleCalculator();
4
+ // fortuna.frames = frames;
5
+ // console.log(JSON.stringify(fortuna.frames, null, 4))
6
+ export default new FlexibleCalculator();
@@ -0,0 +1,7 @@
1
+ declare const frames: {
2
+ material: string;
3
+ model: string;
4
+ price: number;
5
+ discount: number;
6
+ }[];
7
+ export default frames;
@@ -0,0 +1,187 @@
1
+ // const docs = {
2
+ // discount:
3
+ // frames:[]
4
+ // }
5
+ const frames = [
6
+ {
7
+ material: 'BOPP.Clear20/LLDPE60-90 (TRANS)',
8
+ model: 'Standing Pouch',
9
+ price: 21000,
10
+ discount: 0.2,
11
+ },
12
+ {
13
+ material: 'BOPP.Clear20/LLDPE60-90 (TRANS)',
14
+ model: 'Layflat Pouch',
15
+ price: 20600,
16
+ discount: 0.2,
17
+ },
18
+ {
19
+ material: 'BOPP.Clear20/LLDPE60-90 (TRANS)',
20
+ model: 'Center Seal',
21
+ price: 20600,
22
+ discount: 0.2,
23
+ },
24
+ {
25
+ material: 'BOPP.Clear20/LLDPE60-90 (TRANS)',
26
+ model: 'Gusset',
27
+ price: 20600,
28
+ discount: 0.2,
29
+ },
30
+ {
31
+ material: 'BOPP.Doff20/LLDPE60-90 (TRANS)',
32
+ model: 'Standing Pouch',
33
+ price: 21000,
34
+ discount: 0.2,
35
+ },
36
+ {
37
+ material: 'BOPP.Doff20/LLDPE60-90 (TRANS)',
38
+ model: 'Layflat Pouch',
39
+ price: 20600,
40
+ discount: 0.2,
41
+ },
42
+ {
43
+ material: 'BOPP.Doff20/LLDPE60-90 (TRANS)',
44
+ model: 'Center Seal',
45
+ price: 20600,
46
+ discount: 0.2,
47
+ },
48
+ {
49
+ material: 'BOPP.Doff20/LLDPE60-90 (TRANS)',
50
+ model: 'Gusset',
51
+ price: 20600,
52
+ discount: 0.2,
53
+ },
54
+ {
55
+ material: 'NYLON15/LLDPE60-90 (TRANS)',
56
+ model: 'Standing Pouch',
57
+ price: 21000,
58
+ discount: 0.2,
59
+ },
60
+ {
61
+ material: 'NYLON15/LLDPE60-90 (TRANS)',
62
+ model: 'Layflat Pouch',
63
+ price: 21000,
64
+ discount: 0.2,
65
+ },
66
+ {
67
+ material: 'NYLON15/LLDPE60-90 (TRANS)',
68
+ model: 'Center Seal',
69
+ price: 20600,
70
+ discount: 0.2,
71
+ },
72
+ {
73
+ material: 'NYLON15/LLDPE60-90 (TRANS)',
74
+ model: 'Gusset',
75
+ price: 20600,
76
+ discount: 0.2,
77
+ },
78
+ {
79
+ material: 'BOPP.Clear20/VMPET12/LLDPE60-90 (MET)',
80
+ model: 'Standing Pouch',
81
+ price: 22968.75,
82
+ discount: 0.2,
83
+ },
84
+ {
85
+ material: 'BOPP.Clear20/VMPET12/LLDPE60-90 (MET)',
86
+ model: 'Layflat Pouch',
87
+ price: 22531.25,
88
+ discount: 0.2,
89
+ },
90
+ {
91
+ material: 'BOPP.Clear20/VMPET12/LLDPE60-90 (MET)',
92
+ model: 'Center Seal',
93
+ price: 22531.25,
94
+ discount: 0.2,
95
+ },
96
+ {
97
+ material: 'BOPP.Clear20/VMPET12/LLDPE60-90 (MET)',
98
+ model: 'Gusset',
99
+ price: 22531.25,
100
+ discount: 0.2,
101
+ },
102
+ {
103
+ material: 'BOPP.Doff20/VMPET12/LLDPE60-90 (MET)',
104
+ model: 'Standing Pouch',
105
+ price: 22968.75,
106
+ discount: 0.2,
107
+ },
108
+ {
109
+ material: 'BOPP.Doff20/VMPET12/LLDPE60-90 (MET)',
110
+ model: 'Layflat Pouch',
111
+ price: 22531.25,
112
+ discount: 0.2,
113
+ },
114
+ {
115
+ material: 'BOPP.Doff20/VMPET12/LLDPE60-90 (MET)',
116
+ model: 'Center Seal',
117
+ price: 22531.25,
118
+ discount: 0.2,
119
+ },
120
+ {
121
+ material: 'BOPP.Doff20/VMPET12/LLDPE60-90 (MET)',
122
+ model: 'Gusset',
123
+ price: 22531.25,
124
+ discount: 0.2,
125
+ },
126
+ {
127
+ material: 'BOPP.Clear20/ALU7/LLDPE60-90 (ALU)',
128
+ model: 'Standing Pouch',
129
+ price: 24937.5,
130
+ discount: 0.2,
131
+ },
132
+ {
133
+ material: 'BOPP.Clear20/ALU7/LLDPE60-90 (ALU)',
134
+ model: 'Layflat Pouch',
135
+ price: 224462.5,
136
+ discount: 0.2,
137
+ },
138
+ {
139
+ material: 'BOPP.Clear20/ALU7/LLDPE60-90 (ALU)',
140
+ model: 'Center Seal',
141
+ price: 24462.5,
142
+ discount: 0.2,
143
+ },
144
+ {
145
+ material: 'BOPP.Clear20/ALU7/LLDPE60-90 (ALU)',
146
+ model: 'Gusset',
147
+ price: 24462.5,
148
+ discount: 0.2,
149
+ },
150
+ {
151
+ material: 'BOPP.Doff20/ALU7/LLDPE60-90 (ALU)',
152
+ model: 'Standing Pouch',
153
+ price: 24937.5,
154
+ discount: 0.2,
155
+ },
156
+ {
157
+ material: 'BOPP.Doff20/ALU7/LLDPE60-90 (ALU)',
158
+ model: 'Layflat Pouch',
159
+ price: 224462.5,
160
+ discount: 0.2,
161
+ },
162
+ {
163
+ material: 'BOPP.Doff20/ALU7/LLDPE60-90 (ALU)',
164
+ model: 'Center Seal',
165
+ price: 24462.5,
166
+ discount: 0.2,
167
+ },
168
+ {
169
+ material: 'BOPP.Doff20/ALU7/LLDPE60-90 (ALU)',
170
+ model: 'Gusset',
171
+ price: 24462.5,
172
+ discount: 0.2,
173
+ },
174
+ {
175
+ material: 'BOPPClear20/Nylon15/LLDPE120',
176
+ model: 'Standing Pouch',
177
+ price: 30000,
178
+ discount: 0,
179
+ },
180
+ {
181
+ material: 'BOPPDoff20/Nylon15/LLDPE120',
182
+ model: 'Standing Pouch',
183
+ price: 30000,
184
+ discount: 0,
185
+ },
186
+ ];
187
+ export default frames;
@@ -0,0 +1,15 @@
1
+ export default interface FrameCalculation {
2
+ upsPerFrame: number;
3
+ pricePerFrame: number;
4
+ finalPricePerFrame: number;
5
+ productPricePerPcs: number;
6
+ productSize: {
7
+ length: number;
8
+ width?: number;
9
+ height: number;
10
+ };
11
+ cost: {
12
+ formula: string;
13
+ value: number;
14
+ };
15
+ }
File without changes
@@ -0,0 +1,6 @@
1
+ export default interface FrameData {
2
+ material: string;
3
+ model: string;
4
+ price: number;
5
+ discount: number;
6
+ }
File without changes
@@ -0,0 +1,5 @@
1
+ export default interface MarginData {
2
+ qty: number;
3
+ min: number;
4
+ max: number;
5
+ }
File without changes
@@ -0,0 +1,10 @@
1
+ export default interface PouchInput {
2
+ length: number;
3
+ width?: number;
4
+ height: number;
5
+ model: string;
6
+ material: string;
7
+ fin?: number;
8
+ quantity: number;
9
+ margin: number;
10
+ }
File without changes
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@tjetak/fortuna",
3
+ "version": "1.0.0-alpha.1",
4
+ "description": "The flexible printing calculator",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "test": "jest",
9
+ "build": "tsc",
10
+ "format": "prettier --write \"src/**/*.ts\" \"src/**/*.js\"",
11
+ "lint": "eslint src --ext .js,.ts --fix",
12
+ "prepare": "npm run build && npm run build-rollup",
13
+ "prepublishOnly": "npm test && npm run lint",
14
+ "preversion": "npm run lint",
15
+ "version": "npm run format && git add -A src",
16
+ "postversion": "git push && git push --tags",
17
+ "release": "standard-version",
18
+ "build-rollup": "rollup -c"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+ssh://git@gitlab.com/tjetak/fortuna.git"
23
+ },
24
+ "author": "Hasandi Patriawan",
25
+ "license": "ISC",
26
+ "bugs": {
27
+ "url": "https://gitlab.com/tjetak/fortuna/issues"
28
+ },
29
+ "homepage": "https://gitlab.com/tjetak/fortuna#readme",
30
+ "devDependencies": {
31
+ "@babel/core": "^7.11.6",
32
+ "@babel/preset-env": "^7.11.5",
33
+ "@types/jest": "^26.0.14",
34
+ "@types/lodash-es": "^4.17.3",
35
+ "@typescript-eslint/eslint-plugin": "^3.10.1",
36
+ "@typescript-eslint/parser": "^3.10.1",
37
+ "babel-jest": "^26.5.2",
38
+ "cz-conventional-changelog": "^3.3.0",
39
+ "eslint": "^7.10.0",
40
+ "eslint-config-prettier": "^6.12.0",
41
+ "eslint-plugin-prettier": "^3.1.4",
42
+ "jest": "^26.5.2",
43
+ "prettier": "^2.1.2",
44
+ "standard-version": "^9.0.0",
45
+ "ts-jest": "^26.4.1",
46
+ "typescript": "^3.9.7"
47
+ },
48
+ "config": {
49
+ "commitizen": {
50
+ "path": "./node_modules/cz-conventional-changelog"
51
+ }
52
+ },
53
+ "dependencies": {
54
+ "@ampproject/rollup-plugin-closure-compiler": "^0.26.0",
55
+ "@rollup/plugin-node-resolve": "^8.4.0",
56
+ "avl": "^1.4.4",
57
+ "greedy-rect-packer": "^1.0.7",
58
+ "lodash-es": "^4.17.15",
59
+ "rollup": "^2.23.0"
60
+ },
61
+ "files": [
62
+ "dist/**/*",
63
+ "build/**/*"
64
+ ],
65
+ "directories": {
66
+ "test": "tests"
67
+ }
68
+ }