Implement CSV export functionality for inventory, users, and worklogs with error handling

This commit is contained in:
Yaro Kasear 2025-07-17 08:06:26 -05:00
parent 1d0468b9be
commit 357d7196fa
4 changed files with 151 additions and 10 deletions

View file

@ -214,6 +214,22 @@ def delete_inventory_item(id):
@main.route("/api/inventory/export", methods=["POST"])
def get_inventory_csv():
def export_value(item, col):
try:
match col:
case "brand":
return item.brand.name
case "location":
return item.location.full_name
case "owner":
return item.owner.full_name
case "type":
return item.item.description
case _:
return getattr(item, col, "")
except Exception:
return ""
data = request.get_json()
ids = data.get('ids', [])
@ -225,13 +241,26 @@ def get_inventory_csv():
output = io.StringIO()
writer = csv.writer(output)
model = Inventory
columns = [c.key for c in inspect(model).mapper.column_attrs]
columns = [
"id",
"timestamp",
"condition",
"type",
"name",
"serial",
"model",
"notes",
"owner",
"brand",
"location",
"barcode",
"shared"
]
writer.writerow(columns)
for item in rows:
writer.writerow([getattr(item, col) for col in columns])
writer.writerow([export_value(item, col) for col in columns])
csv_string = output.getvalue()
output.close()

View file

@ -1,3 +1,7 @@
import base64
import csv
import io
from flask import render_template, request, jsonify
from . import main
@ -15,7 +19,8 @@ def list_users():
header = user_headers,
rows = [{"id": user.id, "cells": [fn(user) for fn in user_headers.values()]} for user in users],
title = "Users",
entry_route = 'user'
entry_route = 'user',
csv_route = 'user'
)
@main.route("/user/<id>")
@ -120,4 +125,53 @@ def update_user(id):
except Exception as e:
db.session.rollback()
return jsonify({"success": False, "error": str(e)}), 400
return jsonify({"success": False, "error": str(e)}), 400
@main.route("/api/user/export", methods=["POST"])
def get_user_csv():
def export_value(user, col):
try:
match col:
case "location":
return user.location.full_name
case "supervisor":
return user.supervisor.full_name
case _:
return getattr(user, col, "")
except Exception:
return ""
data = request.get_json()
ids = data.get('ids', [])
if not ids:
return jsonify({"success": False, "error": "No IDs provided"}), 400
rows = eager_load_user_relationships(db.session.query(User).filter(User.id.in_(ids))).all()
output = io.StringIO()
writer = csv.writer(output)
columns = [
"id",
"staff",
"active",
"last_name",
"first_name",
"location",
"supervisor"
]
writer.writerow(columns)
for user in rows:
writer.writerow([export_value(user, col) for col in columns])
csv_string = output.getvalue()
output.close()
return jsonify({
"success": True,
"csv": base64.b64encode(csv_string.encode()).decode(),
"count": len(rows)
})

View file

@ -1,4 +1,7 @@
import base64
import csv
import datetime
import io
from flask import request, render_template, jsonify
@ -9,15 +12,15 @@ from ..models import WorkLog, User, Inventory, WorkNote
from ..utils.load import eager_load_worklog_relationships, eager_load_user_relationships, eager_load_inventory_relationships
@main.route("/worklog")
def list_worklog(page=1):
page = request.args.get('page', default=1, type=int)
def list_worklog():
query = eager_load_worklog_relationships(db.session.query(WorkLog))
return render_template(
'table.html',
header=worklog_headers,
rows=[{"id": log.id, "cells": [fn(log) for fn in worklog_headers.values()]} for log in query.all()],
title="Work Log",
entry_route='worklog_entry'
entry_route='worklog_entry',
csv_route='worklog'
)
@main.route("/worklog/<id>")
@ -143,3 +146,58 @@ def delete_worklog(id):
except Exception as e:
db.session.rollback()
return jsonify({"success": False, "error": str(e)}), 400
@main.route("/api/worklog/export", methods=["POST"])
def get_worklog_csv():
def export_value(log, col):
try:
match col:
case "contact":
return log.contact.full_name
case "work_item":
return log.work_item.identifier
case "latest_update":
if log.updates:
return log.updates[-1].content
return ""
case _:
return getattr(log, col, "")
except Exception:
return ""
data = request.get_json()
ids = data.get('ids', [])
if not ids:
return jsonify({"success": False, "error": "No IDs provided"}), 400
rows = eager_load_worklog_relationships(db.session.query(WorkLog).filter(WorkLog.id.in_(ids))).all()
output = io.StringIO()
writer = csv.writer(output)
columns = [
"id",
"start_time",
"end_time",
"complete",
"followup",
"contact",
"work_item",
"analysis",
"latest_update"
]
writer.writerow(columns)
for user in rows:
writer.writerow([export_value(user, col) for col in columns])
csv_string = output.getvalue()
output.close()
return jsonify({
"success": True,
"csv": base64.b64encode(csv_string.encode()).decode(),
"count": len(rows)
})

View file

@ -36,10 +36,10 @@
URL.revokeObjectURL(url);
} else {
renderToast({ message: `Export failed: ${result.error}` });
renderToast({ message: `Export failed: ${result.error}`, type: 'danger' });
}
} catch (err) {
renderToast({ message: `Export failed: ${err}` });
renderToast({ message: `Export failed: ${err}`, type: 'danger' });
}
{% endset %}
{% set toolbarButtons %}