Skip to content

Commit

Permalink
Merge pull request #55 from MauriceBoendermaker/Packinglist-PDF
Browse files Browse the repository at this point in the history
Packinglist pdf
  • Loading branch information
yassyass2 authored Dec 30, 2024
2 parents 0b12518 + 47bdee6 commit 835878d
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 0 deletions.
33 changes: 33 additions & 0 deletions CargoHubV2/app/controllers/packinglist_controller.py
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")
2 changes: 2 additions & 0 deletions CargoHubV2/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from CargoHubV2.app.controllers import inventories_controller
from CargoHubV2.app.controllers import orders_controller
from CargoHubV2.app.controllers import reporting_controller
from CargoHubV2.app.controllers import packinglist_controller
from CargoHubV2.app.controllers import docks_controller
import time
from starlette.responses import JSONResponse
Expand All @@ -38,6 +39,7 @@
app.include_router(shipments_controller.router)
app.include_router(inventories_controller.router)
app.include_router(orders_controller.router)
app.include_router(packinglist_controller.router)
app.include_router(docks_controller.router)

logger = logging.getLogger("uvicorn.error")
Expand Down
61 changes: 61 additions & 0 deletions CargoHubV2/app/packinglist_template.html
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>
72 changes: 72 additions & 0 deletions CargoHubV2/app/services/packinglist_service.py
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 added generated_pdfs/packinglist_order_1.pdf
Binary file not shown.

1 comment on commit 835878d

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.