Skip to content
This repository has been archived by the owner on Jul 25, 2023. It is now read-only.

feat(#386): Add inventory management #538

Draft
wants to merge 31 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
98304d8
feat(#386): Add infrastructure for creating view design documents
timo-reymann Dec 9, 2022
8a6ef68
feat(#386): Add units data model
timo-reymann Dec 26, 2022
e5af037
feat(#386): Add inventory change data model
timo-reymann Dec 26, 2022
ef94ebe
chore: Fix code smell with unit spec test
timo-reymann Dec 26, 2022
2218dcb
chore(#386): Fix circular core dependency
timo-reymann Dec 26, 2022
eca65fa
chore: Fix build
timo-reymann Dec 26, 2022
092206b
chore(deps): update eslint (#537)
renovate[bot] Dec 12, 2022
dc2ae86
fix(deps): update dependency @angular-devkit/architect to v0.1500.4 (…
renovate[bot] Dec 15, 2022
be69a29
fix(deps): update dependency rxjs to v7.8.0 (#541)
renovate[bot] Dec 16, 2022
e12622c
fix(deps): update pouchdb monorepo to v8 (#540)
renovate[bot] Dec 16, 2022
b079a35
chore(deps): update dependency eslint to v8.30.0 (#542)
renovate[bot] Dec 17, 2022
9a3d9e7
Update Node.js to v18.12.1 (#543)
renovate[bot] Dec 19, 2022
5af61a8
Update dependency zone.js to v0.12.0 (#545)
renovate[bot] Dec 19, 2022
40483e6
chore: Pin to node 18
timo-reymann Dec 25, 2022
4294049
ci: Add sudo to npm i global
timo-reymann Dec 25, 2022
ac5d2bc
ci: Add sudo for generation report
timo-reymann Dec 25, 2022
a54cd7b
ci: Downgrade node image to work around permissions problems
timo-reymann Dec 25, 2022
1c2a02e
ci: Add npm global config
timo-reymann Dec 25, 2022
e997b3e
chore(deps): update eslint to v5.47.1 (#550)
renovate[bot] Dec 26, 2022
7b95373
chore: Add build translations package for report
timo-reymann Dec 27, 2022
70d2622
fix: Fix test for load spec
timo-reymann Dec 27, 2022
37206cb
chore: Fix generation of translation report
timo-reymann Dec 27, 2022
8558cee
fix: Fix unit load test
timo-reymann Dec 27, 2022
51f7d7e
chore: Cleanup translation report script
timo-reymann Dec 27, 2022
c9a9ebc
chore: Fix dir switch for translation report
timo-reymann Dec 27, 2022
1f9f574
chore: Change PWD before script start
timo-reymann Dec 27, 2022
1b0e1a6
chore: Switch to project root for translation report
timo-reymann Dec 27, 2022
78ffb97
chore: Harden generate translation report script
timo-reymann Dec 27, 2022
06f8fca
feat(#386): Add inventory view
timo-reymann Jan 7, 2023
da03e9c
feat(#386): Add empty unit translation
timo-reymann Jan 7, 2023
6d522e0
chore: Cleanup sonarcloud code smells
timo-reymann Jan 7, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ jobs:
- run:
name: Run translation report script
command: |
mkdir ~/.npm-global
npm config set prefix '~/.npm-global'
export PATH=~/.npm-global/bin:$PATH
npm install -g typescript
npm run generate-translation-report
- store_artifacts:
Expand Down
45 changes: 23 additions & 22 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,29 @@
"@typescript-eslint/member-ordering": [
"error",
{
"default": [
"private-field",
"protected-field",
"public-field",
"public-constructor",
"protected-constructor",
"private-constructor",
"signature",
"method",
"private-static-method",
"private-decorated-method",
"private-instance-method",
"private-abstract-method",
"protected-static-method",
"protected-instance-method",
"protected-abstract-method",
"protected-decorated-method",
"public-static-method",
"public-decorated-method",
"public-instance-method",
"public-abstract-method"
]
"default": {
"memberTypes": [
"private-field",
"protected-field",
"public-field",
"public-constructor",
"protected-constructor",
"private-constructor",
"signature",
"method",
"private-static-method",
"private-decorated-method",
"private-instance-method",
"protected-static-method",
"protected-instance-method",
"protected-abstract-method",
"protected-decorated-method",
"public-static-method",
"public-decorated-method",
"public-instance-method",
"public-abstract-method"
]
}
}
],
"comma-dangle": [
Expand Down
640 changes: 306 additions & 334 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 8 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,18 @@
"@thymesave/material-food-icons": "1.0.1",
"hammerjs": "2.0.8",
"lodash": "4.17.21",
"pouchdb": "7.3.1",
"pouchdb-find": "7.3.1",
"pouchdb": "8.0.0",
"pouchdb-find": "8.0.0",
"pouchdb-upsert": "2.2.0",
"rxjs": "7.6.0",
"rxjs": "7.8.0",
"schema-dts": "1.1.0",
"string-similarity": "4.0.4",
"tslib": "2.4.1",
"uuid": "9.0.0",
"zone.js": "0.11.8"
"zone.js": "0.12.0"
},
"devDependencies": {
"@angular-devkit/architect": "0.1500.3",
"@angular-devkit/architect": "0.1500.4",
"@angular-devkit/build-angular": "14.2.10",
"@angular-eslint/builder": "14.4.0",
"@angular-eslint/eslint-plugin": "14.4.0",
Expand All @@ -64,9 +64,9 @@
"@types/pouchdb-upsert": "2.2.6",
"@types/string-similarity": "4.0.0",
"@types/uuid": "9.0.0",
"@typescript-eslint/eslint-plugin": "5.44.0",
"@typescript-eslint/parser": "5.44.0",
"eslint": "8.28.0",
"@typescript-eslint/eslint-plugin": "5.47.1",
"@typescript-eslint/parser": "5.47.1",
"eslint": "8.30.0",
"eslint-plugin-decorator-position": "5.0.1",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-sort-keys-fix": "1.1.2",
Expand Down
23 changes: 23 additions & 0 deletions projects/thymesave/core/src/lib/models/inventory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { UnitIdentifier } from "./unit";

/**
* Represent a change to the inventory. There are two changes that can occure:
* - adding an ingredient to the inventory (amount is positive)
* - removing an ingredient from the inventory (amount is negative)
*
* The final amount depends on the inventory change aggregated
*/
export interface InventoryChange {
/**
* Technical key for the ingredient to change the stock for
*/
ingredientKey: string
/**
* Amount that was added/removed
*/
amount: number
/**
* Unit related to the change
*/
unit : UnitIdentifier
}
28 changes: 28 additions & 0 deletions projects/thymesave/core/src/lib/models/unit.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { calculateUtilization, convertAmount } from "./unit";

describe("convertUnit", () => {
it("should convert successfully when source and target are there", () => {
expect(convertAmount(1, "kilogram", "gram")).toBe(1_000);
expect(convertAmount(1, "cup", "gram")).toBe(125);
});
it("should return null if no mapping is found", () => {
expect(convertAmount(10, "pack", "gram")).toBe(null);
});
it("should work with conversion between units", () => {
expect(convertAmount(1, "tbsp", "gram")).toBe(10);
});
});

describe("calculateUtilization", () => {
it("should work with same weight unit", () => {
expect(calculateUtilization(1, "kilogram", 100, "gram")).toBe(0.1);
expect(calculateUtilization(1, "kilogram", 0, "gram")).toBe(0);
expect(calculateUtilization(1, "kilogram",1000, "gram")).toBe(1);
});

it("should work with different weight unit", () => {
expect(calculateUtilization(1, "tbsp", 100, "gram")).toBe(1);
expect(calculateUtilization(1, "tbsp", 3, "gram")).toBe(0.3);
expect(calculateUtilization(1, "kilogram", 1000, "gram")).toBe(1);
});
});
196 changes: 196 additions & 0 deletions projects/thymesave/core/src/lib/models/unit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
export type UnitIdentifier =
"" |
"cup" |
"deciliter" |
"gram" |
"jar" |
"kilogram" |
"liter" |
"milligram" |
"milliliter" |
"ounce" |
"pack" |
"pinch" |
"pound" |
"tsp" |
"tbsp" |
"twig";

export interface UnitReplacementFactor {
generic: string
}

/**
* Try to convert the amount from the given unit to the target unit, in case the conversion is not supported null is returned
*
* @param amount Amount to convert
* @param sourceUnit Source unit
* @param targetUnit Target unit to be converted to
*/
export const convertAmount = (amount: number, sourceUnit: UnitIdentifier, targetUnit: UnitIdentifier) => {
const conversionFactor = unitConversionFactor[sourceUnit].conversions[targetUnit];
return conversionFactor ? amount * conversionFactor : null;
};

/**
* Calculates the utilization.
*
* Return values:
*
* => -1 - can not be calculated
*
* => 0 - not utilized
*
* => 1 - fully utilized
*
* => 0..1 - utilization as percentage
*
* @param fullAmount Full amount required
* @param fullAmountUnit Unit of full amount
* @param givenAmount Given amount that we have
* @param givenAmountUnit Amount of the given amount
*/
export const calculateUtilization = (fullAmount: number, fullAmountUnit: UnitIdentifier, givenAmount: number, givenAmountUnit: UnitIdentifier) => {
if (fullAmount == 0 || givenAmount == 0) {
return 0;
}

const convertedFullAmount = convertAmount(fullAmount, fullAmountUnit, givenAmountUnit) ?? -1;
if (convertedFullAmount == -1) {
return -1;
}

if (givenAmount >= convertedFullAmount) {
return 1;
}

return givenAmount / convertedFullAmount;
};

/**
* @internal
*/
export const unitConversionFactor: {
[key in UnitIdentifier]: {
estimated: boolean
conversions: { [key in UnitIdentifier]?: number }
}
} = {
"": {
conversions: {},
estimated: true,
},
cup: {
conversions: {
gram: 125,
kilogram: 0.125,
milliliter: 240,
},
estimated: false,
},
deciliter: {
conversions: {
liter: 0.1,
milliliter: 100,
},
estimated: false,
},
gram: {
conversions: {
kilogram: 0.001,
milligram: 1_000,
},
estimated: false,
},
jar: {
conversions: {
gram: 200,
milliliter: 200,
},
estimated: true,
},
kilogram: {
conversions: {
gram: 1_000,
milligram: 1_000_000,
},
estimated: false,
},
liter: {
conversions: {
deciliter: 10,
milliliter: 1_000,
},
estimated: false,
},
milligram: {
conversions: {
gram: 0.001,
kilogram: 0.00000100,
},
estimated: false,
},
milliliter: {
conversions: {
deciliter: 0.01,
liter: 0.001,
},
estimated: false,
},
ounce: {
conversions: {
gram: 28.3495,
kilogram: 0.0283495,
liter: 0.0295735,
milligram: 2_8349.5,
milliliter: 295_735_000.0000136,
},
estimated: false,
},

pack: {
conversions: {},
estimated: true,
},
pinch: {
conversions: {
gram: 0.04,
kilogram: 0.004,
milligram: 4_000,
},
estimated: false,
},
pound: {
conversions: {
gram: 453.592,
kilogram: 0.453592,
},
estimated: false,
},
tbsp: {
conversions: {
gram: 10,
kilogram: 0.01,
liter: 0.015,
milligram: 10_000,
milliliter: 15,
},
estimated: true,
},
tsp: {
conversions: {
gram: 3,
kilogram: 0.0003,
liter: 0.0005,
milligram: 3_000,
milliliter: 5,
},
estimated: true,
},
twig: {
conversions: {
gram: 30,
},
estimated: true,
},
};
2 changes: 2 additions & 0 deletions projects/thymesave/core/src/public-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export * from "./lib/models/funnel";
export * from "./lib/models/instruction";
export * from "./lib/models/ingredient";
export * from "./lib/models/shopping-list";
export * from "./lib/models/unit";
export * from "./lib/models/inventory";
export * from "./lib/apis/importer";
export * from "./lib/apis/services";
export * from "./lib/apis/context";
Expand Down
Loading