11from urllib .parse import urljoin
22from django .conf import settings
3+ from conferences .frontend import trigger_frontend_revalidate
34from grants .tasks import get_name
45from notifications .models import EmailTemplate , EmailTemplateIdentifier
56from strawberry .scalars import JSON
2021from i18n .strings import LazyI18nString
2122from languages .models import Language
2223from participants .models import Participant
23- from submissions .models import Submission as SubmissionModel
24+ from submissions .models import ProposalMaterial , Submission as SubmissionModel
2425from submissions .tasks import notify_new_cfp_submission
2526
26- from .types import Submission
27+ from .types import Submission , SubmissionMaterialInput
2728
2829FACEBOOK_LINK_MATCH = re .compile (r"^http(s)?:\/\/(www\.)?facebook\.com\/" )
2930LINKEDIN_LINK_MATCH = re .compile (r"^http(s)?:\/\/(www\.)?linkedin\.com\/" )
3031
3132
33+ @strawberry .type
34+ class ProposalMaterialErrors :
35+ file_id : list [str ] = strawberry .field (default_factory = list )
36+ url : list [str ] = strawberry .field (default_factory = list )
37+ id : list [str ] = strawberry .field (default_factory = list )
38+
39+
3240@strawberry .type
3341class SendSubmissionErrors (BaseErrorType ):
3442 @strawberry .type
@@ -46,6 +54,7 @@ class _SendSubmissionErrors:
4654 audience_level : list [str ] = strawberry .field (default_factory = list )
4755 tags : list [str ] = strawberry .field (default_factory = list )
4856 short_social_summary : list [str ] = strawberry .field (default_factory = list )
57+ materials : list [ProposalMaterialErrors ] = strawberry .field (default_factory = list )
4958
5059 speaker_bio : list [str ] = strawberry .field (default_factory = list )
5160 speaker_photo : list [str ] = strawberry .field (default_factory = list )
@@ -247,6 +256,22 @@ class UpdateSubmissionInput(BaseSubmissionInput):
247256
248257 topic : Optional [ID ] = strawberry .field (default = None )
249258 tags : list [ID ] = strawberry .field (default_factory = list )
259+ materials : list [SubmissionMaterialInput ] = strawberry .field (default_factory = list )
260+
261+ def validate (self , conference : Conference , submission : SubmissionModel ):
262+ errors = super ().validate (conference )
263+
264+ if self .materials :
265+ if len (self .materials ) > 3 :
266+ errors .add_error (
267+ "non_field_errors" , "You can only add up to 3 materials"
268+ )
269+ else :
270+ for index , material in enumerate (self .materials ):
271+ with errors .with_prefix ("materials" , index ):
272+ material .validate (errors , submission )
273+
274+ return errors
250275
251276
252277SendSubmissionOutput = Annotated [
@@ -276,7 +301,7 @@ def update_submission(
276301
277302 conference = instance .conference
278303
279- errors = input .validate (conference = conference )
304+ errors = input .validate (conference = conference , submission = instance )
280305
281306 if errors .has_errors :
282307 return errors
@@ -294,13 +319,56 @@ def update_submission(
294319 instance .speaker_level = input .speaker_level
295320 instance .previous_talk_video = input .previous_talk_video
296321 instance .short_social_summary = input .short_social_summary
322+
297323 languages = Language .objects .filter (code__in = input .languages ).all ()
298324 instance .languages .set (languages )
299325
300326 instance .tags .set (input .tags )
301327
302328 instance .save ()
303329
330+ materials_to_create = []
331+ materials_to_update = []
332+
333+ existing_materials = {
334+ existing_material .id : existing_material
335+ for existing_material in instance .materials .all ()
336+ }
337+ for material in input .materials :
338+ existing_material = (
339+ existing_materials .get (int (material .id )) if material .id else None
340+ )
341+
342+ if existing_material :
343+ existing_material .name = material .name
344+ existing_material .url = material .url
345+ existing_material .file_id = material .file_id
346+ materials_to_update .append (existing_material )
347+ else :
348+ materials_to_create .append (
349+ ProposalMaterial (
350+ proposal = instance ,
351+ name = material .name ,
352+ url = material .url ,
353+ file_id = material .file_id ,
354+ )
355+ )
356+
357+ if to_delete := [
358+ m .id for m in existing_materials .values () if m not in materials_to_update
359+ ]:
360+ ProposalMaterial .objects .filter (
361+ proposal = instance ,
362+ id__in = to_delete ,
363+ ).delete ()
364+
365+ if materials_to_create :
366+ ProposalMaterial .objects .bulk_create (materials_to_create )
367+ if materials_to_update :
368+ ProposalMaterial .objects .bulk_update (
369+ materials_to_update , fields = ["name" , "url" , "file_id" ]
370+ )
371+
304372 Participant .objects .update_or_create (
305373 user_id = request .user .id ,
306374 conference = conference ,
@@ -319,6 +387,8 @@ def update_submission(
319387 },
320388 )
321389
390+ trigger_frontend_revalidate (conference , instance )
391+
322392 instance .__strawberry_definition__ = Submission .__strawberry_definition__
323393 return instance
324394
0 commit comments