X-Git-Url: https://apps.delaporte.us/gitweb/matrix-shop-bot.git/blobdiff_plain/d3e89743c10b7d8a5d4367471995366afa8d497c..dbe3765edb809f29f17baf9f638089eb40f4eda7:/matrix_shop_bot/db.py diff --git a/matrix_shop_bot/db.py b/matrix_shop_bot/db.py index 31daf99..a6d51e3 100644 --- a/matrix_shop_bot/db.py +++ b/matrix_shop_bot/db.py @@ -6,6 +6,8 @@ from typing import List from sqlmodel import Field, Session, SQLModel, create_engine, select, text, Relationship +from sqlite3 import IntegrityError + MODULE='shop' DATE_FORMAT = '%Y-%m-%d' @@ -15,7 +17,6 @@ def today(): logger = logging.getLogger(__name__) -logging.basicConfig(filename=f'{MODULE}.log', encoding='utf-8', level=logging.DEBUG) class ItemStoreLink(SQLModel, table=True): item_id: int | None = Field(default=None, foreign_key="item.id", primary_key=True) @@ -42,17 +43,13 @@ class Store(SQLModel, table=True): def __str__(self): return f'{self.name} (#{self.id})' - - - - # May get used later... -#class PurchaseRecord(SQLModel, table=True): -# id: int | None = Field(default=None, primary_key=True) -# name: str = Field(default=None, unique=True) -# price: Decimal | None = Field(decimal_places=2) -# store: Store = Relationship(back_populates="purchase_history") -# purchase_date: dt | None = Field(default=None) +class PurchaseRecord(SQLModel, table=True): + id: int | None = Field(default=None, primary_key=True) + name: str = Field(default=None) + price: Decimal | None = Field(decimal_places=2) + store: str | None = Field(default=None) + purchase_date: dt | None = Field(default=None) def _get_with_id(cls, item_id): return select(cls).where(cls.id == item_id) @@ -64,6 +61,7 @@ class Data(): db_file = os.path.join(os.environ.get('MATRIX_DATA_DIR', ''), f'{MODULE}.db') self.file = db_file + logger.debug(f'Using db file {self.file}') self.engine = self.get_engine() self.last_store_id = None @@ -83,47 +81,80 @@ class Data(): return pref.store_id def _add_with_name(self, cls, name): - id = -1 - with Session(self.engine) as session: - new = cls(name=name) - session.add(new) - session.commit() - id = new.id - return id + item_id = -1 + try: + with Session(self.engine) as session: + new = cls(name=name) + session.add(new) + session.commit() + item_id = new.id + except: + # duplicate add + # recover by returning the item_id + item = session.exec(select(Item).where(Item.name == name)).first() + item_id = item.id + + return item_id def add_store(self, name): store_id = self._add_with_name(Store, name) - self.last_store_id = store_id + self._set_pref_store_id(store_id) return store_id def add_item(self, name): - item_id = self._add_with_name(Item, name) - if isinstance(self.last_store_id, int): - with Session(self.engine) as session: - store_id = self.last_store_id - store = session.exec(_get_with_id(Store, store_id)).first() - item = session.exec(_get_with_id(Item, item_id)).first() - item.stores.append(store) - session.commit() + names = name.split(',') + for name in names: + item_id = self._add_with_name(Item, name.strip()) + store_id = self._get_pref_store_id() + self.assign_store(item_id, store_id) return item_id - def assign_store(self, item_id, store_id=None): - if store_id: - self.last_store_id = store_id - else: - store_id = self.last_store_id + def assign_last_store(self, item_id): + store_id = self._get_pref_store_id() + self.assign_store(item_id, store_id) + return store_id + + def assign_store(self, item_id, store_id): + self._set_pref_store_id(store_id) with Session(self.engine) as session: store = session.exec(_get_with_id(Store, store_id)).first() item = session.exec(_get_with_id(Item, item_id)).first() - item.stores.append(store) - session.commit() + try: + item.stores.append(store) + session.commit() + except: + pass # Already assigned + return ['Success'] - def purchase_item(self, item_id): + def list_purchases(self, store_name): with Session(self.engine) as session: - item = session.exec(_get_with_id(Item, item_id)).first() - item.purchase_date = dt.today() + cmd = select(PurchaseRecord).where(PurchaseRecord.store == store_name) + records = session.exec(cmd).all() + return records + + def purchase_items(self, item_ids): + results = [] + with Session(self.engine) as session: + # Mark items as purchased + for item_id in item_ids.split(' '): + item = session.exec(_get_with_id(Item, item_id)).first() + if item: + item.purchase_date = dt.today() + results.append(str(item)) + + # Track purchase history (locally only!) + # to generate recommended shopping lists + record = PurchaseRecord() + record.name = item.name + record.price = item.price + record.purchase_date = item.purchase_date + record.store = self._get_pref_store_id() # We bought it here + session.add(record) + session.commit() + return results + def clear_list(self, store_id, clear_all=False): with Session(self.engine) as session: