Implement CSV export functionality for inventory, users, and worklogs with error handling
This commit is contained in:
parent
1d0468b9be
commit
357d7196fa
4 changed files with 151 additions and 10 deletions
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
})
|
|
@ -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)
|
||||
})
|
|
@ -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 %}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue