diff --git a/Dockerfile b/Dockerfile index c6164f9..785582a 100755 --- a/Dockerfile +++ b/Dockerfile @@ -12,6 +12,8 @@ WORKDIR /app RUN pip3 install -r requirements.txt +RUN apt-get update && apt-get install -y wkhtmltopdf + EXPOSE 8000 COPY . /app diff --git a/app/__pycache__/__init__.cpython-312.pyc b/app/__pycache__/__init__.cpython-312.pyc index 8fe2c5d..37fe7f1 100644 Binary files a/app/__pycache__/__init__.cpython-312.pyc and b/app/__pycache__/__init__.cpython-312.pyc differ diff --git a/app/__pycache__/database.cpython-312.pyc b/app/__pycache__/database.cpython-312.pyc index 9406172..d0c9180 100644 Binary files a/app/__pycache__/database.cpython-312.pyc and b/app/__pycache__/database.cpython-312.pyc differ diff --git a/app/__pycache__/main.cpython-312.pyc b/app/__pycache__/main.cpython-312.pyc index 9a23e4e..9f67a5e 100644 Binary files a/app/__pycache__/main.cpython-312.pyc and b/app/__pycache__/main.cpython-312.pyc differ diff --git a/app/bin/__init__.py b/app/bin/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/bin/print_file.py b/app/bin/print_file.py new file mode 100644 index 0000000..1f86f1e --- /dev/null +++ b/app/bin/print_file.py @@ -0,0 +1 @@ +adsfasd \ No newline at end of file diff --git a/app/dependencies.py b/app/dependencies.py index 49d6ead..e69de29 100644 --- a/app/dependencies.py +++ b/app/dependencies.py @@ -1,13 +0,0 @@ -from typing import Annotated - -from fastapi import Header, HTTPException - - -async def get_token_header(x_token: Annotated[str, Header()]): - if x_token != "fake-super-secret-token": - raise HTTPException(status_code=400, detail="X-Token header invalid") - - -async def get_query_token(token: str): - if token != "jessica": - raise HTTPException(status_code=400, detail="No Jessica token provided") \ No newline at end of file diff --git a/app/main.py b/app/main.py index 24a1093..29d0ff6 100644 --- a/app/main.py +++ b/app/main.py @@ -1,6 +1,8 @@ from fastapi import FastAPI -from app.routers import printstatus, command +from app.routers import (cron_print, printstatus, + command, + ) @@ -11,11 +13,12 @@ app = FastAPI() app.include_router(printstatus.router) app.include_router(command.router) +app.include_router(cron_print.router) @app.get("/") def read_root(): - return {"Hello": "World"} + return {"Status": "Printer Service is Online"} diff --git a/app/models/__pycache__/delivery.cpython-312.pyc b/app/models/__pycache__/delivery.cpython-312.pyc index 916210b..e5fa210 100644 Binary files a/app/models/__pycache__/delivery.cpython-312.pyc and b/app/models/__pycache__/delivery.cpython-312.pyc differ diff --git a/app/models/__pycache__/printer.cpython-312.pyc b/app/models/__pycache__/printer.cpython-312.pyc new file mode 100644 index 0000000..42b41a8 Binary files /dev/null and b/app/models/__pycache__/printer.cpython-312.pyc differ diff --git a/app/models/delivery.py b/app/models/delivery.py index 6696629..8319183 100644 --- a/app/models/delivery.py +++ b/app/models/delivery.py @@ -1,5 +1,5 @@ from sqlalchemy import Column, Integer,\ - Integer, DECIMAL, Text,\ + DECIMAL, Text,\ VARCHAR, TIMESTAMP, Date from datetime import datetime from app.database import Base @@ -48,5 +48,3 @@ class Delivery(Base): pre_charge_amount = Column(DECIMAL(50, 2)) total_price = Column(DECIMAL(50, 2)) final_price = Column(DECIMAL(50, 2)) - - diff --git a/app/models/printer.py b/app/models/printer.py new file mode 100644 index 0000000..22d300e --- /dev/null +++ b/app/models/printer.py @@ -0,0 +1,29 @@ +from sqlalchemy import Column, Integer,\ + DECIMAL, Text,\ + VARCHAR, TIMESTAMP, Date +from datetime import datetime +from app.database import Base + + +class Printer_jobs(Base): + __tablename__ = "printer_jobs" + + id = Column(Integer, + primary_key=True, + autoincrement=True, + unique=False) + + delivery_id = Column(Integer) + date_added = Column(Date(), default=datetime.utcnow()) + date_completed = Column(Date(), default=datetime.utcnow()) + employee_id = Column(Integer) + #0 = waiting + #1 = file made..read to print + #2 = printing + #3 = printed + #4 = error + status = Column(Integer) + + + + diff --git a/app/routers/__pycache__/command.cpython-312.pyc b/app/routers/__pycache__/command.cpython-312.pyc index 3f75949..0e9d95e 100644 Binary files a/app/routers/__pycache__/command.cpython-312.pyc and b/app/routers/__pycache__/command.cpython-312.pyc differ diff --git a/app/routers/__pycache__/cron_make_files.cpython-312.pyc b/app/routers/__pycache__/cron_make_files.cpython-312.pyc new file mode 100644 index 0000000..ed9a705 Binary files /dev/null and b/app/routers/__pycache__/cron_make_files.cpython-312.pyc differ diff --git a/app/routers/__pycache__/cron_print.cpython-312.pyc b/app/routers/__pycache__/cron_print.cpython-312.pyc new file mode 100644 index 0000000..d46a9ac Binary files /dev/null and b/app/routers/__pycache__/cron_print.cpython-312.pyc differ diff --git a/app/routers/__pycache__/cronprint.cpython-312.pyc b/app/routers/__pycache__/cronprint.cpython-312.pyc new file mode 100644 index 0000000..e72c64b Binary files /dev/null and b/app/routers/__pycache__/cronprint.cpython-312.pyc differ diff --git a/app/routers/__pycache__/printstatus.cpython-312.pyc b/app/routers/__pycache__/printstatus.cpython-312.pyc index 1967611..687d4e7 100644 Binary files a/app/routers/__pycache__/printstatus.cpython-312.pyc and b/app/routers/__pycache__/printstatus.cpython-312.pyc differ diff --git a/app/routers/command.py b/app/routers/command.py index 630dfc9..f24c3c7 100644 --- a/app/routers/command.py +++ b/app/routers/command.py @@ -1,7 +1,9 @@ -from fastapi import APIRouter, Depends, HTTPException +from fastapi import APIRouter + +from datetime import date, timedelta, datetime from app.database import session from app.models.delivery import Delivery - +from app.models.printer import Printer_jobs router = APIRouter( prefix="/command", @@ -10,7 +12,103 @@ router = APIRouter( ) -@router.get("/") -async def read_items(): - x = session.query(Delivery).first() - return {"x": x.id} \ No newline at end of file +@router.get("/printticket/{delivery_id}") +async def print_specific_ticket(delivery_id): + + now = datetime.utcnow() + + get_ticket = (session.query(Delivery) + .filter(Delivery.id == delivery_id) + .first()) + + new_job = Printer_jobs( + delivery_id = delivery_id, + date_added = now, + date_completed = None, + employee_id = get_ticket.driver_employee_id, + status = 0, + ) + session.add(new_job) + session.commit() + + return {"ok": True} + + +@router.get("/print_waiting") +async def print_waiting_tickets(): + + tomm = date.today() + timedelta(days=1) + now = datetime.utcnow() + + get_deliveries = (session + .query(Delivery) + .filter(Delivery.delivery_status == 0) + .filter(Delivery.expected_delivery_date != tomm) + .filter(Delivery.expected_delivery_date != date.today()) + .all()) + + for f in get_deliveries: + new_job = Printer_jobs( + delivery_id = f.id, + date_added = now, + date_completed = None, + employee_id = f.driver_employee_id, + status = 0, + ) + session.add(new_job) + + session.commit() + + return {"ok": True} + + +@router.get("/print_today") +async def print_today_tickets(): + + now = datetime.utcnow() + + get_deliveries = (session + .query(Delivery) + .filter(Delivery.expected_delivery_date == date.today()) + .all()) + + for f in get_deliveries: + new_job = Printer_jobs( + delivery_id = f.id, + date_added = now, + date_completed = None, + employee_id = f.driver_employee_id, + status = 0, + ) + session.add(new_job) + + session.commit() + + return {"ok": True} + + +@router.get("/print_tommorrow") +async def print_tommorrow_tickets(): + + now = datetime.utcnow() + tomm = date.today() + timedelta(days=1) + + get_deliveries = (session + .query(Delivery) + .filter(Delivery.expected_delivery_date == tomm) + .all()) + + for f in get_deliveries: + new_job = Printer_jobs( + delivery_id = f.id, + date_added = now, + date_completed = None, + employee_id = f.driver_employee_id, + status = 0, + ) + session.add(new_job) + + session.commit() + + return {"ok": True} + diff --git a/app/routers/cron_print.py b/app/routers/cron_print.py new file mode 100644 index 0000000..10a7378 --- /dev/null +++ b/app/routers/cron_print.py @@ -0,0 +1,78 @@ +from fastapi import APIRouter, BackgroundTasks + +from app.database import session +from app.models.printer import Printer_jobs +import subprocess +import shutil +import pdfkit + +location_tickets = '/home/amnesia/gitbox/tickets/' +printer_url_service = 'http://172.18.0.1:5173/ticket/' + +router = APIRouter( + prefix="/cron", + tags=["cron"], + responses={404: {"description": "Not found"}}, +) + +@router.get("/waiting") +async def make_waiting(): + + """ + Cron job - Gets waiting tickets in database and makes pdf files + Updates values in database for next step + """ + get_tickets_to_print = (session.query(Printer_jobs) + .filter(Printer_jobs.status == 0) + .all()) + count = 0 + for f in get_tickets_to_print: + # get the pdf name + filename_out = str(f.id) + '.pdf' + # read website for the html in + web_url = printer_url_service + str(f.id) + pdfkit.from_url(web_url, filename_out, verbose=True) + #set location and name to move the ticket too + renamed_file = location_tickets + filename_out + # perform command to move command + shutil.move(filename_out, renamed_file) + + # update count + newcount = count + 1 + count = newcount + f.status = 1 + session.add(f) + session.commit() + + + return {'ok': True, + 'count': count, + } + + +@router.get("/print/waiting") +async def print_waiting(background_tasks: BackgroundTasks): + """ + Checks if pdfs are made by query + Prints tickets using linux command on background tasks + """ + get_tickets_to_print = (session.query(Printer_jobs) + .filter(Printer_jobs.status == 1) + .all()) + if get_tickets_to_print is not None: + for f in get_tickets_to_print: + background_tasks.add_task(print_ticket, id=f.id) + f.status = 3 + session.add(f) + session.commit() + + return {'ok': True } + +def print_ticket(id: int): + location = location_tickets + id + '.pdf' + + p = (subprocess.run(["lp", location], capture_output=True)) + + for line in p.stdout.readlines(): + print(line) + \ No newline at end of file diff --git a/app/routers/printstatus.py b/app/routers/printstatus.py index dab9e77..5ac6997 100644 --- a/app/routers/printstatus.py +++ b/app/routers/printstatus.py @@ -1,10 +1,40 @@ -from fastapi import APIRouter, Depends, HTTPException +from fastapi import APIRouter +from fastapi.responses import JSONResponse +from fastapi.encoders import jsonable_encoder + +from app.database import session +from app.models.delivery import Delivery +from app.models.printer import Printer_jobs + router = APIRouter( prefix="/status", tags=["status"], responses={404: {"description": "Not found"}}, ) -@router.get("/") + + +@router.get("/waiting") async def read_items(): - return {"Hello": "World"} \ No newline at end of file + all_jobs = session.query(Printer_jobs).filter(Printer_jobs.status == 0).all() + return JSONResponse(content=jsonable_encoder(all_jobs), status_code=200) + +@router.get("/ready") +async def read_items(): + all_jobs = session.query(Printer_jobs).filter(Printer_jobs.status == 1).all() + return JSONResponse(content=jsonable_encoder(all_jobs), status_code=200) + +@router.get("/printing") +async def read_items(): + all_jobs = session.query(Printer_jobs).filter(Printer_jobs.status == 2).all() + return JSONResponse(content=jsonable_encoder(all_jobs), status_code=200) + +@router.get("/printed") +async def read_items(): + all_jobs = session.query(Printer_jobs).filter(Printer_jobs.status == 3).all() + return JSONResponse(content=jsonable_encoder(all_jobs), status_code=200) + +@router.get("/error") +async def read_items(): + all_jobs = session.query(Printer_jobs).filter(Printer_jobs.status == 4).all() + return JSONResponse(content=jsonable_encoder(all_jobs), status_code=200) \ No newline at end of file diff --git a/app/schema/__init__.py b/app/schema/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/app/schema/delivery.py b/app/schema/delivery.py new file mode 100644 index 0000000..834cf70 --- /dev/null +++ b/app/schema/delivery.py @@ -0,0 +1,39 @@ +from pydantic import BaseModel, Field +from datetime import datetime, timezone +from uuid import UUID, uuid4 + +def datetime_now() -> datetime: + return datetime.now(timezone.utc) + +class Delivery(BaseModel): + customer_id: int + customer_name: str + customer_address: str + customer_town: str + customer_state: int + customer_zip: int + gallons_ordered: float + customer_asked_for_fill: int + gallons_delivered: float + customer_filled: int + delivery_status: int + when_ordered: datetime = Field(default_factory=datetime_now) + when_delivered: datetime = Field(default_factory=datetime_now) + expected_delivery_date: datetime = Field(default_factory=datetime_now) + automatic: int + oil_id: int + supplier_price: float + customer_price: float + customer_temperature: float + dispatcher_notes: str + prime: int + same_day: int + payment_type: int + payment_card_id: int + cash_recieved: float + driver_employee_id: int + driver_first_name: str + driver_last_name: str + pre_charge_amount: float + total_price: float + final_price: float diff --git a/requirements.txt b/requirements.txt index 4e961b3..e7cbf49 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,9 @@ fastapi uvicorn[standard] psycopg2-binary -sqlalchemy \ No newline at end of file +sqlalchemy +python-multipart +pdfkit +requests +beautifulsoup4 +lxml \ No newline at end of file diff --git a/tickets/1.pdf b/tickets/1.pdf new file mode 100644 index 0000000..6b001c3 Binary files /dev/null and b/tickets/1.pdf differ