diff --git a/db_classes.py b/db_classes.py index c4062ac..c83cc20 100644 --- a/db_classes.py +++ b/db_classes.py @@ -88,7 +88,7 @@ def init(): db.create_tables([location, office, item, component, user]) print("Database initialized.") global search - print("Creating cache index... ", end='', flush=True) + print("Creating cache index...", end='', flush=True) search = ivs() add = item.select().dicts() #print(add) @@ -101,7 +101,8 @@ def init(): #print(itm) #print(type(itm)) search.add_document(itm) - print(len(add)) + print('.',end='',flush=True) + print(" " + str(len(add)), "items added.") print("Cache build complete.") def search_item(query, filters: dict={}): @@ -266,6 +267,8 @@ def change_password(username, password): def checkout(user, barcode, loc=None): itm = get_item(barcode) + if loc == False: + loc = None if itm: itm.checkout = True itm.checkout_user = user @@ -277,6 +280,8 @@ def checkout(user, barcode, loc=None): def checkin(user, barcode, loc=None): itm = get_item(barcode) + if loc == False: + loc = None if itm: itm.checkout = False itm.last_user = user diff --git a/docker-compose.yml b/docker-compose.yml index a177d9f..961a573 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,7 @@ services: meilisearch: image: "getmeili/meilisearch:v1.10.1" + restart: always ports: - "7700:7700" environment: @@ -24,6 +25,7 @@ services: inventory: build: . init: true + restart: always ports: - "8000:8000" environment: @@ -33,4 +35,4 @@ services: - database volumes: - meili_data: \ No newline at end of file + meili_data: diff --git a/inventory/__init__.py b/inventory/__init__.py index 9932e78..c8b3696 100644 --- a/inventory/__init__.py +++ b/inventory/__init__.py @@ -63,6 +63,16 @@ app = rio.App( url_segment='item', build=pages.ItemPage, ), + rio.ComponentPage( + name="CheckinPage", + url_segment='in', + build=pages.CheckinPage, + ), + rio.ComponentPage( + name="CheckoutPage", + url_segment='out', + build=pages.CheckoutPage, + ), ], # You can optionally provide a root component for the app. By default, # a simple `rio.PageView` is used. By providing your own component, you diff --git a/inventory/pages/__init__.py b/inventory/pages/__init__.py index d6384a5..4abac8f 100644 --- a/inventory/pages/__init__.py +++ b/inventory/pages/__init__.py @@ -5,4 +5,5 @@ from .add_location import AddLocationPage from .browse_page import BrowsePage from .login_page import LoginPage from .item_page import ItemPage - +from .checkin_page import CheckinPage +from .checkout_page import CheckoutPage diff --git a/inventory/pages/add_location.py b/inventory/pages/add_location.py index da51f83..140a8db 100644 --- a/inventory/pages/add_location.py +++ b/inventory/pages/add_location.py @@ -1,6 +1,5 @@ from __future__ import annotations -from dataclasses import KW_ONLY, field from typing import * # type: ignore import rio diff --git a/inventory/pages/browse_page.py b/inventory/pages/browse_page.py index 50352b4..57f0cc6 100644 --- a/inventory/pages/browse_page.py +++ b/inventory/pages/browse_page.py @@ -63,7 +63,7 @@ class BrowsePage(rio.Component): self.items = search_item(query, self.filters) mid = time() self.loading_text = "Loading data..." - self.force_refresh() + #self.force_refresh() end = time() self.loading_text = "" render = str(int((end - mid) * 1000)) + "ms" diff --git a/inventory/pages/checkin_page.py b/inventory/pages/checkin_page.py new file mode 100644 index 0000000..3cc7937 --- /dev/null +++ b/inventory/pages/checkin_page.py @@ -0,0 +1,98 @@ +from __future__ import annotations + +from typing import * # type: ignore + +import rio +import datetime +from mac_vendor_lookup import AsyncMacLookup + +from db_classes import * +from .. import components as comps +import asyncio + +class CheckinPage(rio.Component): + code: str = "" + popup_message: str = "" + popup_show: bool = False + popup_color: str = 'warning' + name: str = "" + user_code: str = "" + loc_code: str = "" + loc: str = "" + + async def _update_location(self, event: rio.TextInputChangeEvent): + print("Checking " + self.loc) + if get_location_id(self.loc) != False: + self.loc_code = self.loc + print("Found location " + get_location_id(self.loc).name) + self.loc = get_location_id(self.loc).name + + async def _update_user(self, event: rio.TextInputChangeEvent): + print("Checking " + self.name) + if get_location_id(self.name) != False: + self.user_code = self.name + print("Found user " + get_user(self.name).name) + self.name = get_user(self.name).name + + async def _checkin_item_enter(self, event: rio.TextInputConfirmEvent): + await self.check_in() + + async def check_in(self): + if checkin(get_user(self.user_code), self.code, get_location_id(self.loc_code)): + self.popup_message = "\n Item checked in! \n\n" + self.popup_show = True + self.popup_color = 'success' + self.name: str = "" + self.user_code: str = "" + self.code: str = "" + self.loc_code: str = "" + self.loc: str = "" + await asyncio.sleep(2) + self.popup_show = False + else: + self.popup_message = "\n Error! Check item & location! \n\n" + self.popup_show = True + self.popup_color = 'warning' + await asyncio.sleep(2) + self.popup_show = False + + def build(self) -> rio.Component: + return rio.Column( + rio.Popup( + anchor=rio.Text( + text="Check in devices to storage:", + style='heading1', + align_x = 0.5 + ), + color=self.bind().popup_color, + is_open=self.bind().popup_show, + content=rio.Text( + text=self.bind().popup_message, + ), + + ), + rio.TextInput( + label="Barcode", + text=self.bind().code + ), + rio.TextInput( + label="New location", + text=self.bind().loc, + on_change=self._update_location + ), + rio.TextInput( + label="User", + text=self.bind().name, + on_confirm=self._checkin_item_enter + ), + rio.Button( + content="Go" + ), + + spacing=2, + min_width=60, + margin_bottom=4, + align_x=0.5, + align_y=0, + ) + diff --git a/inventory/pages/checkout_page.py b/inventory/pages/checkout_page.py new file mode 100644 index 0000000..d12bb54 --- /dev/null +++ b/inventory/pages/checkout_page.py @@ -0,0 +1,99 @@ +from __future__ import annotations + +from typing import * # type: ignore + +import rio +import datetime +from mac_vendor_lookup import AsyncMacLookup + +from db_classes import * +from .. import components as comps +import asyncio + +class CheckoutPage(rio.Component): + code: str = "" + popup_message: str = "" + popup_show: bool = False + popup_color: str = 'warning' + description: str = "" + name: str = "" + user_code: str = "" + loc_code: str = "" + loc: str = "" + + async def _update_location(self, event: rio.TextInputChangeEvent): + print("Checking " + self.loc) + if get_location_id(self.loc) != False: + self.loc_code = self.loc + print("Found location " + get_location_id(self.loc).name) + self.loc = get_location_id(self.loc).name + + async def _update_user(self, event: rio.TextInputChangeEvent): + print("Checking " + self.name) + if get_location_id(self.name) != False: + self.user_code = self.name + print("Found user " + get_user(self.name).name) + self.name = get_user(self.name).name + + async def _checkout_item_enter(self, event: rio.TextInputConfirmEvent): + await self.check_out() + + async def check_out(self): + if checkout(get_user(self.user_code), self.code, get_location_id(self.loc_code)): + self.popup_message = "\n Item checked out! \n\n" + self.popup_show = True + self.popup_color = 'success' + self.name: str = "" + self.user_code: str = "" + self.code: str = "" + self.loc_code: str = "" + self.loc: str = "" + await asyncio.sleep(2) + self.popup_show = False + else: + self.popup_message = "\n Error! Check item & location! \n\n" + self.popup_show = True + self.popup_color = 'warning' + await asyncio.sleep(2) + self.popup_show = False + + def build(self) -> rio.Component: + return rio.Column( + rio.Popup( + anchor=rio.Text( + text="Check out devices from storage:", + style='heading1', + align_x = 0.5 + ), + color=self.bind().popup_color, + is_open=self.bind().popup_show, + content=rio.Text( + text=self.bind().popup_message, + ), + + ), + rio.TextInput( + label="Barcode", + text=self.bind().code + ), + rio.TextInput( + label="New location", + text=self.bind().loc, + on_change=self._update_location + ), + rio.TextInput( + label="User", + text=self.bind().name, + on_confirm=self._checkout_item_enter + ), + rio.Button( + content="Go" + ), + + spacing=2, + min_width=60, + margin_bottom=4, + align_x=0.5, + align_y=0, + ) +