Skip to content

Commit d7f9453

Browse files
Hieu Lam - TMAkhangonodkhang
authored
feature-8683: Add Options for Badges in Wizard (#8968)
* feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard implemnent save badge * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard fix UI bug * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * thanhhieu-tma/feature-8683: Add print QR code * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Add Options for Badges in Wizard * feature-8683: Merge code development * feature-8683: Merge code development * feature-8683: Merge code development * feature-8683: Merge code development * feature-8683: Merge code development * feature-8683: Merge code development * feature-8683: Add Options for Badges in Wizard * feature-8683: EVENTYAY ID in CVF should be the id of ticket holder. --------- Co-authored-by: Khang On - TMA <[email protected]> Co-authored-by: khangon <[email protected]>
1 parent e7e0779 commit d7f9453

26 files changed

+1171
-5
lines changed

app/api/badge_field_forms.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
2+
from flask_rest_jsonapi.exceptions import ObjectNotFound
3+
4+
from app.api.helpers.permission_manager import has_access
5+
from app.api.helpers.permissions import jwt_required
6+
from app.api.helpers.utilities import require_relationship
7+
from app.api.schema.badge_field_forms import BadgeFieldFormSchema
8+
from app.models import db
9+
from app.models.badge_field_form import BadgeFieldForms
10+
11+
12+
class BadgeFieldFormList(ResourceList):
13+
"""Create and List Custom Form Translates"""
14+
15+
def query(self, view_kwargs):
16+
"""
17+
query method for different view_kwargs
18+
:param view_kwargs:
19+
:return:
20+
"""
21+
query_ = self.session.query(BadgeFieldForms)
22+
if view_kwargs.get('badge_form_id'):
23+
query_ = query_.filter_by(badge_forms_id=view_kwargs['badge_form_id'])
24+
return query_
25+
26+
schema = BadgeFieldFormSchema
27+
data_layer = {
28+
'session': db.session,
29+
'model': BadgeFieldForms,
30+
'methods': {'query': query},
31+
}
32+
33+
34+
class BadgeFieldFormDetail(ResourceDetail):
35+
"""BadgeFieldForm Resource Detail"""
36+
37+
schema = BadgeFieldFormSchema
38+
data_layer = {'session': db.session, 'model': BadgeFieldForms}
39+
40+
41+
class BadgeFieldFormRelationship(ResourceRelationship):
42+
"""BadgeFieldForm Relationship (Required)"""
43+
44+
decorators = (jwt_required,)
45+
methods = ['GET', 'PATCH']
46+
schema = BadgeFieldFormSchema
47+
data_layer = {'session': db.session, 'model': BadgeFieldForms}
48+
49+
50+
class BadgeFieldFormListPost(ResourceList):
51+
"""Create and List Custom Form Translates"""
52+
53+
@staticmethod
54+
def before_post(data):
55+
"""
56+
method to check for required relationship with event
57+
:param data:
58+
:return:
59+
"""
60+
require_relationship(['badge_form'], data)
61+
if not has_access('is_coorganizer', badge_form=data['badge_form']):
62+
raise ObjectNotFound(
63+
{'parameter': 'badge_form'},
64+
f"Custom Form: {data['badge_form']} not found",
65+
)
66+
67+
schema = BadgeFieldFormSchema
68+
methods = [
69+
'POST',
70+
]
71+
data_layer = {'session': db.session, 'model': BadgeFieldForms}

app/api/badge_forms.py

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
from flask_rest_jsonapi import ResourceDetail, ResourceList, ResourceRelationship
2+
from flask_rest_jsonapi.exceptions import ObjectNotFound
3+
4+
from app.api.bootstrap import api
5+
from app.api.data_layers.BadgeFormLayer import BadgeFormLayer
6+
from app.api.helpers.db import safe_query, safe_query_kwargs
7+
from app.api.helpers.permission_manager import has_access
8+
from app.api.helpers.permissions import jwt_required
9+
from app.api.helpers.query import event_query
10+
from app.api.helpers.utilities import require_relationship
11+
from app.api.schema.badge_forms import BadgeFormSchema
12+
from app.models import db
13+
from app.models.badge_field_form import BadgeFieldForms
14+
from app.models.badge_form import BadgeForms
15+
from app.models.event import Event
16+
17+
18+
class BadgeFormList(ResourceList):
19+
"""Create and List Custom Form Translates"""
20+
21+
def query(self, view_kwargs):
22+
"""
23+
query method for different view_kwargs
24+
:param view_kwargs:
25+
:return:
26+
"""
27+
query_ = self.session.query(BadgeForms)
28+
if view_kwargs.get('badge_id'):
29+
events = safe_query_kwargs(Event, view_kwargs, 'event_id')
30+
query_ = self.session.query(BadgeForms).filter_by(event_id=events.id)
31+
query_ = query_.filter_by(badge_id=view_kwargs.get('badge_id'))
32+
else:
33+
query_ = event_query(query_, view_kwargs)
34+
return query_
35+
36+
@staticmethod
37+
def after_get(badge_forms):
38+
"""
39+
query method for different view_kwargs
40+
:param view_kwargs:
41+
:return:
42+
"""
43+
for item in badge_forms['data']:
44+
badgeFields = []
45+
badgeFieldForms = (
46+
BadgeFieldForms.query.filter_by(badge_form_id=item['id'])
47+
.filter_by(badge_id=item['attributes']['badge-id'])
48+
.all()
49+
)
50+
for badgeFieldForm in badgeFieldForms:
51+
badgeFields.append(badgeFieldForm.convert_to_dict())
52+
item['attributes']['badge-fields'] = badgeFields
53+
return badge_forms
54+
55+
view_kwargs = True
56+
decorators = (jwt_required,)
57+
methods = [
58+
'GET',
59+
]
60+
schema = BadgeFormSchema
61+
data_layer = {
62+
'session': db.session,
63+
'model': BadgeForms,
64+
'methods': {'query': query, 'after_get': after_get},
65+
}
66+
67+
68+
class BadgeFormDetail(ResourceDetail):
69+
"""BadgeForm Resource Detail"""
70+
71+
@staticmethod
72+
def before_get_object(view_kwargs):
73+
"""
74+
before get method
75+
:param view_kwargs:
76+
:return:
77+
"""
78+
event = None
79+
if view_kwargs.get('event_id'):
80+
event = safe_query_kwargs(Event, view_kwargs, 'event_id')
81+
elif view_kwargs.get('event_identifier'):
82+
event = safe_query_kwargs(
83+
Event,
84+
view_kwargs,
85+
'event_identifier',
86+
'identifier',
87+
)
88+
89+
if event:
90+
badge_form = safe_query(BadgeForms, 'event_id', event.id, 'event_id')
91+
view_kwargs['id'] = badge_form.id
92+
93+
@staticmethod
94+
def before_patch(_args, kwargs, data):
95+
"""
96+
before patch method
97+
:param _args:
98+
:param kwargs:
99+
:param data:
100+
:return:
101+
"""
102+
badgeFields = data.get('badge_fields')
103+
if badgeFields:
104+
for badgeField in badgeFields:
105+
badgeFieldForm = None
106+
if 'badge_field_id' in badgeField:
107+
badgeFieldForm = BadgeFieldForms.get_badge_field_form_if_exist(
108+
badgeField['badge_field_id'], badgeField['badge_id']
109+
)
110+
if (
111+
badgeFieldForm is not None
112+
and 'is_deleted' in badgeField
113+
and badgeField['is_deleted']
114+
):
115+
db.session.delete(badgeFieldForm)
116+
else:
117+
if badgeFieldForm:
118+
badgeFieldForm.badge_id = data['badge_id']
119+
else:
120+
badgeFieldForm = BadgeFieldForms()
121+
badgeFieldForm.badge_id = data['badge_id']
122+
123+
badgeFieldForm.badge_form_id = kwargs['id']
124+
badgeFieldForm.field_identifier = badgeField['field_identifier']
125+
badgeFieldForm.custom_field = badgeField['custom_field']
126+
badgeFieldForm.sample_text = badgeField['sample_text']
127+
badgeFieldForm.font_name = badgeField['font_name']
128+
badgeFieldForm.font_size = badgeField['font_size']
129+
badgeFieldForm.font_color = badgeField['font_color']
130+
badgeFieldForm.font_weight = badgeField['font_weight']
131+
badgeFieldForm.text_rotation = badgeField['text_rotation']
132+
badgeFieldForm.text_alignment = badgeField['text_alignment']
133+
badgeFieldForm.text_type = badgeField['text_type']
134+
badgeFieldForm.margin_top = badgeField['margin_top']
135+
badgeFieldForm.margin_bottom = badgeField['margin_bottom']
136+
badgeFieldForm.margin_left = badgeField['margin_left']
137+
badgeFieldForm.margin_right = badgeField['margin_right']
138+
badgeFieldForm.qr_custom_field = badgeField.get('qr_custom_field')
139+
badgeFieldForm.is_deleted = badgeField['is_deleted']
140+
db.session.add(badgeFieldForm)
141+
142+
@staticmethod
143+
def before_delete(_obj, kwargs):
144+
"""
145+
before delete method
146+
:param _obj:
147+
:param kwargs:
148+
:return:
149+
"""
150+
badgeFieldForm = BadgeFieldForms.query.filter_by(badge_form_id=kwargs['id']).all()
151+
for item in badgeFieldForm:
152+
db.session.delete(item)
153+
154+
@staticmethod
155+
def after_patch(badge_form):
156+
"""
157+
after patch method
158+
:param badge_form:
159+
:return:
160+
"""
161+
badgeFields = []
162+
data = badge_form['data']
163+
attributes = data['attributes']
164+
badgeFieldForms = (
165+
BadgeFieldForms.query.filter_by(badge_form_id=data['id'])
166+
.filter_by(badge_id=attributes['badge-id'])
167+
.all()
168+
)
169+
for badgeFieldForm in badgeFieldForms:
170+
badgeFields.append(badgeFieldForm.convert_to_dict())
171+
attributes['badge-fields'] = badgeFields
172+
return badge_form
173+
174+
decorators = (
175+
api.has_permission(
176+
'is_coorganizer',
177+
fetch='event_id',
178+
model=BadgeForms,
179+
methods="PATCH,DELETE",
180+
),
181+
)
182+
schema = BadgeFormSchema
183+
data_layer = {
184+
'session': db.session,
185+
'model': BadgeForms,
186+
'methods': {
187+
'before_patch': before_patch,
188+
'before_delete': before_delete,
189+
'after_patch': after_patch,
190+
},
191+
}
192+
193+
194+
class BadgeFormRelationship(ResourceRelationship):
195+
"""BadgeForm Relationship (Required)"""
196+
197+
decorators = (jwt_required,)
198+
methods = ['GET', 'PATCH']
199+
schema = BadgeFormSchema
200+
data_layer = {'session': db.session, 'model': BadgeForms}
201+
202+
203+
class BadgeFormListPost(ResourceList):
204+
"""Create and List Custom Form Translates"""
205+
206+
@staticmethod
207+
def before_post(_args, _kwargs, data):
208+
"""
209+
method to check for required relationship with event
210+
:param args:
211+
:param kwargs:
212+
:param data:
213+
:return:
214+
"""
215+
require_relationship(['event'], data)
216+
if not has_access('is_coorganizer', event_id=data['event']):
217+
raise ObjectNotFound(
218+
{'parameter': 'event_id'},
219+
f"Event: {data['event_id']} not found",
220+
)
221+
222+
schema = BadgeFormSchema
223+
methods = [
224+
'POST',
225+
]
226+
data_layer = {'class': BadgeFormLayer, 'session': db.session, 'model': BadgeForms}

app/api/custom/badge_forms.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from flask import Blueprint, request
2+
from flask.helpers import send_from_directory
3+
from flask_jwt_extended import jwt_required
4+
5+
from app.api.helpers.badge_forms import create_preivew_badge_pdf, create_print_badge_pdf
6+
from app.api.helpers.errors import ForbiddenError, NotFoundError
7+
from app.api.helpers.permission_manager import has_access
8+
from app.models.badge_form import BadgeForms
9+
from app.models.ticket_holder import TicketHolder
10+
11+
badge_forms_routes = Blueprint(
12+
'badge_forms_routes', __name__, url_prefix='/v1/badge-forms'
13+
)
14+
15+
16+
@badge_forms_routes.route('/preview-badge-pdf', methods=['POST'])
17+
@jwt_required
18+
def preivew_badge_pdf():
19+
"""Preview Badge Template PDF"""
20+
badgeForms = request.json.get('badgeForms')
21+
if badgeForms is None:
22+
raise NotFoundError(
23+
{'source': ''}, 'This badge form is not associated with any ticket'
24+
)
25+
26+
file_path = create_preivew_badge_pdf(badgeForms)
27+
return send_from_directory('../', file_path, as_attachment=True)
28+
29+
30+
@badge_forms_routes.route('/print-badge-pdf', methods=['POST'])
31+
@jwt_required
32+
def print_badge_pdf():
33+
"""Print Badge Template PDF"""
34+
attendee_id = request.json.get('attendee_id')
35+
list_field_show = request.json.get('list_field_show')
36+
ticketHolders = TicketHolder.query.filter_by(id=attendee_id).first()
37+
if ticketHolders is None:
38+
raise NotFoundError(
39+
{'source': ''}, 'This ticket holder is not associated with any ticket'
40+
)
41+
badgeForms = BadgeForms.query.filter_by(
42+
badge_id=ticketHolders.ticket.badge_id
43+
).first()
44+
if badgeForms is None:
45+
raise NotFoundError(
46+
{'source': ''}, 'This badge form is not associated with any ticket'
47+
)
48+
if not has_access('is_coorganizer', event_id=badgeForms.event_id):
49+
raise ForbiddenError({'source': ''}, 'Unauthorized Access')
50+
51+
file_path = create_print_badge_pdf(badgeForms, ticketHolders, list_field_show)
52+
return send_from_directory('../', file_path, as_attachment=True)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from marshmallow import Schema, fields
2+
3+
4+
class BadgeFieldFormSchema(Schema):
5+
"""Badge Field Form Schema"""
6+
7+
badge_field_id = fields.Integer(allow_none=False)
8+
badge_id = fields.String(allow_none=False)
9+
field_identifier = fields.String(allow_none=True)
10+
custom_field = fields.String(allow_none=True)
11+
sample_text = fields.String(allow_none=True)
12+
font_size = fields.Integer(allow_none=True)
13+
font_name = fields.String(allow_none=True)
14+
font_weight = fields.Integer(allow_none=True)
15+
font_color = fields.String(allow_none=True)
16+
text_rotation = fields.Integer(allow_none=True)
17+
text_alignment = fields.String(allow_none=True)
18+
text_type = fields.String(allow_none=True)
19+
badge_field_id = fields.Integer(allow_none=True)
20+
is_deleted = fields.Boolean(allow_none=True, default=False)
21+
margin_top = fields.Integer(allow_none=True)
22+
margin_bottom = fields.Integer(allow_none=True)
23+
margin_left = fields.Integer(allow_none=True)
24+
margin_right = fields.Integer(allow_none=True)
25+
qr_custom_field = fields.List(fields.String(), allow_none=True, default=None)

0 commit comments

Comments
 (0)