-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #55 from MauriceBoendermaker/Packinglist-PDF
Packinglist pdf
- Loading branch information
Showing
5 changed files
with
168 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from fastapi import APIRouter, HTTPException, Depends, Header | ||
from sqlalchemy.orm import Session | ||
from CargoHubV2.app.database import get_db | ||
from CargoHubV2.app.services import packinglist_service | ||
from CargoHubV2.app.models.orders_model import Order | ||
from fastapi.responses import FileResponse | ||
from pathlib import Path | ||
|
||
router = APIRouter( | ||
prefix="/api/v2/packinglist", | ||
tags=["packinglist"] | ||
) | ||
|
||
@router.get("/api/v2/packinglist/{order_id}") | ||
def create_packing_list( | ||
order_id: int, | ||
db: Session = Depends(get_db), | ||
api_key: str = Header(...), | ||
): | ||
order = db.query(Order).filter(Order.id == order_id).first() | ||
if not order: | ||
raise HTTPException(status_code=404, detail="Order not found") | ||
return packinglist_service.generate_packing_list(order) | ||
|
||
|
||
@router.get("/get-pdf/{filename}") | ||
def get_pdf(filename: str): | ||
PDF_DIR = Path("generated_pdfs") | ||
pdf_path = PDF_DIR/filename | ||
if pdf_path.exists(): | ||
return FileResponse(pdf_path, media_type="application/pdf", filename=filename) | ||
else: | ||
raise HTTPException(status_code=404, detail="PDF not found") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
|
||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Packing List</title> | ||
<style> | ||
body { | ||
font-family: Arial, sans-serif; | ||
} | ||
|
||
table { | ||
width: 100%; | ||
border-collapse: collapse; | ||
margin-top: 20px; | ||
} | ||
|
||
th, | ||
td { | ||
border: 1px solid #ddd; | ||
padding: 8px; | ||
} | ||
|
||
th { | ||
background-color: #f2f2f2; | ||
} | ||
</style> | ||
</head> | ||
|
||
<body> | ||
<h1>Packing List</h1> | ||
<p><strong>Warehouse ID:</strong> {{ warehouse_id }}</p> | ||
<p><strong>Source ID:</strong> {{ source_id }}</p> | ||
<p><strong>Order ID:</strong> {{ order_id }}</p> | ||
<p><strong>Order Date:</strong> {{ order_date }}</p> | ||
<p><strong>Request Date:</strong> {{ request_date }}</p> | ||
<p><strong>Shipping Notes:</strong> {{ shipping_notes }}</p> | ||
<p><strong>Total Different Items:</strong> {{ total_items }}</p> | ||
<p><strong>Total Amount of Items:</strong> {{ total_amount }}</p> | ||
|
||
<h2>Items</h2> | ||
<table> | ||
<thead> | ||
<tr> | ||
<th>Item ID</th> | ||
<th>Quantity</th> | ||
</tr> | ||
</thead> | ||
<tbody> | ||
{% for item in items %} | ||
<tr> | ||
<td>{{ item.item_id }}</td> | ||
<td>{{ item.amount }}</td> | ||
</tr> | ||
{% endfor %} | ||
</tbody> | ||
</table> | ||
</body> | ||
|
||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import io | ||
import os | ||
import json | ||
import pdfkit | ||
import base64 | ||
import matplotlib.pyplot as plt | ||
|
||
from pathlib import Path | ||
from jinja2 import Template | ||
from itertools import chain | ||
from datetime import datetime | ||
from sqlalchemy import extract | ||
from sqlalchemy.orm import Session | ||
from fastapi import HTTPException, status, FastAPI | ||
from CargoHubV2.app.models.orders_model import Order | ||
from fastapi.responses import FileResponse, JSONResponse | ||
|
||
|
||
PDF_DIR = Path("generated_pdfs") | ||
PDF_DIR.mkdir(exist_ok=True) | ||
|
||
TEMPLATE_FILE = Path(os.path.dirname(__file__)).parent / "packinglist_template.html" | ||
|
||
|
||
def generate_packing_list(order: Order): | ||
try: | ||
# Parse the items data from the order | ||
try: | ||
items = json.loads(order.items) if isinstance(order.items, str) else order.items | ||
if not isinstance(items, list): | ||
raise ValueError("Items should be a list of dictionaries with 'item_id' and 'amount'.") | ||
except json.JSONDecodeError: | ||
raise ValueError("Failed to decode order items. Ensure items are in valid JSON format.") | ||
|
||
|
||
total_amount = sum(item["amount"] for item in items) | ||
|
||
# Prepare data for the packing list | ||
content = { | ||
"warehouse_id": order.warehouse_id, | ||
"source_id": order.source_id, | ||
"shipping_notes": order.shipping_notes, | ||
"order_date": order.order_date.strftime("%Y-%m-%d"), | ||
"order_id": order.id, | ||
"request_date": order.request_date.strftime("%Y-%m-%d"), | ||
"total_items": len(items), | ||
"total_amount": total_amount, | ||
"items": [{"item_id": item["item_id"], "amount": item["amount"]} for item in items], # Simplified item list | ||
} | ||
|
||
# Load the packing list template | ||
with open(TEMPLATE_FILE, "r") as file: | ||
html_template = file.read() | ||
|
||
# Render the template | ||
template = Template(html_template) | ||
html_content = template.render(**content) | ||
|
||
# Define PDF file path | ||
pdf_filename = f"packinglist_order_{order.id}.pdf" | ||
pdf_path = PDF_DIR / pdf_filename | ||
|
||
# Generate PDF | ||
pdfkit.from_string(html_content, str(pdf_path)) | ||
|
||
# Return the file URL or file path | ||
pdf_url = f"http://127.0.0.1:3000/api/v2/packinglist/get-pdf/{pdf_filename}" | ||
return JSONResponse({"message": "Packing list PDF generated successfully.", "pdf_url": pdf_url}) | ||
except ValueError as ve: | ||
raise HTTPException(status_code=400, detail=str(ve)) | ||
except Exception as e: | ||
raise HTTPException(status_code=500, detail=f"Error generating packing list PDF, {e}") |
Binary file not shown.
835878d
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Coverage Report