things might be working
This commit is contained in:
@@ -439,5 +439,14 @@
|
||||
"servingUnit": "mg",
|
||||
"numUnitsInServing": 134,
|
||||
"numBottles": 1
|
||||
},
|
||||
{
|
||||
"name": "DHEA",
|
||||
"quantity": 90,
|
||||
"numUnitsInServing": 25,
|
||||
"servingUnit": "mg",
|
||||
"quantityUnit": "caps",
|
||||
"orderDate": "2024-02-03",
|
||||
"numBottles": 1
|
||||
}
|
||||
]
|
||||
|
||||
206
poetry.lock
generated
206
poetry.lock
generated
@@ -1,5 +1,60 @@
|
||||
# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "astroid"
|
||||
version = "3.0.2"
|
||||
description = "An abstract syntax tree for Python with inference support."
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "astroid-3.0.2-py3-none-any.whl", hash = "sha256:d6e62862355f60e716164082d6b4b041d38e2a8cf1c7cd953ded5108bac8ff5c"},
|
||||
{file = "astroid-3.0.2.tar.gz", hash = "sha256:4a61cf0a59097c7bb52689b0fd63717cd2a8a14dc9f1eee97b82d814881c8c91"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "black"
|
||||
version = "24.1.1"
|
||||
description = "The uncompromising code formatter."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "black-24.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2588021038bd5ada078de606f2a804cadd0a3cc6a79cb3e9bb3a8bf581325a4c"},
|
||||
{file = "black-24.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a95915c98d6e32ca43809d46d932e2abc5f1f7d582ffbe65a5b4d1588af7445"},
|
||||
{file = "black-24.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa6a0e965779c8f2afb286f9ef798df770ba2b6cee063c650b96adec22c056a"},
|
||||
{file = "black-24.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5242ecd9e990aeb995b6d03dc3b2d112d4a78f2083e5a8e86d566340ae80fec4"},
|
||||
{file = "black-24.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc1ec9aa6f4d98d022101e015261c056ddebe3da6a8ccfc2c792cbe0349d48b7"},
|
||||
{file = "black-24.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0269dfdea12442022e88043d2910429bed717b2d04523867a85dacce535916b8"},
|
||||
{file = "black-24.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3d64db762eae4a5ce04b6e3dd745dcca0fb9560eb931a5be97472e38652a161"},
|
||||
{file = "black-24.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5d7b06ea8816cbd4becfe5f70accae953c53c0e53aa98730ceccb0395520ee5d"},
|
||||
{file = "black-24.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e2c8dfa14677f90d976f68e0c923947ae68fa3961d61ee30976c388adc0b02c8"},
|
||||
{file = "black-24.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a21725862d0e855ae05da1dd25e3825ed712eaaccef6b03017fe0853a01aa45e"},
|
||||
{file = "black-24.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07204d078e25327aad9ed2c64790d681238686bce254c910de640c7cc4fc3aa6"},
|
||||
{file = "black-24.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a83fe522d9698d8f9a101b860b1ee154c1d25f8a82ceb807d319f085b2627c5b"},
|
||||
{file = "black-24.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08b34e85170d368c37ca7bf81cf67ac863c9d1963b2c1780c39102187ec8dd62"},
|
||||
{file = "black-24.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7258c27115c1e3b5de9ac6c4f9957e3ee2c02c0b39222a24dc7aa03ba0e986f5"},
|
||||
{file = "black-24.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40657e1b78212d582a0edecafef133cf1dd02e6677f539b669db4746150d38f6"},
|
||||
{file = "black-24.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e298d588744efda02379521a19639ebcd314fba7a49be22136204d7ed1782717"},
|
||||
{file = "black-24.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:34afe9da5056aa123b8bfda1664bfe6fb4e9c6f311d8e4a6eb089da9a9173bf9"},
|
||||
{file = "black-24.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:854c06fb86fd854140f37fb24dbf10621f5dab9e3b0c29a690ba595e3d543024"},
|
||||
{file = "black-24.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3897ae5a21ca132efa219c029cce5e6bfc9c3d34ed7e892113d199c0b1b444a2"},
|
||||
{file = "black-24.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:ecba2a15dfb2d97105be74bbfe5128bc5e9fa8477d8c46766505c1dda5883aac"},
|
||||
{file = "black-24.1.1-py3-none-any.whl", hash = "sha256:5cdc2e2195212208fbcae579b931407c1fa9997584f0a415421748aeafff1168"},
|
||||
{file = "black-24.1.1.tar.gz", hash = "sha256:48b5760dcbfe5cf97fd4fba23946681f3a81514c6ab8a45b50da67ac8fbc6c7b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
click = ">=8.0.0"
|
||||
mypy-extensions = ">=0.4.3"
|
||||
packaging = ">=22.0"
|
||||
pathspec = ">=0.9.0"
|
||||
platformdirs = ">=2"
|
||||
|
||||
[package.extras]
|
||||
colorama = ["colorama (>=0.4.3)"]
|
||||
d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"]
|
||||
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
|
||||
uvloop = ["uvloop (>=0.15.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.7"
|
||||
@@ -25,6 +80,35 @@ files = [
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dill"
|
||||
version = "0.3.8"
|
||||
description = "serialize all of Python"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"},
|
||||
{file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
graph = ["objgraph (>=1.7.2)"]
|
||||
profile = ["gprof2dot (>=2022.7.29)"]
|
||||
|
||||
[[package]]
|
||||
name = "isort"
|
||||
version = "5.13.2"
|
||||
description = "A Python utility / library to sort Python imports."
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"},
|
||||
{file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
colors = ["colorama (>=0.4.6)"]
|
||||
|
||||
[[package]]
|
||||
name = "markdown-it-py"
|
||||
version = "3.0.0"
|
||||
@@ -49,6 +133,17 @@ profiling = ["gprof2dot"]
|
||||
rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"]
|
||||
testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"]
|
||||
|
||||
[[package]]
|
||||
name = "mccabe"
|
||||
version = "0.7.0"
|
||||
description = "McCabe checker, plugin for flake8"
|
||||
optional = false
|
||||
python-versions = ">=3.6"
|
||||
files = [
|
||||
{file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
|
||||
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mdurl"
|
||||
version = "0.1.2"
|
||||
@@ -60,6 +155,54 @@ files = [
|
||||
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mypy-extensions"
|
||||
version = "1.0.0"
|
||||
description = "Type system extensions for programs checked with the mypy type checker."
|
||||
optional = false
|
||||
python-versions = ">=3.5"
|
||||
files = [
|
||||
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
|
||||
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "23.2"
|
||||
description = "Core utilities for Python packages"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
|
||||
{file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathspec"
|
||||
version = "0.12.1"
|
||||
description = "Utility library for gitignore style pattern matching of file paths."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
|
||||
{file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "platformdirs"
|
||||
version = "4.2.0"
|
||||
description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = [
|
||||
{file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"},
|
||||
{file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"]
|
||||
test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.17.2"
|
||||
@@ -75,6 +218,30 @@ files = [
|
||||
plugins = ["importlib-metadata"]
|
||||
windows-terminal = ["colorama (>=0.4.6)"]
|
||||
|
||||
[[package]]
|
||||
name = "pylint"
|
||||
version = "3.0.3"
|
||||
description = "python code static checker"
|
||||
optional = false
|
||||
python-versions = ">=3.8.0"
|
||||
files = [
|
||||
{file = "pylint-3.0.3-py3-none-any.whl", hash = "sha256:7a1585285aefc5165db81083c3e06363a27448f6b467b3b0f30dbd0ac1f73810"},
|
||||
{file = "pylint-3.0.3.tar.gz", hash = "sha256:58c2398b0301e049609a8429789ec6edf3aabe9b6c5fec916acd18639c16de8b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
astroid = ">=3.0.1,<=3.1.0-dev0"
|
||||
colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""}
|
||||
dill = {version = ">=0.3.7", markers = "python_version >= \"3.12\""}
|
||||
isort = ">=4.2.5,<5.13.0 || >5.13.0,<6"
|
||||
mccabe = ">=0.6,<0.8"
|
||||
platformdirs = ">=2.2.0"
|
||||
tomlkit = ">=0.10.1"
|
||||
|
||||
[package.extras]
|
||||
spelling = ["pyenchant (>=3.2,<4.0)"]
|
||||
testutils = ["gitpython (>3)"]
|
||||
|
||||
[[package]]
|
||||
name = "rich"
|
||||
version = "13.7.0"
|
||||
@@ -93,6 +260,32 @@ pygments = ">=2.13.0,<3.0.0"
|
||||
[package.extras]
|
||||
jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.2.0"
|
||||
description = "An extremely fast Python linter and code formatter, written in Rust."
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:638ea3294f800d18bae84a492cb5a245c8d29c90d19a91d8e338937a4c27fca0"},
|
||||
{file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3ff35433fcf4dff6d610738712152df6b7d92351a1bde8e00bd405b08b3d5759"},
|
||||
{file = "ruff-0.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9faafbdcf4f53917019f2c230766da437d4fd5caecd12ddb68bb6a17d74399"},
|
||||
{file = "ruff-0.2.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8153a3e4128ed770871c47545f1ae7b055023e0c222ff72a759f5a341ee06483"},
|
||||
{file = "ruff-0.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a75a98ae989a27090e9c51f763990ad5bbc92d20626d54e9701c7fe597f399"},
|
||||
{file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:87057dd2fdde297130ff99553be8549ca38a2965871462a97394c22ed2dfc19d"},
|
||||
{file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d232f99d3ab00094ebaf88e0fb7a8ccacaa54cc7fa3b8993d9627a11e6aed7a"},
|
||||
{file = "ruff-0.2.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3c641f95f435fc6754b05591774a17df41648f0daf3de0d75ad3d9f099ab92"},
|
||||
{file = "ruff-0.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3826fb34c144ef1e171b323ed6ae9146ab76d109960addca730756dc19dc7b22"},
|
||||
{file = "ruff-0.2.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eceab7d85d09321b4de18b62d38710cf296cb49e98979960a59c6b9307c18cfe"},
|
||||
{file = "ruff-0.2.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:30ad74687e1f4a9ff8e513b20b82ccadb6bd796fe5697f1e417189c5cde6be3e"},
|
||||
{file = "ruff-0.2.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a7e3818698f8460bd0f8d4322bbe99db8327e9bc2c93c789d3159f5b335f47da"},
|
||||
{file = "ruff-0.2.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:edf23041242c48b0d8295214783ef543847ef29e8226d9f69bf96592dba82a83"},
|
||||
{file = "ruff-0.2.0-py3-none-win32.whl", hash = "sha256:e155147199c2714ff52385b760fe242bb99ea64b240a9ffbd6a5918eb1268843"},
|
||||
{file = "ruff-0.2.0-py3-none-win_amd64.whl", hash = "sha256:ba918e01cdd21e81b07555564f40d307b0caafa9a7a65742e98ff244f5035c59"},
|
||||
{file = "ruff-0.2.0-py3-none-win_arm64.whl", hash = "sha256:3fbaff1ba9564a2c5943f8f38bc221f04bac687cc7485e45237579fee7ccda79"},
|
||||
{file = "ruff-0.2.0.tar.gz", hash = "sha256:63856b91837606c673537d2889989733d7dffde553828d3b0f0bacfa6def54be"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.10.2"
|
||||
@@ -104,6 +297,17 @@ files = [
|
||||
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tomlkit"
|
||||
version = "0.12.3"
|
||||
description = "Style preserving TOML library"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "tomlkit-0.12.3-py3-none-any.whl", hash = "sha256:b0a645a9156dc7cb5d3a1f0d4bab66db287fcb8e0430bdd4664a095ea16414ba"},
|
||||
{file = "tomlkit-0.12.3.tar.gz", hash = "sha256:75baf5012d06501f07bee5bf8e801b9f343e7aac5a92581f20f80ce632e6b5a4"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typer"
|
||||
version = "0.9.0"
|
||||
@@ -139,4 +343,4 @@ files = [
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "4760c0a423126e044bb2d35b8bff39a0c605f92514ca863afbd72930d00fa619"
|
||||
content-hash = "4d919c3abe892130917c89f930787d3465a604a90ebd7a6b618bc2483abb5653"
|
||||
|
||||
@@ -12,6 +12,11 @@ typer = "^0.9.0"
|
||||
toml = "^0.10.2"
|
||||
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
pylint = "^3.0.3"
|
||||
ruff = "^0.2.0"
|
||||
black = "^24.1.1"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
'numUnitsInServing': 134,
|
||||
'numBottles': 2}]
|
||||
"""
|
||||
|
||||
import datetime as dt
|
||||
import json
|
||||
import math
|
||||
import toml
|
||||
from typing_extensions import Annotated
|
||||
|
||||
@@ -21,6 +23,8 @@ from sup.main import (
|
||||
SUPP_CONSUMPTION_FP,
|
||||
load_inventory,
|
||||
Supp,
|
||||
CONFIG,
|
||||
ALIASES_REV,
|
||||
)
|
||||
|
||||
app = typer.Typer()
|
||||
@@ -30,17 +34,24 @@ class UnitMismatch(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def get_qty_inventory(supp: Supp, inventory: dict) -> int:
|
||||
class Missing(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def get_qty_inventory(supp: Supp, inventory: dict, next_fill_date: dt.date) -> int:
|
||||
inventory_order_date = dt.datetime.strptime(
|
||||
inventory["orderDate"][:10], "%Y-%m-%d"
|
||||
).date()
|
||||
num_days_since_bought = (dt.date.today() - inventory_order_date).days
|
||||
num_days_since_bought = (next_fill_date - inventory_order_date).days
|
||||
if inventory["servingUnit"] != supp.units:
|
||||
raise UnitMismatch(inventory, supp)
|
||||
|
||||
return (inventory["quantity"] * inventory["numBottles"]) - (
|
||||
supp * num_days_since_bought
|
||||
)
|
||||
inv = (
|
||||
inventory["quantity"] * inventory["numBottles"] * inventory["numUnitsInServing"]
|
||||
) - (supp * num_days_since_bought)
|
||||
if inv < 0:
|
||||
return 0
|
||||
return inv
|
||||
|
||||
|
||||
def get_num_winter_days_starting(num_days: int, starting: dt.date) -> int:
|
||||
@@ -72,38 +83,59 @@ def get_num_winter_days_starting(num_days: int, starting: dt.date) -> int:
|
||||
@app.command()
|
||||
def status():
|
||||
"""check if there's enough inventory for the next fill-up; if not, what to order?"""
|
||||
validate_matches()
|
||||
|
||||
config = load_config()
|
||||
|
||||
num_days_of_inventory_needed = config["FILL_EVERY_X_DAYS"]
|
||||
next_fill_date = config["LAST_FILL_DATE"] + dt.timedelta(
|
||||
num_days_of_inventory_needed
|
||||
)
|
||||
inventory = load_inventory()
|
||||
|
||||
needs = []
|
||||
|
||||
num_days_of_inventory_needed_winter = get_num_winter_days_starting(
|
||||
num_days_of_inventory_needed, next_fill_date
|
||||
)
|
||||
|
||||
for sup in config["supps"]:
|
||||
sup_inst = Supp(**sup)
|
||||
if sup_inst.winter_only:
|
||||
num_days_of_inventory_needed = get_num_winter_days_starting(
|
||||
num_days_of_inventory_needed, next_fill_date
|
||||
)
|
||||
qty_needed = sup_inst * num_days_of_inventory_needed
|
||||
qty_needed = sup_inst * num_days_of_inventory_needed_winter
|
||||
else:
|
||||
qty_needed = sup_inst * num_days_of_inventory_needed
|
||||
|
||||
try:
|
||||
inv = inventory[sup_inst.name]
|
||||
except KeyError:
|
||||
qty_of_inventory = 0
|
||||
else:
|
||||
qty_of_inventory = get_qty_inventory(sup_inst, inv)
|
||||
net_need = qty_needed - qty_of_inventory
|
||||
qty_of_inventory = get_qty_inventory(sup_inst, inv, next_fill_date)
|
||||
|
||||
net_need = int(qty_needed - qty_of_inventory)
|
||||
if net_need > 0:
|
||||
needs.append((sup_inst.name, net_need, sup_inst.units))
|
||||
if qty_of_inventory == 0:
|
||||
num_bottles_needed = 1
|
||||
else:
|
||||
if sup_inst.name == "magnesium slow release":
|
||||
print(f"{net_need=}")
|
||||
print(f"{inv['numUnitsInServing']=}")
|
||||
print(f"{inv['quantity']=}")
|
||||
num_units_needed = net_need / inv["numUnitsInServing"] # type: ignore
|
||||
num_bottles_needed = int(math.ceil(num_units_needed / inv["quantity"])) # type: ignore
|
||||
needs.append((sup_inst.name, int(num_units_needed), num_bottles_needed))
|
||||
if needs:
|
||||
print(f"The next fill-up is on {next_fill_date}, and you won't have enough of:")
|
||||
for name, quant, units in needs:
|
||||
print(f"{name} (need {quant} {units})")
|
||||
for name, units_needed, num_bottles in needs:
|
||||
bottle = "bottle" if num_bottles == 1 else "bottles"
|
||||
print(f"{name} (need {units_needed} units, which is {num_bottles} {bottle})")
|
||||
|
||||
|
||||
@app.command()
|
||||
def fill():
|
||||
"""reset 'next fill' clock"""
|
||||
validate_matches()
|
||||
config = load_config()
|
||||
today = dt.date.today()
|
||||
config["LAST_FILL_DATE"] = today.strftime("%Y-%m-%d")
|
||||
@@ -123,8 +155,9 @@ def add(
|
||||
serving_quantity: Annotated[int, typer.Option(prompt=True)],
|
||||
serving_unit: Annotated[str, typer.Option(prompt=True)] = "mg",
|
||||
quantity_unit: Annotated[str, typer.Option(prompt=True)] = "caps",
|
||||
date: Annotated[dt.datetime, typer.Option(help="(today)", prompt=True)]
|
||||
| None = None,
|
||||
date: (
|
||||
Annotated[dt.datetime, typer.Option(help="(today)", prompt=True)] | None
|
||||
) = None,
|
||||
number_of_bottles: Annotated[int, typer.Option(prompt=True)] = 1,
|
||||
) -> None:
|
||||
"""add to inventory"""
|
||||
@@ -153,3 +186,21 @@ def save_ordered_supps(ordered_supps: list[dict]) -> None:
|
||||
|
||||
def save_config(config: dict) -> None:
|
||||
SUPP_CONSUMPTION_FP.write_text(toml.dumps(config))
|
||||
|
||||
|
||||
def validate_matches() -> None:
|
||||
missing = []
|
||||
|
||||
ordered_supp_names_lower = [i["name"].lower() for i in load_ordered_supps()]
|
||||
for i in CONFIG["supps"]:
|
||||
if (
|
||||
not any(
|
||||
i["name"].lower() in ordered_supp_name
|
||||
for ordered_supp_name in ordered_supp_names_lower
|
||||
)
|
||||
and i["name"].lower() not in ALIASES_REV
|
||||
):
|
||||
missing.append(i["name"])
|
||||
|
||||
if missing:
|
||||
raise Missing(", ".join(missing))
|
||||
|
||||
@@ -3,6 +3,7 @@ TODO:
|
||||
special case: Liquid D-3 & MK-7 -- has d-3 and k-mk7
|
||||
special case: K Complex has K1, MK-4 and MK-7 in it
|
||||
"""
|
||||
|
||||
from dataclasses import dataclass
|
||||
import json
|
||||
import pathlib as pl
|
||||
@@ -43,28 +44,6 @@ def load_inventory():
|
||||
}
|
||||
|
||||
|
||||
class Missing(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def validate_matches() -> None:
|
||||
missing = []
|
||||
|
||||
ordered_supp_names_lower = [i["name"].lower() for i in load_ordered_supps()]
|
||||
for i in CONFIG["supps"]:
|
||||
if (
|
||||
not any(
|
||||
i["name"].lower() in ordered_supp_name
|
||||
for ordered_supp_name in ordered_supp_names_lower
|
||||
)
|
||||
and i["name"].lower() not in ALIASES_REV
|
||||
):
|
||||
missing.append(i["name"])
|
||||
|
||||
if missing:
|
||||
raise Missing(", ".join(missing))
|
||||
|
||||
|
||||
@dataclass
|
||||
class Supp:
|
||||
name: str
|
||||
@@ -86,13 +65,3 @@ class Supp:
|
||||
* 7
|
||||
/ self.days_per_week
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
missing_names = validate_matches()
|
||||
if missing_names:
|
||||
print(missing_names)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user