Woziii commited on
Commit
015ea7a
·
verified ·
1 Parent(s): 75f2f9e

Update pdf_generator.py

Browse files
Files changed (1) hide show
  1. pdf_generator.py +66 -345
pdf_generator.py CHANGED
@@ -25,172 +25,14 @@ from contract_templates import ContractTemplates # Import this to use title gen
25
  pdfmetrics.registerFont(TTFont('Vera', 'Vera.ttf'))
26
  pdfmetrics.registerFont(TTFont('VeraBd', 'VeraBd.ttf'))
27
 
28
- def _format_physical_person_details(author_info, contract_type, styles):
29
- """
30
- Formate les détails d'une personne physique pour le contrat PDF.
31
-
32
- Args:
33
- author_info (dict): Informations sur l'auteur
34
- contract_type (list): Types de contrat
35
- styles (dict): Styles de paragraphe
36
-
37
- Returns:
38
- list: Éléments de paragraphe pour les détails de l'auteur
39
- """
40
- elements = []
41
- gentille = author_info.get("gentille", "M.")
42
- nom = author_info.get("nom", "")
43
- prenom = author_info.get("prenom", "")
44
- date_naissance = author_info.get("date_naissance", "")
45
- nationalite = author_info.get("nationalite", "")
46
- adresse = author_info.get("adresse", "")
47
- contact = author_info.get("contact", "")
48
-
49
- # Construire la description de l'auteur
50
- author_description = f"{gentille} {prenom} {nom}"
51
- if date_naissance:
52
- author_description += f", né(e) le {date_naissance}"
53
- if nationalite:
54
- author_description += f", de nationalité {nationalite}"
55
- author_description += f", domicilié(e) au {adresse}"
56
- if contact:
57
- author_description += f", joignable à {contact}"
58
-
59
- # Ajouter la description
60
- elements.append(Paragraph(author_description, styles['ContractNormalText']))
61
- elements.append(Spacer(1, 6))
62
-
63
- # Dénomination de l'auteur
64
- if "Auteur (droits d'auteur)" in contract_type and "Image (droit à l'image)" in contract_type:
65
- denomination = "ci-après dénommé(e) \"l'Auteur et le Modèle\","
66
- elif "Auteur (droits d'auteur)" in contract_type:
67
- denomination = "ci-après dénommé(e) \"l'Auteur\","
68
- else:
69
- denomination = "ci-après dénommé(e) \"le Modèle\","
70
-
71
- elements.append(Paragraph(denomination, styles['ContractNormalText']))
72
- elements.append(Spacer(1, 6))
73
-
74
- return elements
75
 
76
- def _format_legal_entity_details(author_info, contract_type, styles):
77
- """
78
- Formate les détails d'une personne morale pour le contrat PDF.
79
-
80
- Args:
81
- author_info (dict): Informations sur l'entité légale
82
- contract_type (list): Types de contrat
83
- styles (dict): Styles de paragraphe
84
-
85
- Returns:
86
- list: Éléments de paragraphe pour les détails de l'entité
87
- """
88
- elements = []
89
- nom_societe = author_info.get("nom_societe", "")
90
- statut = author_info.get("statut", "")
91
- rcs = author_info.get("rcs", "")
92
- siege = author_info.get("siege", "")
93
- contact = author_info.get("contact", "")
94
-
95
- # Construire la description de l'entité
96
- entity_description = f"La société {nom_societe}, {statut}, immatriculée sous le numéro {rcs} au Registre du Commerce et des Sociétés, dont le siège social est situé {siege}"
97
- if contact:
98
- entity_description += f", joignable à {contact}"
99
-
100
- # Ajouter la description
101
- elements.append(Paragraph(entity_description, styles['ContractNormalText']))
102
- elements.append(Spacer(1, 6))
103
-
104
- # Dénomination de l'auteur
105
- if "Auteur (droits d'auteur)" in contract_type and "Image (droit à l'image)" in contract_type:
106
- denomination = "ci-après dénommée \"l'Auteur et le Modèle\","
107
- elif "Auteur (droits d'auteur)" in contract_type:
108
- denomination = "ci-après dénommée \"l'Auteur\","
109
- else:
110
- denomination = "ci-après dénommée \"le Modèle\","
111
-
112
- elements.append(Paragraph(denomination, styles['ContractNormalText']))
113
- elements.append(Spacer(1, 6))
114
-
115
- return elements
116
-
117
- def get_enriched_styles():
118
- """
119
- Retourne des styles enrichis pour la génération du PDF.
120
-
121
- Returns:
122
- dict: Dictionnaire des styles enrichis
123
- """
124
- styles = getSampleStyleSheet()
125
-
126
- # Style pour le titre du contrat
127
- styles.add(ParagraphStyle(
128
- name='ContractTitle',
129
- fontName='VeraBd',
130
- fontSize=16,
131
- alignment=TA_CENTER,
132
- spaceAfter=12,
133
- textColor=black
134
- ))
135
-
136
- # Style pour les titres de section
137
- styles.add(ParagraphStyle(
138
- name='ContractSectionHeader',
139
- fontName='VeraBd',
140
- fontSize=12,
141
- alignment=TA_LEFT,
142
- spaceAfter=6,
143
- textColor=black
144
- ))
145
-
146
- # Style pour les articles principaux
147
- styles.add(ParagraphStyle(
148
- name='ContractArticle',
149
- fontName='VeraBd',
150
- fontSize=12,
151
- alignment=TA_LEFT,
152
- spaceAfter=6,
153
- textColor=black
154
- ))
155
-
156
- # Style pour les sous-articles
157
- styles.add(ParagraphStyle(
158
- name='ContractSubArticle',
159
- fontName='VeraBd',
160
- fontSize=11,
161
- alignment=TA_LEFT,
162
- spaceAfter=6,
163
- textColor=black
164
- ))
165
-
166
- # Style pour le texte normal du contrat
167
- styles.add(ParagraphStyle(
168
- name='ContractNormalText',
169
- fontName='Vera',
170
- fontSize=10,
171
- alignment=TA_JUSTIFY,
172
- spaceAfter=6,
173
- textColor=black
174
- ))
175
-
176
- # Style pour les éléments de liste
177
- styles.add(ParagraphStyle(
178
- name='ContractListItem',
179
- fontName='Vera',
180
- fontSize=10,
181
- alignment=TA_LEFT,
182
- spaceAfter=3,
183
- textColor=black,
184
- leftIndent=20
185
- ))
186
-
187
- return styles
188
 
189
  def generate_pdf(contract_type, is_free, author_type, author_info,
190
  work_description, image_description, supports,
191
  additional_rights, remuneration, is_exclusive):
192
  """
193
- Génère un PDF du contrat avec des champs interactifs et tous les détails.
 
194
 
195
  Args:
196
  contract_type (list): Liste des types de contrats sélectionnés
@@ -217,200 +59,33 @@ def generate_pdf(contract_type, is_free, author_type, author_info,
217
  # Créer un nom de fichier temporaire pour le PDF
218
  output_filename = create_temp_file(prefix="contrat_cession_", suffix=".pdf")
219
 
220
- # Préparer les styles
221
- styles = get_enriched_styles()
 
 
 
 
222
 
223
- # Créer un buffer pour le PDF
224
  buffer = io.BytesIO()
225
 
226
- # Créer le document PDF avec des marges adaptées
227
  doc = SimpleDocTemplate(
228
  buffer,
229
  pagesize=A4,
230
- rightMargin=25*mm,
231
- leftMargin=25*mm,
232
- topMargin=20*mm,
233
- bottomMargin=20*mm
234
  )
235
 
236
- # Liste pour stocker les éléments du document
237
- elements = []
238
-
239
- # Titre du contrat
240
- title = Paragraph(ContractTemplates.get_title(contract_type), styles['ContractTitle'])
241
- elements.append(title)
242
- elements.append(Spacer(1, 12))
243
-
244
- # Ajouter le préambule
245
- elements.append(Paragraph("ENTRE LES SOUSSIGNÉS :", styles['ContractSectionHeader']))
246
- elements.append(Spacer(1, 6))
247
-
248
- # Informations sur l'auteur/modèle
249
- if author_type == "Personne physique":
250
- author_details = _format_physical_person_details(author_info, contract_type, styles)
251
- elements.extend(author_details)
252
- else:
253
- author_details = _format_legal_entity_details(author_info, contract_type, styles)
254
- elements.extend(author_details)
255
-
256
- # Informations sur Tellers
257
- elements.append(Paragraph("Tellers, société par actions simplifiée unipersonnelle au capital de 1000 €, " +
258
- "immatriculée sous le numéro 932 553 266 R.C.S. Lyon, et dont le siège social est situé au : " +
259
- "12 RUE DE LA PART-DIEU, 69003 LYON, représentée par son Président en exercice dûment habilité à l'effet des présentes, " +
260
- "ci-après dénommée \"le Cessionnaire\",", styles['ContractNormalText']))
261
- elements.append(Spacer(1, 6))
262
-
263
- # Introduction
264
- elements.append(Paragraph("Ci-après dénommées ensemble \"les Parties\" ou individuellement \"la Partie\",", styles['ContractNormalText']))
265
- elements.append(Spacer(1, 6))
266
- elements.append(Paragraph("CECI EXPOSÉ, IL A ÉTÉ CONVENU CE QUI SUIT :", styles['ContractSectionHeader']))
267
- elements.append(Spacer(1, 12))
268
-
269
- # ARTICLE 1 - OBJET DU CONTRAT
270
- elements.append(Paragraph("ARTICLE 1 – OBJET DU CONTRAT", styles['ContractArticle']))
271
- elements.append(Spacer(1, 6))
272
-
273
- # Œuvre concernée si droits d'auteur
274
- if "Auteur (droits d'auteur)" in contract_type:
275
- elements.append(Paragraph("1.1 Œuvre concernée", styles['ContractSubArticle']))
276
- elements.append(Paragraph("L'Auteur déclare être le créateur et titulaire exclusif des droits d'auteur sur l'œuvre suivante :",
277
- styles['ContractNormalText']))
278
- elements.append(Paragraph(work_description, styles['ContractNormalText']))
279
- elements.append(Spacer(1, 6))
280
-
281
- # Image concernée si droit à l'image
282
- if "Image (droit à l'image)" in contract_type:
283
- elements.append(Paragraph("1.2 Images concernées", styles['ContractSubArticle']))
284
- elements.append(Paragraph("Le Modèle autorise l'utilisation de son image telle qu'elle apparaît dans :",
285
- styles['ContractNormalText']))
286
- elements.append(Paragraph(image_description, styles['ContractNormalText']))
287
- elements.append(Spacer(1, 6))
288
-
289
- # ARTICLE 2 - DROITS CÉDÉS
290
- elements.append(Paragraph("ARTICLE 2 – ÉTENDUE DES DROITS CÉDÉS", styles['ContractArticle']))
291
- elements.append(Spacer(1, 6))
292
-
293
- elements.append(Paragraph("2.1 Nature de la cession", styles['ContractSubArticle']))
294
-
295
- # Détails de la cession
296
- cession_details = "L'Auteur cède au Cessionnaire, "
297
- cession_details += "à titre exclusif, " if is_exclusive_bool else "à titre non exclusif, "
298
- cession_details += "gratuitement et pour la durée précisée à l'article 4, les droits patrimoniaux suivants :" if is_free_bool else "pour la durée précisée à l'article 4 et moyennant rémunération, les droits suivants :"
299
-
300
- elements.append(Paragraph(cession_details, styles['ContractNormalText']))
301
- elements.append(Spacer(1, 6))
302
-
303
- elements.append(Paragraph("2.2 Droits patrimoniaux cédés", styles['ContractSubArticle']))
304
-
305
- # Droits de base
306
- elements.append(Paragraph("- Droit de reproduction", styles['ContractListItem']))
307
- elements.append(Paragraph("- Droit de représentation", styles['ContractListItem']))
308
-
309
- # Droits supplémentaires
310
- if not is_free_bool and additional_rights:
311
- elements.append(Paragraph("Droits supplémentaires inclus :", styles['ContractNormalText']))
312
- for right in additional_rights:
313
- short_name = right.split(" - ")[0] if " - " in right else right
314
- elements.append(Paragraph(f"- {short_name}", styles['ContractListItem']))
315
-
316
- elements.append(Spacer(1, 6))
317
-
318
- # Article sur l'image si applicable
319
- article_num = 3
320
- if "Image (droit à l'image)" in contract_type:
321
- elements.append(Paragraph(f"ARTICLE {article_num} – AUTORISATION D'EXPLOITATION DE L'IMAGE", styles['ContractArticle']))
322
- elements.append(Spacer(1, 6))
323
-
324
- image_rights_details = "Le Modèle autorise expressément le Cessionnaire à exploiter son image "
325
- image_rights_details += "à titre exclusif" if is_exclusive_bool else "à titre non exclusif"
326
- image_rights_details += " et gratuit" if is_free_bool else ""
327
- image_rights_details += " selon les modalités détaillées dans le contrat complet."
328
-
329
- elements.append(Paragraph(image_rights_details, styles['ContractNormalText']))
330
- elements.append(Spacer(1, 6))
331
-
332
- article_num += 1
333
-
334
- # Article DURÉE ET TERRITOIRE
335
- elements.append(Paragraph(f"ARTICLE {article_num} – DURÉE ET TERRITOIRE", styles['ContractArticle']))
336
- elements.append(Spacer(1, 6))
337
-
338
- elements.append(Paragraph("4.1 Durée", styles['ContractSubArticle']))
339
- elements.append(Paragraph("La cession est consentie pour une durée d'un (1) an, renouvelable par tacite reconduction.",
340
- styles['ContractNormalText']))
341
- elements.append(Spacer(1, 6))
342
-
343
- elements.append(Paragraph("4.2 Territoire", styles['ContractSubArticle']))
344
- elements.append(Paragraph("La cession est consentie pour le monde entier.", styles['ContractNormalText']))
345
- elements.append(Spacer(1, 6))
346
-
347
- article_num += 1
348
-
349
- # Article SUPPORTS D'EXPLOITATION
350
- elements.append(Paragraph(f"ARTICLE {article_num} – SUPPORTS D'EXPLOITATION", styles['ContractArticle']))
351
- elements.append(Spacer(1, 6))
352
- elements.append(Paragraph("5.1 Supports autorisés", styles['ContractSubArticle']))
353
- elements.append(Paragraph("Les supports d'exploitation autorisés sont :", styles['ContractNormalText']))
354
-
355
- for support in final_supports:
356
- elements.append(Paragraph(f"- {support}", styles['ContractListItem']))
357
-
358
- elements.append(Spacer(1, 6))
359
- article_num += 1
360
-
361
- # Article RÉMUNÉRATION
362
- elements.append(Paragraph(f"ARTICLE {article_num} – RÉMUNÉRATION", styles['ContractArticle']))
363
- elements.append(Spacer(1, 6))
364
-
365
- if is_free_bool:
366
- elements.append(Paragraph("La présente cession est consentie à titre gratuit, sans contrepartie financière.",
367
- styles['ContractNormalText']))
368
- else:
369
- elements.append(Paragraph("En contrepartie de la présente cession, le Cessionnaire versera au Cédant :",
370
- styles['ContractNormalText']))
371
- elements.append(Paragraph(remuneration, styles['ContractNormalText']))
372
-
373
- elements.append(Spacer(1, 6))
374
- article_num += 1
375
-
376
- # Articles supplémentaires (résumés)
377
- articles_complementaires = [
378
- "GARANTIES ET RESPONSABILITÉS",
379
- "RÉSILIATION",
380
- "DISPOSITIONS DIVERSES",
381
- "LOI APPLICABLE ET JURIDICTION COMPÉTENTE"
382
- ]
383
-
384
- for art in articles_complementaires:
385
- elements.append(Paragraph(f"ARTICLE {article_num} – {art}", styles['ContractArticle']))
386
- elements.append(Spacer(1, 6))
387
- article_num += 1
388
-
389
- # Signature
390
- elements.append(Paragraph("Fait à ________________, le ________________", styles['ContractNormalText']))
391
- elements.append(Spacer(1, 6))
392
- elements.append(Paragraph("En deux exemplaires originaux.", styles['ContractNormalText']))
393
- elements.append(Spacer(1, 12))
394
-
395
- # Lignes de signature
396
- signature_text = ""
397
- if "Auteur (droits d'auteur)" in contract_type and "Image (droit à l'image)" in contract_type:
398
- signature_text = "Pour l'Auteur et Modèle : Pour le Cessionnaire :"
399
- elif "Auteur (droits d'auteur)" in contract_type:
400
- signature_text = "Pour l'Auteur : Pour le Cessionnaire :"
401
- else:
402
- signature_text = "Pour le Modèle : Pour le Cessionnaire :"
403
-
404
- elements.append(Paragraph(signature_text, styles['ContractNormalText']))
405
-
406
- # Construire le document
407
- doc.build(elements)
408
-
409
- # Sauvegarder le PDF
410
- with open(output_filename, 'wb') as f:
411
- f.write(buffer.getvalue())
412
 
413
  # Ajouter des champs interactifs pour les signatures
 
 
 
414
  p = canvas.Canvas(output_filename, pagesize=A4)
415
  form = p.acroForm
416
 
@@ -437,4 +112,50 @@ def generate_pdf(contract_type, is_free, author_type, author_info,
437
 
438
  form.textfield(name='mention_cessionnaire', tooltip='Mention "Lu et approuvé"',
439
  x=350, y=95, width=150, height=15,
440
- borderWidth=0, forceBorder=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  pdfmetrics.registerFont(TTFont('Vera', 'Vera.ttf'))
26
  pdfmetrics.registerFont(TTFont('VeraBd', 'VeraBd.ttf'))
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
  def generate_pdf(contract_type, is_free, author_type, author_info,
31
  work_description, image_description, supports,
32
  additional_rights, remuneration, is_exclusive):
33
  """
34
+ Génère un PDF du contrat avec des champs interactifs.
35
+ Version optimisée pour une génération plus rapide.
36
 
37
  Args:
38
  contract_type (list): Liste des types de contrats sélectionnés
 
59
  # Créer un nom de fichier temporaire pour le PDF
60
  output_filename = create_temp_file(prefix="contrat_cession_", suffix=".pdf")
61
 
62
+ # Générer le contenu du contrat - version simplifiée pour plus de rapidité
63
+ contract_elements = ContractBuilder.build_contract_elements(
64
+ contract_type, is_free_bool, author_type, author_info,
65
+ work_description, image_description, final_supports,
66
+ additional_rights, remuneration, is_exclusive_bool
67
+ )
68
 
69
+ # Créer un document PDF avec moins d'options pour accélérer la génération
70
  buffer = io.BytesIO()
71
 
72
+ # Utiliser des marges plus petites et des réglages plus simples
73
  doc = SimpleDocTemplate(
74
  buffer,
75
  pagesize=A4,
76
+ rightMargin=15*mm,
77
+ leftMargin=15*mm,
78
+ topMargin=15*mm,
79
+ bottomMargin=15*mm
80
  )
81
 
82
+ # Construire le document en une seule passe
83
+ doc.build(contract_elements)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
  # Ajouter des champs interactifs pour les signatures
86
+ buffer.seek(0)
87
+
88
+ # Version simplifiée des champs interactifs dans un second fichier
89
  p = canvas.Canvas(output_filename, pagesize=A4)
90
  form = p.acroForm
91
 
 
112
 
113
  form.textfield(name='mention_cessionnaire', tooltip='Mention "Lu et approuvé"',
114
  x=350, y=95, width=150, height=15,
115
+ borderWidth=0, forceBorder=True)
116
+
117
+ form.textfield(name='signature_cedant', tooltip=f'Signature de {cedant_label}',
118
+ x=70, y=60, width=150, height=30,
119
+ borderWidth=0, forceBorder=True)
120
+
121
+ form.textfield(name='signature_cessionnaire', tooltip='Signature du Cessionnaire',
122
+ x=350, y=60, width=150, height=30,
123
+ borderWidth=0, forceBorder=True)
124
+
125
+ # Ne pas essayer d'ajouter des champs de paraphe sur chaque page
126
+ # Cela causait une erreur car SimpleDocTemplate n'a pas d'attribut page_count
127
+
128
+ # Finaliser et sauvegarder le PDF
129
+ p.save()
130
+
131
+ # Sauvegarder le PDF dans un fichier
132
+ with open(output_filename, 'wb') as f:
133
+ f.write(buffer.getvalue())
134
+
135
+ return output_filename
136
+
137
+
138
+ def get_simplified_styles():
139
+ """
140
+ Retourne des styles simplifiés pour une génération plus rapide.
141
+
142
+ Returns:
143
+ dict: Dictionnaire des styles simplifiés
144
+ """
145
+ styles = getSampleStyleSheet()
146
+ # Utiliser des styles plus simples avec moins d'options
147
+ styles.add(ParagraphStyle(name='ContractTitle',
148
+ fontName='VeraBd',
149
+ fontSize=14,
150
+ alignment=TA_CENTER,
151
+ spaceAfter=10))
152
+ styles.add(ParagraphStyle(name='ContractText',
153
+ fontName='Vera',
154
+ fontSize=10,
155
+ alignment=TA_JUSTIFY,
156
+ spaceAfter=5))
157
+ styles.add(ParagraphStyle(name='ContractArticle',
158
+ fontName='VeraBd',
159
+ fontSize=11,
160
+ spaceAfter=5))
161
+ return styles