inventory/inventory/routes/worklog.py

194 lines
No EOL
6.2 KiB
Python

import base64
import csv
import datetime
import io
from flask import request, render_template, jsonify
from . import main
from .helpers import worklog_headers, make_csv
from .. import db
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():
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',
csv_route='worklog'
)
@main.route("/worklog/<id>")
def worklog_entry(id):
try:
id = int(id)
except ValueError:
return render_template('error.html', title='Bad ID', message='ID must be an integer.', endpoint='worklog_entry', endpoint_args={'id': -1})
log = eager_load_worklog_relationships(db.session.query(WorkLog)).get(id)
user_query = db.session.query(User).order_by(User.first_name)
users = eager_load_user_relationships(user_query).all()
item_query = db.session.query(Inventory)
items = eager_load_inventory_relationships(item_query).all()
items = sorted(items, key=lambda i: i.identifier)
if log:
title = f'Work Log - Entry #{id}'
else:
title = "Work Log - Entry Not Found"
return render_template(
'error.html',
title=title,
message=f"The work log with ID {id} is not found!"
)
return render_template(
"worklog.html",
title=title,
log=log,
users=users,
items=items
)
@main.route("/worklog_entry/new", methods=["GET"])
def new_worklog():
items = eager_load_inventory_relationships(db.session.query(Inventory)).all()
users = eager_load_user_relationships(db.session.query(User).order_by(User.first_name)).all()
items = sorted(items, key=lambda i: i.identifier)
log = WorkLog(
start_time=datetime.datetime.now(),
followup=True
)
return render_template(
"worklog.html",
title="New Entry",
log=log,
users=users,
items=items
)
@main.route("/api/worklog", methods=["POST"])
def create_worklog():
try:
data = request.get_json(force=True)
new_worklog = WorkLog.from_dict(data)
db.session.add(new_worklog)
db.session.commit()
return jsonify({"success": True, "id": new_worklog.id}), 201
except Exception as e:
db.session.rollback()
return jsonify({"success": False, "error": str(e)}), 400
@main.route("/api/worklog/<int:id>", methods=["PUT"])
def update_worklog(id):
try:
data = request.get_json(force=True)
log = eager_load_worklog_relationships(db.session.query(WorkLog)).get(id)
if not log:
return jsonify({"success": False, "error": f"Work Log with ID {id} not found."}), 404
log.start_time = datetime.datetime.fromisoformat(data.get("start_time")) if data.get("start_time") else log.start_time
log.end_time = datetime.datetime.fromisoformat(data.get("end_time")) if data.get("end_time") else log.end_time
log.complete = bool(data.get("complete", log.complete))
log.followup = bool(data.get("followup", log.followup))
log.analysis = bool(data.get("analysis", log.analysis))
log.contact_id = data.get("contact_id", log.contact_id)
log.work_item_id = data.get("work_item_id", log.work_item_id)
existing = {str(note.id): note for note in log.updates}
incoming = data.get("updates", [])
new_updates = []
for note_data in incoming:
if isinstance(note_data, dict):
if "id" in note_data and str(note_data["id"]) in existing:
note = existing[str(note_data["id"])]
note.content = note_data.get("content", note.content)
new_updates.append(note)
elif "content" in note_data:
new_updates.append(WorkNote(content=note_data["content"]))
log.updates[:] = new_updates # This replaces in-place
db.session.commit()
return jsonify({"success": True, "id": log.id}), 200
except Exception as e:
db.session.rollback()
return jsonify({"success": False, "error": str(e)}), 400
@main.route("/api/worklog/<int:id>", methods=["DELETE"])
def delete_worklog(id):
try:
log = db.session.query(WorkLog).get(id)
if not log:
return jsonify({"success": False, "errpr": f"Item with ID {id} not found!"}), 404
db.session.delete(log)
db.session.commit()
return jsonify({"success": True}), 200
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()
columns = [
"id",
"start_time",
"end_time",
"complete",
"followup",
"contact",
"work_item",
"analysis",
"latest_update"
]
return make_csv(export_value, columns, rows)
# return jsonify({
# "success": True,
# "csv": base64.b64encode(csv_string.encode()).decode(),
# "count": len(rows)
# })