diff --git a/Dockerfile b/Dockerfile index d92cabe..01e1ae0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,7 +13,7 @@ RUN apk add --no-cache --virtual .build-deps gcc python3-dev musl-dev postgresql pip3 install --no-cache-dir psycopg2==2.8.4 pycparser==2.20 cffi==1.14.0 bcrypt==3.1.7 && \ apk del --no-cache .build-deps -RUN apk add --no-cache py3-pillow cairo pango glib font-noto +RUN apk add --no-cache py3-pillow cairo pango glib font-noto gdk-pixbuf-dev COPY requirements.txt . RUN pip3 install --no-cache-dir -r requirements.txt diff --git a/formity/admin.py b/formity/admin.py index 9d3aabc..f9e93bf 100644 --- a/formity/admin.py +++ b/formity/admin.py @@ -316,8 +316,8 @@ class FaceshieldRequestAdmin(ModelView): output.headers["Content-type"] = "text/csv" return output - @flask_admin.actions.action('create_shipment', 'Create Kurjerzy shipment') - def action_create_shipment(self, ids): + @flask_admin.actions.action('shipping_create', 'Kurjerzy / Create shipment') + def action_shipping_create(self, ids): from shipping.kurjerzy import Kurjerzy models = self.get_query().filter(FaceshieldRequest.id.in_(ids)).all() @@ -342,6 +342,11 @@ class FaceshieldRequestAdmin(ModelView): if created: flash('%d shipments created' % (created,), 'info') + @flask_admin.actions.action('shipping_print', 'Kurjerzy / Print shipping labels') + def action_shipping_print(self, ids): + models = self.get_query().filter(FaceshieldRequest.id.in_(ids)).all() + return render_pdf(HTML(string=self.render('shipping_label.html', models=models))) + class FilteredFaceshieldRequestAdmin(FaceshieldRequestAdmin): def get_query(self): return super(FilteredFaceshieldRequestAdmin, self).get_query().filter(~FaceshieldRequest.status.in_([Status.rejected, Status.spam, Status.fulfilled, Status.delegated])) diff --git a/formity/models.py b/formity/models.py index 1032ab6..a7bde82 100644 --- a/formity/models.py +++ b/formity/models.py @@ -2,8 +2,9 @@ from datetime import datetime import enum import hashlib import os +from flask import current_app from jinja2 import Markup -from formity.extensions import db +from formity.extensions import db, cache from sqlalchemy import event from sqlalchemy.ext.hybrid import hybrid_property from formity.utils import get_diff @@ -94,6 +95,24 @@ class FaceshieldRequest(db.Model): return self.faceshield_full_delivered // 150 return 1 + @cache.memoize(timeout=10 * 60) + def fetch_shipping_info(self): + if self.shipping_provider == 'kurjerzy': + from shipping.kurjerzy import Kurjerzy + k = Kurjerzy(current_app) + k.authenticate() + return k.shipment_info(self.shipping_id) + + return None + + def refresh_shipping_info(self): + cache.delete_memoized(self.fetch_shipping_info, self) + + @property + def shipping_info(self): + return self.fetch_shipping_info() + + def changelog_default_user_id(): from flask_login import current_user return current_user.get_id() if current_user and current_user.get_id() else 'nobody' diff --git a/shipping/kurjerzy.py b/shipping/kurjerzy.py index 979247f..5c1ed20 100644 --- a/shipping/kurjerzy.py +++ b/shipping/kurjerzy.py @@ -134,9 +134,14 @@ class Kurjerzy: def shipment_info(self, id): print('fetching shipment_info(%r)' % (id,)) - return self.send_query(r'query($id: Int) { shipments(ids:[$id]) { id, labelRef, labelSource, status, tracking { statuses } } }', { + result = self.send_query(r'query($id: Int) { shipments(ids:[$id]) { id, labelRef, labelSource, status, tracking { statuses } } }', { 'id': id, - })['data']['shipments'] + }) + + try: + return result['data']['shipments'][0] + except IndexError: + return None if __name__ == '__main__': k = Kurjerzy({}) diff --git a/templates/label.html b/templates/label.html index 2a2f4a4..6437496 100644 --- a/templates/label.html +++ b/templates/label.html @@ -2,6 +2,7 @@ + {% block content %} {% for model in models %} {% for label_id in range(model.label_count) %}
@@ -83,5 +86,6 @@ html, body {
{% endfor %} {% endfor %} + {% endblock %} diff --git a/templates/shipping_label.html b/templates/shipping_label.html new file mode 100644 index 0000000..cea641d --- /dev/null +++ b/templates/shipping_label.html @@ -0,0 +1,25 @@ +{% extends "label.html" %} +{% block css %}{{ super() }} + +.shipping { +flex-direction: row; +align-items: initial; +} +.shipping .inner { +width: 6in; +height: 4in; +overflow: hidden; +} +.shipping .inner img { +height: 100%; +} +{% endblock %} +{% block content %} +{% for model in models %} +
+
+ label {{ model.id }} +
+
+{% endfor %} +{% endblock %}