From 6320809f17be61e0b6d25e72f448c5926f9d71db Mon Sep 17 00:00:00 2001 From: Christian Date: Sun, 8 Feb 2026 12:42:19 +0100 Subject: [PATCH] feat: Add subscriptions and products management - Implemented frontend views for products and subscriptions using FastAPI and Jinja2 templates. - Created API endpoints for managing subscriptions, including creation, listing, and status updates. - Added HTML templates for displaying active subscriptions and their statistics. - Established database migrations for sag_subscriptions, sag_subscription_items, and products, including necessary indexes and triggers for automatic subscription number generation. - Introduced product price history tracking to monitor changes in product pricing. --- app/core/config.py | 6 + app/modules/sag/backend/router.py | 6 +- app/modules/sag/templates/detail.html | 620 ++++++++++ app/products/backend/__init__.py | 0 app/products/backend/router.py | 645 ++++++++++ app/products/frontend/__init__.py | 0 app/products/frontend/detail.html | 366 ++++++ app/products/frontend/list.html | 1058 +++++++++++++++++ app/products/frontend/views.py | 24 + app/shared/frontend/base.html | 3 +- app/subscriptions/backend/__init__.py | 0 app/subscriptions/backend/router.py | 308 +++++ app/subscriptions/frontend/__init__.py | 0 app/subscriptions/frontend/list.html | 164 +++ app/subscriptions/frontend/views.py | 19 + docker-compose.yml | 3 + main.py | 8 + migrations/104_sag_subscriptions.sql | 61 + migrations/105_sag_subscription_items.sql | 25 + migrations/106_products.sql | 82 ++ .../106_sag_subscription_items_product.sql | 7 + ...d_product_id_to_sag_subscription_items.sql | 7 + .../108_add_product_id_to_sag_salgsvarer.sql | 7 + migrations/109_product_price_history.sql | 19 + 24 files changed, 3435 insertions(+), 3 deletions(-) create mode 100644 app/products/backend/__init__.py create mode 100644 app/products/backend/router.py create mode 100644 app/products/frontend/__init__.py create mode 100644 app/products/frontend/detail.html create mode 100644 app/products/frontend/list.html create mode 100644 app/products/frontend/views.py create mode 100644 app/subscriptions/backend/__init__.py create mode 100644 app/subscriptions/backend/router.py create mode 100644 app/subscriptions/frontend/__init__.py create mode 100644 app/subscriptions/frontend/list.html create mode 100644 app/subscriptions/frontend/views.py create mode 100644 migrations/104_sag_subscriptions.sql create mode 100644 migrations/105_sag_subscription_items.sql create mode 100644 migrations/106_products.sql create mode 100644 migrations/106_sag_subscription_items_product.sql create mode 100644 migrations/107_add_product_id_to_sag_subscription_items.sql create mode 100644 migrations/108_add_product_id_to_sag_salgsvarer.sql create mode 100644 migrations/109_product_price_history.sql diff --git a/app/core/config.py b/app/core/config.py index 5f1f20a..fb9eef1 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -24,6 +24,12 @@ class Settings(BaseSettings): # Elnet supplier lookup ELNET_API_BASE_URL: str = "https://api.elnet.greenpowerdenmark.dk/api" ELNET_TIMEOUT_SECONDS: int = 12 + + # API Gateway (Product catalog) + APIGW_BASE_URL: str = "https://apigateway.bmcnetworks.dk" + APIGATEWAY_URL: str = "" + APIGW_TOKEN: str = "" + APIGW_TIMEOUT_SECONDS: int = 12 # Security SECRET_KEY: str = "dev-secret-key-change-in-production" diff --git a/app/modules/sag/backend/router.py b/app/modules/sag/backend/router.py index 0c3e734..0a8d533 100644 --- a/app/modules/sag/backend/router.py +++ b/app/modules/sag/backend/router.py @@ -1022,9 +1022,9 @@ async def create_sale_item(sag_id: int, data: dict): query = """ INSERT INTO sag_salgsvarer - (sag_id, type, description, quantity, unit, unit_price, amount, currency, status, line_date, external_ref) + (sag_id, type, description, quantity, unit, unit_price, amount, currency, status, line_date, external_ref, product_id) VALUES - (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) + (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING * """ params = ( @@ -1039,6 +1039,7 @@ async def create_sale_item(sag_id: int, data: dict): status, data.get("line_date"), data.get("external_ref"), + data.get("product_id"), ) result = execute_query(query, params) if result: @@ -1095,6 +1096,7 @@ async def update_sale_item(sag_id: int, item_id: int, updates: dict): "status", "line_date", "external_ref", + "product_id", ] set_clauses = [] diff --git a/app/modules/sag/templates/detail.html b/app/modules/sag/templates/detail.html index 15f466c..f0ba0e6 100644 --- a/app/modules/sag/templates/detail.html +++ b/app/modules/sag/templates/detail.html @@ -555,6 +555,11 @@ Varekøb & Salg +
  • Ny Ticket
  • Prepaid Cards
  • Fastpris Aftaler
  • +
  • Abonnementer
  • Knowledge Base
  • @@ -259,7 +260,7 @@