diff --git a/Dockerfile b/Dockerfile index 04d4590d..47aff2e6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/furthemore/apis:apis-base-11fb148 +FROM ghcr.io/furthemore/apis:apis-base-35aadf5 LABEL org.opencontainers.image.source="https://github.com/furthemore/APIS" diff --git a/DockerfileBase b/DockerfileBase index 13d1144e..8eef64d2 100644 --- a/DockerfileBase +++ b/DockerfileBase @@ -5,8 +5,8 @@ COPY ./requirements.txt /app WORKDIR /app RUN apt-get update && apt-get -y install python3-psycopg2 ca-certificates xfonts-75dpi xfonts-base -RUN wget -nv https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb -RUN dpkg -i wkhtmltox_0.12.6-1.buster_amd64.deb +RUN wget -nv https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6.1-3/wkhtmltox_0.12.6.1-3.bullseye_amd64.deb +RUN dpkg -i wkhtmltox_0.12.6.1-3.bullseye_amd64.deb RUN apt-get -y -f install RUN pip install --upgrade pip diff --git a/registration/admin.py b/registration/admin.py index ecb71aec..5e5fe659 100644 --- a/registration/admin.py +++ b/registration/admin.py @@ -1148,7 +1148,7 @@ class BadgeAdmin(NestedModelAdmin, ImportExportModelAdmin): "badgeName", "badgeNumber", ] - readonly_fields = ["get_age_range", "registrationToken"] + readonly_fields = ["get_age_range", "registrationToken", "image_signature"] actions = [ assign_badge_numbers, print_badges, @@ -1165,12 +1165,16 @@ class BadgeAdmin(NestedModelAdmin, ImportExportModelAdmin): "printed", ("badgeName", "badgeNumber", "get_age_range"), ("registeredDate", "event", "registrationToken"), + "image_signature", "attendee", ) }, ), ) + def image_signature(self, obj): + return format_html('', obj.signature_bitmap) + def get_age_range(self, obj): try: born = obj.attendee.birthdate diff --git a/registration/migrations/0101_auto_20240630_0045.py b/registration/migrations/0101_auto_20240630_0045.py new file mode 100644 index 00000000..ced95c25 --- /dev/null +++ b/registration/migrations/0101_auto_20240630_0045.py @@ -0,0 +1,28 @@ +# Generated by Django 3.2.25 on 2024-06-30 04:45 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('registration', '0100_webhook_type'), + ] + + operations = [ + migrations.AlterField( + model_name='badge', + name='signature_bitmap', + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name='badge', + name='signature_svg', + field=models.TextField(blank=True, null=True), + ), + migrations.AlterField( + model_name='order', + name='status', + field=models.CharField(choices=[('Pending', 'Pending'), ('Captured', 'Captured'), ('Completed', 'Completed'), ('Refunded', 'Refunded'), ('Refund Pending', 'Refund Pending'), ('Failed', 'Failed'), ('Dispute Evidence Required', 'Dispute Evidence Required'), ('Dispute Processing', 'Dispute Processing'), ('Dispute Won', 'Dispute Won'), ('Dispute Lost', 'Dispute Lost'), ('Dispute Accepted', 'Dispute Accepted')], default='Pending', max_length=50), + ), + ] diff --git a/registration/models.py b/registration/models.py index 8172192e..27341258 100644 --- a/registration/models.py +++ b/registration/models.py @@ -428,12 +428,8 @@ class Badge(models.Model): badgeNumber = models.IntegerField(null=True, blank=True) printed = models.BooleanField(default=False) printCount = models.IntegerField(default=0) - signature_svg = models.FileField( - upload_to=badge_signature_svg_path, null=True, blank=True - ) - signature_bitmap = models.ImageField( - upload_to=badge_signature_bitmap_path, null=True, blank=True - ) + signature_svg = models.TextField(null=True, blank=True) + signature_bitmap = models.TextField(null=True, blank=True) def __str__(self): if self.badgeNumber is not None or self.badgeNumber == "": diff --git a/registration/static/js/jSignature.min.js b/registration/static/js/jSignature.min.js new file mode 100644 index 00000000..93e1c5ce --- /dev/null +++ b/registration/static/js/jSignature.min.js @@ -0,0 +1,83 @@ +;(function($){ +/* + +jSignature v2 "2018-11-06T13:56" "commit ID 89c22b348ab2e1d92a928d8fd992f175e8bc5cbd" +Copyright (c) 2012 Willow Systems Corp http://willow-systems.com +Copyright (c) 2010 Brinley Ang http://www.unbolt.net +MIT License + + +Simplify.js BSD +(c) 2012, Vladimir Agafonkin +mourner.github.com/simplify-js + + +base64 encoder +MIT, GPL +http://phpjs.org/functions/base64_encode ++ original by: Tyler Akins (http://rumkin.com) ++ improved by: Bayron Guevara ++ improved by: Thunder.m ++ improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) ++ bugfixed by: Pellentesque Malesuada ++ improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net) ++ improved by: Rafal Kukawski (http://kukawski.pl) + + +jSignature v2 jSignature's Undo Button and undo functionality plugin + + +jSignature v2 jSignature's custom "base30" format export and import plugins. + + +jSignature v2 SVG export plugin. + +*/ +(function(){function q(a){var b=a.css("color"),c;a=a[0];for(var g=!1;a&&!c&&!g;){try{var d=$(a).css("background-color")}catch(l){d="transparent"}"transparent"!==d&&"rgba(0, 0, 0, 0)"!==d&&(c=d);g=a.body;a=a.parentNode}a=/rgb[a]*\((\d+),\s*(\d+),\s*(\d+)/;g=/#([AaBbCcDdEeFf\d]{2})([AaBbCcDdEeFf\d]{2})([AaBbCcDdEeFf\d]{2})/;d=void 0;if(d=b.match(a))var m={r:parseInt(d[1],10),g:parseInt(d[2],10),b:parseInt(d[3],10)};else(d=b.match(g))&&(m={r:parseInt(d[1],16),g:parseInt(d[2],16),b:parseInt(d[3],16)}); +if(c)if(d=void 0,d=c.match(a))var e={r:parseInt(d[1],10),g:parseInt(d[2],10),b:parseInt(d[3],10)};else(d=c.match(g))&&(e={r:parseInt(d[1],16),g:parseInt(d[2],16),b:parseInt(d[3],16)});else e=m?127').appendTo(g);this.isCanvasEmulator=!1;b=this.canvas=this.initializeCanvas(e);c=$(b);this.$controlbarLower=$('
').appendTo(g); +this.canvasContext=b.getContext("2d");c.data("jSignature.this",this);e.lineWidth=function(a,b){return a?a:Math.max(Math.round(b/400),2)}(e.lineWidth,b.width);this.lineCurveThreshold=3*e.lineWidth;e.cssclass&&""!=$.trim(e.cssclass)&&c.addClass(e.cssclass);this.fatFingerCompensation=0;g=function(a){var b,c,d=function(d){d=d.changedTouches&&0e.minFatFingerCompensation?-3*e.lineWidth:e.minFatFingerCompensation;b(g);m?(d.addEventListener("touchend",a),d.addEventListener("touchstart",b),d.addEventListener("touchmove",c)): +(d.ontouchend=a,d.ontouchstart=b,d.ontouchmove=c)};m?d.addEventListener("touchstart",this.ontouchstart):d.ontouchstart=ontouchstart;d.onmousedown=function(g){m?d.removeEventListener("touchstart",this.ontouchstart):d.ontouchstart=d.ontouchend=d.ontouchmove=void 0;b(g);d.onmousedown=b;d.onmouseup=a;d.onmousemove=c};window.navigator.msPointerEnabled&&(d.onmspointerdown=b,d.onmspointerup=a,d.onmspointermove=c)}}).call(this,g.drawEndHandler,g.drawStartHandler,g.drawMoveHandler);a["jSignature.windowmouseup"]= +d.subscribe("jSignature.windowmouseup",g.drawEndHandler);this.events.publish("jSignature.attachingEventHandlers");n.call(this,this,e.width.toString(10),"jSignature",d);this.resetCanvas(e.data);this.events.publish("jSignature.initialized");return this}function x(a){if(a.getContext)return!1;var b=a.ownerDocument.parentWindow,c=b.FlashCanvas?a.ownerDocument.parentWindow.FlashCanvas:"undefined"===typeof FlashCanvas?void 0:FlashCanvas;if(c){a=c.initElement(a);c=1;b&&b.screen&&b.screen.deviceXDPI&&b.screen.logicalXDPI&& +(c=1*b.screen.deviceXDPI/b.screen.logicalXDPI);if(1!==c)try{$(a).children("object").get(0).resize(Math.ceil(a.width*c),Math.ceil(a.height*c)),a.getContext("2d").scale(c,c)}catch(g){}return!0}throw Error("Canvas element does not support 2d context. jSignature cannot proceed.");}var v=function(a,b){var c;this.kick=function(){clearTimeout(c);c=setTimeout(b,a)};this.clear=function(){clearTimeout(c)};return this},u=function(a){this.topics={};this.context=a?a:this;this.publish=function(a,c,g,d){if(this.topics[a]){var b= +this.topics[a],e=Array.prototype.slice.call(arguments,1),f=[],h=[],t;var k=0;for(t=b.length;kthis.lineCurveThreshold){var l= +2this.lineCurveThreshold)if(1').appendTo(this.$controlbarLower),k=h.width();h.css("left",Math.round((this.canvas.width-k)/2));k!==h.width()&&h.width(k);return h});q.call(this,h,"jSignature",k)}})})})(); +(function(){for(var q={},k={},h="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX".split(""),p=h.length/2,n=p-1;-1f&&0c&&(c=1,a.push("Y")),d=Math.abs(f),d>=p?a.push(w(d.toString(p))):a.push(d.toString(p));return a.join("")},v=function(e){var a= +[];e=e.split("");for(var b=e.length,c,g=1,d=[],f=0,h=0;ha?(a=2e){a=(new k(f.x[a-2],f.y[a-2])).getVectorToPoint(c);c=b.angleTo(a.reverse());var g=.35*b.getLength();a=(new q(a.x+b.x,a.y+b.y)).resizeTo(Math.max(.05,c)*g);return["c",h(a.x,2),h(a.y,2),h(b.x, +2),h(b.y,2),h(b.x,2),h(b.y,2)]}return["l",h(b.x,2),h(b.y,2)]}function w(f,e,a){e=["M",h(f.x[0]-e,2),h(f.y[0]-a,2)];a=1;for(var b=f.x.length-1;a',''],b,c=f.length,g,d=[],h=[],k=g=b=0,l=0,p=[];if(0!==c){for(b=0;bc?0:c;l=0>d?0:d;b-=c;g=h-d}a.push('');b=0;for(c=p.length;b');a.push("");return a.join("")}function u(f,e){return["image/svg+xml",v(f,e)]}function y(f,e){return["image/svg+xml;base64",C(v(f,e))]}(function(f,e){"use strict"; +f.simplify=function(a,b,c){b=b!==e?b*b:1;if(!c){var g=a.length,d=a[0],f=[d];for(c=1;cb&&(f.push(h),d=h)}a=(d!==h&&f.push(h),f)}h=a;c=h.length;g=new (typeof Uint8Array!=e+""?Uint8Array:Array)(c);d=0;f=c-1;var p,q=[],r=[],y=[];for(g[d]=g[f]=1;f;){n=0;for(k=d+1;kn&&(p=k,n=A)}n>b&&(g[p]=1,q.push(d),r.push(p),q.push(p),r.push(f));d=q.pop();f=r.pop()}for(k=0;k>18&63;d=k>>12&63;h=k>>6&63;k&=63;c[b++]=e[g]+e[d]+e[h]+e[k]}while(aPlacement Options
-
-
- -
-
-
- + {% include "templatetags/coc_sig.html" %}
@@ -335,6 +323,14 @@

Placement Options

return; } + let signature = $("#jsign_signature"); + let nativeData = signature.jSignature("getData", "native"); + if (nativeData.length < 2) { + alert("You must sign to acknowledge your acceptance of the Code of Conduct."); + $("#register").one('click', register_click); + return; + } + var data = { 'attendee': { 'firstName': $("#firstName").val(), @@ -351,7 +347,9 @@

Placement Options

'birthdate': $("#birthDate").val(), 'emailsOk': $("#contact").is(':checked'), 'surveyOk': $("#survey").is(':checked'), - 'badgeName': $("#badgename").val() + 'badgeName': $("#badgename").val(), + 'signature_svg': signature.jSignature("getData", "svgbase64")[1], + 'signature_bitmap': signature.jSignature("getData", "image")[1] }, 'dealer': { 'businessName': $("#businessName").val(), 'website': $("#website").val(), 'logo': $("#logo").val(), diff --git a/registration/templates/registration/emails/registration-payment.html b/registration/templates/registration/emails/registration-payment.html index 62439b3f..5a84ec06 100644 --- a/registration/templates/registration/emails/registration-payment.html +++ b/registration/templates/registration/emails/registration-payment.html @@ -555,7 +555,7 @@

One or more of the attendees in this order will still be minors at the start of {{ event }}. Please note that we require a parent or guardian to be present at registration to sign our consent form for all minor attendees. Any attendee under the age of 13 (by the start of the convention) must have a parent or guardian also register and accompany them during the event.

{% endif %} -

This email is for your records only. You will not need the confirmation number to pick up your badge. In order to pick up your badge on-site, you will only need to bring your Government Issued Photo ID and Vaccine proof to the registration desk.

+

This email is for your records only. You will not need the confirmation number to pick up your badge. In order to pick up your badge on-site, you will only need to bring your Government Issued Photo ID to the registration desk.

If you have any questions about your order, please contact us at {{ event.registrationEmail }}

Thanks,
{{ event }} Registration Team

diff --git a/registration/templates/registration/emails/registration-payment.txt b/registration/templates/registration/emails/registration-payment.txt index 87018eb3..d79f6732 100644 --- a/registration/templates/registration/emails/registration-payment.txt +++ b/registration/templates/registration/emails/registration-payment.txt @@ -49,7 +49,7 @@ consent form for all minor attendees. Any attendee under the age of 13 (by the s must have a parent or guardian also register and accompany them during the event. {% endif %} -This email is for your records only. You will not need the confirmation number to pick up your badge. In order to pick up your badge on-site, you will only need to bring your Government Issued Photo ID and Vaccine proof to the registration desk. +This email is for your records only. You will not need the confirmation number to pick up your badge. In order to pick up your badge on-site, you will only need to bring your Government Issued Photo ID to the registration desk. If you have any questions about your order, please contact us at {{ event.registrationEmail }}. diff --git a/registration/templates/registration/master.html b/registration/templates/registration/master.html index c65a5540..e5189a30 100644 --- a/registration/templates/registration/master.html +++ b/registration/templates/registration/master.html @@ -70,6 +70,7 @@ + {% block javascript %} {% endblock %} diff --git a/registration/templates/registration/registration-form.html b/registration/templates/registration/registration-form.html index 623768cf..574b4167 100644 --- a/registration/templates/registration/registration-form.html +++ b/registration/templates/registration/registration-form.html @@ -52,7 +52,7 @@

Pre-Register for {{ event }}!

Select your registration options and level.


- +
@@ -60,7 +60,7 @@

Select your registration options and level.

- +
- I agree to abide by the {{ event.name }} Code of - Conduct. By registering for {{ event }} you attest that you are not listed on any sexual offender - registry. - -
-
-
+ + {% include "templatetags/coc_sig.html" %}
 
@@ -422,6 +412,14 @@

} let birthdate = parseDate(birthdate_str); + let signature = $("#jsign_signature"); + let nativeData = signature.jSignature("getData", "native"); + if (nativeData.length < 2) { + alert("You must sign to acknowledge your acceptance of the Code of Conduct."); + $("#register").one('click', register_click); + return; + } + {% if not event.allowOnlineMinorReg %} let age = getAgeByEventStart(birthdate); if (age < 18) { @@ -449,6 +447,8 @@

'volDepts': $("#volunteer").val(), 'surveyOk': $("#survey").is(':checked'), 'asl': false, + 'signature_svg': signature.jSignature("getData", "svgbase64")[1], + 'signature_bitmap': signature.jSignature("getData", "image")[1] }, 'priceLevel': {'id': $(".selectLevel")[0].id.split('_')[1], 'options': getOptions()}, 'event': '{{event}}' diff --git a/registration/templates/registration/signature.html b/registration/templates/registration/signature.html deleted file mode 100644 index 206145d5..00000000 --- a/registration/templates/registration/signature.html +++ /dev/null @@ -1,48 +0,0 @@ -{% extends "registration/master_admin.html" %} -{% load static %} - -{% block head %} - -{% endblock %} - -{% block content %} - - - -

Badge Collection

-
-
-
-
-
- - - - -
-
-
-
-
- -
-
-
- -
- - - -{% endblock %} - -{% block javascript %} -{% endblock %} diff --git a/registration/templates/templatetags/coc_sig.html b/registration/templates/templatetags/coc_sig.html new file mode 100644 index 00000000..1170ce19 --- /dev/null +++ b/registration/templates/templatetags/coc_sig.html @@ -0,0 +1,33 @@ +{% load registration_tags static %} + +
+
+ +
+
+
+
Please Sign Below:
+
+
+ + + + \ No newline at end of file diff --git a/registration/tests/common.py b/registration/tests/common.py index bfd44a05..62b1d186 100644 --- a/registration/tests/common.py +++ b/registration/tests/common.py @@ -287,6 +287,7 @@ def setUp(self): "volunteer": "false", "volDepts": "", "surveyOk": "false", + "signature_svg": "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmVyc2lvbj0iMS4xIiB3aWR0aD0iNjI3IiBoZWlnaHQ9IjkwIj48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSJyZ2IoODUsIDg1LCA4NSkiIGZpbGw9Im5vbmUiIGQ9Ik0gMSA1NSBjIDAuMDUgLTAuMjEgMS4yIC04LjU5IDMgLTEyIGMgNC4yIC03Ljk1IDEwLjE2IC0xNi41NSAxNiAtMjQgYyAzLjcyIC00Ljc1IDguNDYgLTkuMjkgMTMgLTEzIGMgMi41NCAtMi4wOCA2LjE1IC0zLjk4IDkgLTUgYyAxLjM4IC0wLjQ5IDMuNzkgLTAuNjEgNSAwIGMgMi4yNCAxLjEyIDYuMzYgMy42IDcgNiBjIDMgMTEuMzEgNC40OSAyOC4zNiA2IDQzIGMgMC44NyA4LjQ0IDAuMjcgMTYuNzcgMSAyNSBjIDAuMjcgMy4wMyAxLjAzIDYuMjcgMiA5IGMgMC42MiAxLjczIDEuNjYgNC44MiAzIDUgYyA2LjE5IDAuODMgMTguMjMgMC41MyAyNyAtMSBjIDI1LjI5IC00LjQyIDQ5LjY3IC0xMS40NCA3NiAtMTcgYyAxMS4zNCAtMi4zOSAyMS44MSAtNC40IDMzIC02IGMgNS4zNSAtMC43NiAxMC41IC0wLjg2IDE2IC0xIGMgNy41NCAtMC4yIDE1LjIxIC0wLjk0IDIyIDAgYyA0LjU5IDAuNjQgOS40NyAyLjk5IDE0IDUgYyA0LjUgMiA4Ljc0IDUuMiAxMyA3IGMgMS43NiAwLjc0IDMuOTggMC45MyA2IDEgYyA4LjI5IDAuMjcgMTYuNjggMC41NSAyNSAwIGMgNi43MyAtMC40NSAyMCAtMyAyMCAtMyIvPjxwYXRoIHN0cm9rZS1saW5lam9pbj0icm91bmQiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9InJnYig4NSwgODUsIDg1KSIgZmlsbD0ibm9uZSIgZD0iTSAyMDUgMzggYyAwLjI1IDAgOS4zOCAwLjQ5IDE0IDAgYyA4LjAyIC0wLjg0IDE1LjgzIC0zLjIzIDI0IC00IGMgMTMuNDQgLTEuMjYgMjYuMjEgLTEuODQgNDAgLTIgYyA0NC4wOCAtMC41MiA4NC44OCAtMS43NSAxMjggMCBjIDIzLjQgMC45NSA0NS41NiA0LjMgNjkgOCBjIDI4LjUzIDQuNSA1NS4wMyAxMC4xNyA4MyAxNiBjIDQuNSAwLjk0IDguNTMgMy4xNSAxMyA0IGMgMTYuNjMgMy4xNyA1MCA4IDUwIDgiLz48L3N2Zz4=", } self.attendee_form_2 = { "firstName": "Bea", diff --git a/registration/tests/test_webhooks.py b/registration/tests/test_webhooks.py index 3bda8530..0337085a 100644 --- a/registration/tests/test_webhooks.py +++ b/registration/tests/test_webhooks.py @@ -1,7 +1,7 @@ import json from unittest.mock import patch -from django.test import TestCase +from django.test import TestCase, tag from django.test.utils import override_settings from django.urls import reverse @@ -31,6 +31,7 @@ class TestSquareRefundWebhooks(TestCase): SIGNATURE_KEY = "bj-4rZKxCc8_1CZtghoatg" NOTIFICATION_URL = "https://webhook.site/5477eda8-952e-4844-91db-8b10cf228833" + @tag("square") @override_settings(SQUARE_WEBHOOK_SIGNATURE_KEY=SIGNATURE_KEY) @patch("django.http.request.HttpRequest.build_absolute_uri") def test_square_webhook(self, mock_build_absolute_uri): @@ -48,6 +49,7 @@ def test_square_webhook(self, mock_build_absolute_uri): self.assertEqual(str(webhook.event_id), webhook.body["event_id"]) self.assertEqual(webhook.event_type, webhook.body["type"]) + @tag("square") @override_settings(SQUARE_WEBHOOK_SIGNATURE_KEY=SIGNATURE_KEY) @patch("django.http.request.HttpRequest.build_absolute_uri") def test_square_webhook_invalid_signature(self, mock_build_absolute_uri): @@ -62,6 +64,7 @@ def test_square_webhook_invalid_signature(self, mock_build_absolute_uri): self.assertTrue(response.status_code, 403) + @tag("square") @override_settings(SQUARE_WEBHOOK_SIGNATURE_KEY=SIGNATURE_KEY) @patch("square.utilities.webhooks_helper.is_valid_webhook_event_signature") @patch("django.http.request.HttpRequest.build_absolute_uri") @@ -81,6 +84,7 @@ def test_square_webhook_invalid_json( self.assertTrue(response.status_code, 400) self.assertIn(b"Unable to decode JSON", response.content) + @tag("square") @override_settings(SQUARE_WEBHOOK_SIGNATURE_KEY=SIGNATURE_KEY) @patch("square.utilities.webhooks_helper.is_valid_webhook_event_signature") @patch("django.http.request.HttpRequest.build_absolute_uri") @@ -100,6 +104,7 @@ def test_square_webhook_missing_event_id( self.assertTrue(response.status_code, 400) self.assertIn(b"Missing event_id", response.content) + @tag("square") @override_settings(SQUARE_WEBHOOK_SIGNATURE_KEY=SIGNATURE_KEY) @patch("django.http.request.HttpRequest.build_absolute_uri") def test_square_webhook_idempotency(self, mock_build_absolute_uri): @@ -246,6 +251,7 @@ def setUp(self) -> None: self.order_item.save() self.order.refresh_from_db() + @tag("square") @override_settings(SQUARE_WEBHOOK_SIGNATURE_KEY=SIGNATURE_KEY) @patch("django.http.request.HttpRequest.build_absolute_uri") def test_dispute_webhook(self, mock_build_absolute_uri): @@ -275,6 +281,7 @@ def test_dispute_webhook(self, mock_build_absolute_uri): self.assertEqual(self.attendee.firstName, ban_list.firstName) self.assertEqual(self.attendee.lastName, ban_list.lastName) + @tag("square") @override_settings(SQUARE_WEBHOOK_SIGNATURE_KEY=SIGNATURE_KEY) @patch("django.http.request.HttpRequest.build_absolute_uri") def test_dispute_payment_id_not_found(self, mock_build_absolute_uri): diff --git a/registration/urls.py b/registration/urls.py index 109e9161..f29d12d7 100644 --- a/registration/urls.py +++ b/registration/urls.py @@ -253,16 +253,6 @@ def trigger_error(request): registration.views.onsite_admin.no_sale, name="no_sale", ), - url( - r"^onsite/signature/?$", - registration.views.onsite_admin.onsite_signature, - name="onsite_signature", - ), - url( - r"^onsite/admin/signature/?$", - registration.views.onsite_admin.onsite_signature_prompt, - name="onsite_signature_prompt", - ), url( r"^onsite/admin/discount/create/?$", registration.views.onsite_admin.create_discount, diff --git a/registration/views/cart.py b/registration/views/cart.py index 6e4d51a1..cd5cf809 100644 --- a/registration/views/cart.py +++ b/registration/views/cart.py @@ -162,7 +162,7 @@ def saveCart(cart): ) attendee.save() - badge = Badge(badgeName=pda["badgeName"], event=event, attendee=attendee) + badge = Badge(badgeName=pda["badgeName"], event=event, attendee=attendee, signature_svg=pda.get("signature_svg"), signature_bitmap=pda.get("signature_bitmap")) badge.save() priceLevel = PriceLevel.objects.get(id=int(pdp["id"])) diff --git a/registration/views/onsite_admin.py b/registration/views/onsite_admin.py index 46148172..b3677890 100644 --- a/registration/views/onsite_admin.py +++ b/registration/views/onsite_admin.py @@ -367,11 +367,6 @@ def admin_push_cart_refresh(request): send_mqtt_message(topic, None) -def onsite_signature(request): - context = {} - return render(request, "registration/signature.html", context) - - # TODO: update for square SDK data type (fetch txn from square API and store in order.apiData) @csrf_exempt def complete_square_transaction(request): @@ -880,17 +875,6 @@ def onsite_admin_cart(request): return JsonResponse(data) -@staff_member_required() -def onsite_signature_prompt(request): - data = { - "command": "signature", - "name": "Kasper Finch", - "agreement": "I have read and agree to the FurTheMore 2020 Code of Conduct", - "badge_id": "5", - } - return send_message_to_terminal(request, data) - - @staff_member_required def onsite_add_to_cart(request): id = request.GET.get("id", None)