194 lines
No EOL
6.2 KiB
Python
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)
|
|
# }) |