from datetime import datetime from flask import request, render_template, session from sqlalchemy import desc, asc, or_, and_, cast, Integer from common.models.document import Document, Catalog from common.utils.filtered_list_view import FilteredListView from common.utils.view_assistants import prepare_table_for_macro class DocumentListView(FilteredListView): allowed_filters = ['catalog_id', 'validity'] allowed_sorts = ['id', 'name', 'catalog_name', 'valid_from', 'valid_to'] def get_query(self): return Document.query.join(Catalog).add_columns( Document.id, Document.name, Catalog.name.label('catalog_name'), Document.valid_from, Document.valid_to ) def apply_filters(self, query): filters = request.args.to_dict(flat=False) if 'catalog_id' in filters: catalog_ids = filters['catalog_id'] if catalog_ids: # Convert catalog_ids to a list of integers catalog_ids = [int(cid) for cid in catalog_ids if cid.isdigit()] if catalog_ids: query = query.filter(Document.catalog_id.in_(catalog_ids)) if 'validity' in filters: now = datetime.utcnow().date() if 'valid' in filters['validity']: query = query.filter( and_( or_(Document.valid_from.is_(None), Document.valid_from <= now), or_(Document.valid_to.is_(None), Document.valid_to >= now) ) ) return query def apply_sorting(self, query): sort_by = request.args.get('sort_by', 'id') sort_order = request.args.get('sort_order', 'asc') if sort_by in self.allowed_sorts: if sort_by == 'catalog_name': column = Catalog.name else: column = getattr(Document, sort_by) if sort_order == 'asc': query = query.order_by(asc(column)) elif sort_order == 'desc': query = query.order_by(desc(column)) return query def get(self): query = self.get_query() query = self.apply_filters(query) query = self.apply_sorting(query) pagination = self.paginate(query) def format_date(date): if isinstance(date, datetime): return date.strftime('%Y-%m-%d') elif isinstance(date, str): return date else: return '' rows = [ [ {'value': item.id, 'class': '', 'type': 'text'}, {'value': item.name, 'class': '', 'type': 'text'}, {'value': item.catalog_name, 'class': '', 'type': 'text'}, {'value': format_date(item.valid_from), 'class': '', 'type': 'text'}, {'value': format_date(item.valid_to), 'class': '', 'type': 'text'} ] for item in pagination.items ] catalogs = Catalog.query.all() context = { 'rows': rows, 'pagination': pagination, 'filters': request.args.to_dict(flat=False), 'sort_by': request.args.get('sort_by', 'id'), 'sort_order': request.args.get('sort_order', 'asc'), 'filter_options': self.get_filter_options(catalogs) } return render_template(self.template, **context) def get_filter_options(self, catalogs): return { 'catalog_id': [(str(cat.id), cat.name) for cat in catalogs], 'validity': [('valid', 'Valid'), ('all', 'All')] }