X-Git-Url: https://apps.delaporte.us/gitweb/matrix-shop-bot.git/blobdiff_plain/ec3ba0f43a217021caa4b3824673a9be6f3688b4..eded5d366f5bb00ed4b01d90f58a8856fb37a377:/matrix_shop_bot/db.py diff --git a/matrix_shop_bot/db.py b/matrix_shop_bot/db.py index cacac97..464e8f1 100644 --- a/matrix_shop_bot/db.py +++ b/matrix_shop_bot/db.py @@ -24,6 +24,7 @@ class ItemStoreLink(SQLModel, table=True): class Item(SQLModel, table=True): + '''An item to shop for.''' id: int | None = Field(default=None, primary_key=True) name: str = Field(default=None, unique=True) price: Decimal | None = Field(decimal_places=2) @@ -32,10 +33,22 @@ class Item(SQLModel, table=True): def __str__(self): return f'{self.name} (#{self.id})' +class ItemZone(SQLModel, table=True): + '''Where an item is usually found. + + Matched only by loose text matching, since items come and go, over time. + ''' + id: int | None = Field(default=None, primary_key=True) + name: str = Field(default=None, unique=True) # milk + zone: str = Field(default=None, unique=False) # dairy section + + class PreferStore(SQLModel, table=True): + '''Tracks which store we are shopping at, at the moment.''' store_id: int | None = Field(default=None, foreign_key="store.id", primary_key=True) class Store(SQLModel, table=True): + '''A place to shop at.''' id: int | None = Field(default=None, primary_key=True) name: str = Field(default=None, unique=True) shopping_list: list["Item"] = Relationship(back_populates="stores", link_model=ItemStoreLink) @@ -58,8 +71,8 @@ class Store(SQLModel, table=True): return results -# May get used later... class PurchaseRecord(SQLModel, table=True): + '''Tracks when and where items were purchased.''' id: int | None = Field(default=None, primary_key=True) name: str = Field(default=None) price: Decimal | None = Field(decimal_places=2) @@ -67,7 +80,7 @@ class PurchaseRecord(SQLModel, table=True): purchase_date: dt | None = Field(default=None) def __str__(self): date = self.purchase_date.strftime(DATE_FORMAT) - return f'{self.name} at {self.store} on {date}' + return f'Bought {self.name} at {self.store} on {date}' def _get_with_id(cls, item_id): return select(cls).where(cls.id == item_id) @@ -135,6 +148,19 @@ class Data(): self.assign_store(item_id, store_id) return store_id + def assign_zone(self, item_name, zone_name): + item_id = -1 + with Session(self.engine) as session: + try: + new = ItemZone(name=item_name) + new.zone = zone_name + session.add(new) + session.commit() + item_id = new.id + except: + pass # Already assigned + return item_id + def assign_store(self, item_id, store_id): self._set_pref_store_id(store_id) @@ -150,7 +176,7 @@ class Data(): def list_purchases(self, store_name): with Session(self.engine) as session: - cmd = select(PurchaseRecord).where(PurchaseRecord.store == store_name) + cmd = select(PurchaseRecord).where(func.lower(PurchaseRecord.store) == func.lower(store_name)) records = session.exec(cmd).all() return records @@ -183,13 +209,20 @@ class Data(): return results - def clear_list(self, store_id, clear_all=False): + def clear_list(self, store_name, clear_all=False): + results = [] with Session(self.engine) as session: - store = session.exec(_get_with_id(Store, store_id)).first() + store = session.exec(_get_with_name(Store, store_name)).first() + if not store: + return [f'Store {store_name} not found.'] + for item in store.shopping_list: if clear_all or item.purchase_date: session.delete(item) + session.commit() + results = store.get_pretty_shopping_list() + return results def get_stores(self): with Session(self.engine) as session: