- Created a new SQL migration for the sag_salgsvarer table to manage sales and purchase items. - Implemented a new HTML template for the Varekøb & Salg module, including summary cards and tables for sales and purchases. - Added JavaScript functions for loading and rendering order data dynamically. - Introduced a new backend search module for customers, contacts, hardware, and locations with autocomplete functionality. - Developed an email templates API for managing system and customer-specific email templates. - Created multiple migrations for Nextcloud instances, cache, audit logs, email templates, sag comments, hardware locations, and billing methods. - Enhanced the sag module with solutions, order lines, work types, and 2FA support for user authentication.
85 lines
2.4 KiB
Python
85 lines
2.4 KiB
Python
from fastapi import APIRouter, Query
|
|
from app.core.database import execute_query
|
|
|
|
router = APIRouter()
|
|
|
|
@router.get("/search/customers")
|
|
async def search_customers(q: str = Query(..., min_length=2)):
|
|
"""
|
|
Autocomplete search for customers.
|
|
Returns list of {id, name, cvr_nummer, email}
|
|
"""
|
|
sql = """
|
|
SELECT id, name, cvr_number as cvr_nummer, email
|
|
FROM customers
|
|
WHERE (name ILIKE %s OR cvr_number ILIKE %s) AND deleted_at IS NULL
|
|
ORDER BY name ASC
|
|
LIMIT 20
|
|
"""
|
|
term = f"%{q}%"
|
|
results = execute_query(sql, (term, term))
|
|
return results
|
|
|
|
@router.get("/search/contacts")
|
|
async def search_contacts(q: str = Query(..., min_length=2)):
|
|
"""
|
|
Autocomplete search for contacts.
|
|
Returns list of {id, first_name, last_name, email}
|
|
"""
|
|
sql = """
|
|
SELECT id, first_name, last_name, email
|
|
FROM contacts
|
|
WHERE
|
|
(first_name ILIKE %s OR
|
|
last_name ILIKE %s OR
|
|
email ILIKE %s)
|
|
ORDER BY first_name ASC, last_name ASC
|
|
LIMIT 20
|
|
"""
|
|
term = f"%{q}%"
|
|
results = execute_query(sql, (term, term, term))
|
|
return results
|
|
|
|
@router.get("/search/hardware")
|
|
async def search_hardware(q: str = Query(..., min_length=2)):
|
|
"""
|
|
Autocomplete search for hardware.
|
|
Returns list of {id, brand, model, serial_number, internal_asset_id}
|
|
"""
|
|
sql = """
|
|
SELECT id, brand, model, serial_number, internal_asset_id
|
|
FROM hardware_assets
|
|
WHERE
|
|
(brand ILIKE %s OR
|
|
model ILIKE %s OR
|
|
serial_number ILIKE %s OR
|
|
internal_asset_id ILIKE %s)
|
|
AND deleted_at IS NULL
|
|
ORDER BY brand ASC, model ASC
|
|
LIMIT 20
|
|
"""
|
|
term = f"%{q}%"
|
|
results = execute_query(sql, (term, term, term, term))
|
|
return results
|
|
|
|
@router.get("/search/locations")
|
|
async def search_locations(q: str = Query(..., min_length=2)):
|
|
"""
|
|
Autocomplete search for locations.
|
|
Returns list of {id, name, address_street, address_city}
|
|
"""
|
|
sql = """
|
|
SELECT id, name, address_street, address_city
|
|
FROM locations_locations
|
|
WHERE
|
|
(name ILIKE %s OR
|
|
address_street ILIKE %s OR
|
|
address_city ILIKE %s)
|
|
AND deleted_at IS NULL
|
|
ORDER BY name ASC
|
|
LIMIT 20
|
|
"""
|
|
term = f"%{q}%"
|
|
results = execute_query(sql, (term, term, term))
|
|
return results
|