From ff2b6184147c4dbe9a61a3f92aa733f70ba0e734 Mon Sep 17 00:00:00 2001 From: Martin Hohenberg Date: Mon, 6 Jul 2026 17:17:22 +0200 Subject: [PATCH] Duplicate job --- .DS_Store | Bin 0 -> 6148 bytes app/routers/ui.py | 47 ++++++++++++++++++++++++++++++ app/templates/jobs.html | 8 +++++ app/templates/printer_detail.html | 17 +++++++++++ 4 files changed, 72 insertions(+) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6721435ef382c1e50794112f5bab8fea911677c7 GIT binary patch literal 6148 zcmeHKJx;?g6n>_W8UaH`Hhco4UI2wE2#K{9C~Z(dN|X$AU<+d53WyG{bB{_~0u~lV zSQ+@9?Y6ekN=yjBdy@Sn?I;V$t;4kNG`h&v%2X57Wb7vh z=WRvA+-;0Kf=tW4JbZI8d_# zm^iF0!UI#b6lhD8J7OqX4!?GJiNo5WEhlA|@f^pj+zCY)cKEePCzV)~SriZjLIqm( zw!{1X;rjD`SR{9%fGF^%6i`vxPkVSJx3@N4j`v!PF~DHsyxO8E!Q{4MbHQ8j4u&zr YG+zJ{hqXm`VDckiWROV|_)!JE0CRSV761SM literal 0 HcmV?d00001 diff --git a/app/routers/ui.py b/app/routers/ui.py index 52f1985..a170b71 100644 --- a/app/routers/ui.py +++ b/app/routers/ui.py @@ -1,5 +1,6 @@ import math import os +import re import uuid as _uuid from datetime import datetime, timedelta from pathlib import Path @@ -90,10 +91,17 @@ def printer_detail(printer_id: int, request: Request, db: Session = Depends(get_ printer = db.query(Printer).filter(Printer.id == printer_id).first() if not printer: raise HTTPException(status_code=404, detail="Printer not found") + current_job = ( + db.query(PrintJob) + .filter(PrintJob.printer_id == printer_id, PrintJob.status == JobStatus.printing) + .order_by(PrintJob.started_at.desc()) + .first() + ) return templates.TemplateResponse("printer_detail.html", { "request": request, "active": "printers", "printer": printer, + "current_job": current_job, }) @@ -335,6 +343,45 @@ def edit_job( return RedirectResponse(url=f"/jobs/{job_id}", status_code=HTTP_303_SEE_OTHER) +@router.post("/jobs/{job_id}/duplicate") +def duplicate_job(job_id: int, db: Session = Depends(get_db)): + from fastapi import HTTPException + job = db.query(PrintJob).filter(PrintJob.id == job_id).first() + if not job: + raise HTTPException(404, "Job not found") + + copy = PrintJob( + job_uuid=str(_uuid.uuid4()), + name=job.name, + file_name=job.file_name, + printer_id=None, + bracket_id=job.bracket_id, + customer=job.customer, + job_material=job.job_material, + job_color=job.job_color, + priority=job.priority, + status=JobStatus.queued, + notes=job.notes, + ) + db.add(copy) + + # If the original was in a bracket, extend the "×N" count in its name to match. + if job.bracket and job.bracket.name: + job.bracket.name = re.sub( + r"×(\d+)\s*$", + lambda m: f"×{int(m.group(1)) + 1}", + job.bracket.name, + ) + + db.flush() + db.add(JobLog(job_id=copy.id, message=f"Job created (duplicate of #{job.id})")) + db.commit() + + if copy.bracket_id: + return RedirectResponse(url=f"/jobs?bracket_id={copy.bracket_id}", status_code=HTTP_303_SEE_OTHER) + return RedirectResponse(url="/jobs", status_code=HTTP_303_SEE_OTHER) + + @router.get("/files/{filename}") def download_file(filename: str): from fastapi import HTTPException diff --git a/app/templates/jobs.html b/app/templates/jobs.html index c71ef4a..9116369 100644 --- a/app/templates/jobs.html +++ b/app/templates/jobs.html @@ -50,6 +50,7 @@ Material Status Created + @@ -87,6 +88,13 @@ {% endif %} {{ j.created_at.strftime('%d.%m.%Y %H:%M') }} + +
+ +
+ {% endfor %} diff --git a/app/templates/printer_detail.html b/app/templates/printer_detail.html index c665523..2438dfb 100644 --- a/app/templates/printer_detail.html +++ b/app/templates/printer_detail.html @@ -16,6 +16,23 @@ {% endif %} +{# ── Currently printing ── #} +{% if current_job %} + +
+
+ +
+
Currently printing
+
{{ current_job.file_name or current_job.name or '—' }}
+ {% if current_job.customer %}
{{ current_job.customer }}
{% endif %} +
+ +
+
+
+{% endif %} +
{# ── Info card ── #}