diff --git a/docbow_project/docbow/forms.py b/docbow_project/docbow/forms.py index 4299a33..1f34942 100644 --- a/docbow_project/docbow/forms.py +++ b/docbow_project/docbow/forms.py @@ -200,12 +200,13 @@ class FileForm(RecipientForm, ModelForm): cleaned_data = super(FileForm, self).clean() for field, attached_file_kind in self.content_fields: upload_id, upload_files = self.cleaned_data.get(field, (None, [])) - cardinality = attached_file_kind.cardinality + max_files = attached_file_kind.cardinality + min_files = attached_file_kind.minimum errors = [] - if cardinality and len(upload_files) > cardinality: - errors.append(_(u'You must attach at most %d file(s).') % cardinality) - if len(upload_files) == 0: - errors.append(_(u'You must attach at least one file.')) + if max_files and len(upload_files) > max_files: + errors.append(_(u'You must attach at most %d file(s).') % max_files) + if min_files and len(upload_files) < min_files: + errors.append(_(u'You must attach at least %d file(s).') % min_files) for upload_file in upload_files: if not attached_file_kind.match_file(upload_file): mime_types = attached_file_kind.get_mime_types() diff --git a/docbow_project/docbow/locale/fr/LC_MESSAGES/django.po b/docbow_project/docbow/locale/fr/LC_MESSAGES/django.po index 569ef1d..9e167d0 100644 --- a/docbow_project/docbow/locale/fr/LC_MESSAGES/django.po +++ b/docbow_project/docbow/locale/fr/LC_MESSAGES/django.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: docbow 1.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2013-09-11 12:29+0200\n" -"PO-Revision-Date: 2013-09-11 12:29+0200\n" +"POT-Creation-Date: 2013-09-11 13:27+0200\n" +"PO-Revision-Date: 2013-09-11 13:27+0200\n" "Last-Translator: Benjamin Dauvergne \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -27,11 +27,11 @@ msgstr "Activer les objets sélectionnés" msgid "De-activate selected objects" msgstr "" -#: admin.py:40 models.py:691 +#: admin.py:40 models.py:696 msgid "Limitation des destinataires" msgstr "" -#: admin.py:45 models.py:688 +#: admin.py:45 models.py:693 msgid "Limitation des types de fichier" msgstr "" @@ -76,7 +76,7 @@ msgid "Clear failure and done field, resubmitting the notifications." msgstr "" "Réinitialise les champs accompli et erreur, et re-soumet la notification." -#: admin.py:224 models.py:178 +#: admin.py:224 models.py:183 msgid "Document" msgstr "Document" @@ -88,7 +88,7 @@ msgstr "" msgid "None" msgstr "" -#: admin.py:245 forms.py:332 templates/admin/object_history.html:26 +#: admin.py:245 forms.py:333 templates/admin/object_history.html:26 msgid "User" msgstr "Utilisateur" @@ -142,7 +142,7 @@ msgstr "Contacter un administrateur du système" msgid "Your delegation does not allow you to do this action" msgstr "Votre délégation ne vous permet pas d'accomplir cette action" -#: fields.py:69 forms.py:55 forms.py:109 models.py:255 +#: fields.py:69 forms.py:55 forms.py:109 models.py:260 msgid "Recipients" msgstr "Destinataire(s)" @@ -151,7 +151,7 @@ msgid "you must set at least one user recipient or one list recipient..." msgstr "" "Vous devez choisir au moins un utilisateur ou une liste destinataire..." -#: forms.py:56 models.py:185 +#: forms.py:56 models.py:190 msgid "Sender" msgstr "Expéditeur" @@ -163,53 +163,54 @@ msgstr "Transférer le document" msgid "send a file" msgstr "Envoyer le document" -#: forms.py:164 models.py:216 models.py:234 +#: forms.py:164 models.py:221 models.py:239 msgid "Attached files" msgstr "Fichiers attaché(s)" -#: forms.py:206 +#: forms.py:207 #, python-format msgid "You must attach at most %d file(s)." msgstr "Vous devez attacher au plus %d fichier(s)." -#: forms.py:208 -msgid "You must attach at least one file." -msgstr "Vous devez attacher au moins un fichier." +#: forms.py:209 +#, python-format +msgid "You must attach at least %d file(s)." +msgstr "Vous devez attacher au moins %d fichier(s)." -#: forms.py:213 +#: forms.py:214 msgid "" "The file name \"{file_name}\" does not match the patterns \"{extensions}\"." msgstr "" -#: forms.py:252 forms.py:277 +#: forms.py:253 forms.py:278 msgid "send your message" msgstr "Envoyer le message" -#: forms.py:259 +#: forms.py:260 msgid "Subject" msgstr "Sujet" -#: forms.py:262 +#: forms.py:263 msgid "Message" msgstr "Message" -#: forms.py:284 models.py:481 models.py:570 +#: forms.py:285 models.py:486 models.py:575 msgid "Name" msgstr "Nom" -#: forms.py:285 forms.py:331 +#: forms.py:286 forms.py:332 msgid "Email" msgstr "" -#: forms.py:286 +#: forms.py:287 msgid "Phone number" msgstr "Numéro de téléphone" -#: forms.py:303 +#: forms.py:304 msgid "Persons" msgstr "Personnes" -#: forms.py:317 +#: forms.py:318 msgid "" "

You can delegate to a newly created user, then all following fields are " "mandatory:

" @@ -217,24 +218,24 @@ msgstr "" "

Vous pouvez déléguer à un nouvel utilisateur que vous créez — tous les " "champs suivants sont obligatoires dans ce cas:

" -#: forms.py:319 +#: forms.py:320 msgid "

or you can delegate to an existing user:

" msgstr "

ou bien déléguer à un utilisateur existant:

" -#: forms.py:322 templates/docbow/delegate.html:57 +#: forms.py:323 templates/docbow/delegate.html:57 #: templates/docbow/full-profile.html:69 msgid "Create a new delegation" msgstr "Créer une nouvelle délégation" -#: forms.py:329 +#: forms.py:330 msgid "Firstname" msgstr "Prénom" -#: forms.py:330 +#: forms.py:331 msgid "Lastname" msgstr "Nom" -#: forms.py:354 +#: forms.py:355 msgid "" "You must choose between creating a new user or delegating to an existing " "one; the two are mutually exclusive." @@ -242,7 +243,7 @@ msgstr "" "Vous devez choisir entre déléguer à un nouvel utilisateur qui sera créé ou " "déléguer à un utilisateur existant, les deux choix s'excluant mutuellement." -#: forms.py:358 +#: forms.py:359 msgid "" "To create a new user you must give a first name, a last name and a valid " "email" @@ -250,13 +251,13 @@ msgstr "" "Pour créer un nouvel utilisateur vous devez donner un prénom, un nom et une " "adresse de courriel valide." -#: forms.py:375 +#: forms.py:376 msgid "A forwarding rule must have at least one recipient, person or list." msgstr "" "Une règle de transfert doit contenir au moins un nouveau destinataire; une " "personne ou une liste." -#: forms.py:392 +#: forms.py:393 msgid "" "

If You would like to receive a SMS alert each time " "your inbox receives a document, provide your mobile phone number. If you do " @@ -267,15 +268,15 @@ msgstr "" "de téléphone. Si vous ne remplissez pas ce champ, vous ne recevrez pas de " "SMS.

" -#: forms.py:398 +#: forms.py:399 msgid "Clear SMS alert" msgstr "Supprimer l'alerte par SMS" -#: forms.py:399 +#: forms.py:400 msgid "Validate" msgstr "Valider" -#: forms.py:406 +#: forms.py:407 msgid "" "Use international phone number format, i.e +[country code][number]. A " "challenge SMS will be sent to you to validate it." @@ -285,15 +286,15 @@ msgstr "" "code vous sera envoyé et il vous faudra valider une deuxième fois votre " "numéro avec le code." -#: forms.py:432 +#: forms.py:433 msgid "Enter code received by SMS" msgstr "Entrez le code reçu par SMS" -#: forms.py:453 +#: forms.py:454 msgid "E-mail or identifier" msgstr "E-mail ou nom d'utilisateur" -#: forms.py:469 +#: forms.py:470 msgid "" "That e-mail address or identifier doesn't have an associated user account. " "Are you sure you've registered?" @@ -301,15 +302,15 @@ msgstr "" "Cette adresse email ou cet identifiant n'ont pas de compte utilisateur " "associé.Êtes-vous bien sûr d'être enregistré?" -#: forms.py:487 +#: forms.py:488 msgid "From" msgstr "De" -#: forms.py:488 templates/docbow/message.html:34 +#: forms.py:489 templates/docbow/message.html:34 msgid "To" msgstr "Destinataire(s)" -#: forms.py:503 +#: forms.py:504 msgid "From must be inferior or equal to To" msgstr "Le début de la période doit être inférieur ou égal à sa fin" @@ -325,7 +326,7 @@ msgstr "Plate-forme sécurisée d'échange de documents" msgid "Docbow_app" msgstr "Plate-forme sécurisée d'échange de documents" -#: models.py:59 models.py:576 +#: models.py:59 models.py:581 msgid "is active" msgstr "Activé" @@ -354,104 +355,119 @@ msgid "cardinality" msgstr "nombre de fichiers maximum" #: models.py:89 +msgid "zero is a special value setting no limitation" +msgstr "zéro est une valeur spéciale qui signifie \"sans limitation\"" + +#: models.py:91 +msgid "minimum number of files" +msgstr "nombre de fichiers minimum" + +#: models.py:92 msgid "position" msgstr "" -#: models.py:94 +#: models.py:96 +msgid "" +"minimum must be inferior to maximum number of files if maximum is not zero" +msgstr "" +"le minimum doit être inférieur au maximum du nombre de fichiers si le " +"maximum n'est pas nul" + +#: models.py:99 msgid "invalid mime types list" msgstr "liste de types MIME invalide" -#: models.py:111 +#: models.py:116 msgid "file type attached file kind" msgstr "Type de fichiers attachés pour un type de document" -#: models.py:112 +#: models.py:117 msgid "file type attached file kinds" msgstr "Types de fichiers attachés pour un type de document" -#: models.py:126 +#: models.py:131 msgid "Content" msgstr "Description des contenus" -#: models.py:127 +#: models.py:132 msgid "Contents" msgstr "Descriptions des contenus" -#: models.py:179 templates/docbow/mailbox_list.html:18 +#: models.py:184 templates/docbow/mailbox_list.html:18 msgid "Documents" msgstr "Documents" -#: models.py:181 +#: models.py:186 msgid "Can forward documents" msgstr "Peut transférer des documents" -#: models.py:187 +#: models.py:192 msgid "Real sender" msgstr "Expéditeur réel" -#: models.py:189 +#: models.py:194 msgid "Date d'envoi" msgstr "" -#: models.py:191 +#: models.py:196 msgid "Users to send to" msgstr "Aux utilisateurs" -#: models.py:193 +#: models.py:198 msgid "Groups to send to" msgstr "Aux listes des" -#: models.py:194 +#: models.py:199 msgid "Document type" msgstr "Type de document" -#: models.py:196 +#: models.py:201 msgid "Comments" msgstr "Description du contenu" -#: models.py:198 +#: models.py:203 msgid "Reply to" msgstr "Réponse à" -#: models.py:210 +#: models.py:215 msgid "" "document {id} sent on {date} of type {filetype} about {comment} by {sender}" msgstr "" "document {id} envoyé le {date} du type {filetype} à propos de {comment} par " "{sender}" -#: models.py:402 +#: models.py:407 msgid "" "forwarded document {from_document} as {to_document} on {date} automatically" msgstr "" "document {from_document} transféré en {to_document} le {date} automatiquement" -#: models.py:407 +#: models.py:412 msgid "forwarded document {from_document} as {to_document} on {date}" msgstr "document {from_document} transféré en {to_document} le {date}" -#: models.py:430 +#: models.py:435 msgid "filetype" msgstr "Type de fichier" -#: models.py:433 +#: models.py:438 msgid "Original recipients" msgstr "Destinataires d'origine" -#: models.py:434 +#: models.py:439 msgid "At least one recipient must match for the rule to apply." msgstr "" "Au moins un destinataire doit correspondre pour que la règle s'applique." -#: models.py:437 +#: models.py:442 msgid "Users to forward to" msgstr "Aux utilisateurs" -#: models.py:439 +#: models.py:444 msgid "Groups to forward to" msgstr "Aux listes des" -#: models.py:450 +#: models.py:455 msgid "" "Forward documents of type {filetypes} and to {originaly_to_user} " "automatically to {to}" @@ -459,95 +475,95 @@ msgstr "" "Transfert les documents du type {filetypes} et à destination de " "{originaly_to_user} automatiquement à {to}" -#: models.py:452 +#: models.py:457 msgid "Forward documents of type {filetypes} automatically to {to}" msgstr "Transfert les documents du type {filetypes} automatiquement à {to}" -#: models.py:454 +#: models.py:459 msgid "Forward documents to {originaly_to_user} automatically to {to}" msgstr "" "Transfert les documents à destination de {originaly_to_user} automatiquement " "à {to}" -#: models.py:475 +#: models.py:480 msgid "Automatic forwarding rule" msgstr "Règle de transfert automatique" -#: models.py:476 +#: models.py:481 msgid "Automatic forwarding rules" msgstr "Règles de transfert automatique" -#: models.py:482 +#: models.py:487 msgid "File" msgstr "Fichier" -#: models.py:483 +#: models.py:488 msgid "Attached to" msgstr "Attaché à" -#: models.py:486 +#: models.py:491 msgid "attached file kind" msgstr "Type de fichiers attachés pour un type de document" -#: models.py:526 +#: models.py:531 msgid "Account delegation" msgstr "Délégation de compte" -#: models.py:527 +#: models.py:532 msgid "Account delegations" msgstr "Délégations de compte" -#: models.py:531 +#: models.py:536 msgctxt "delegation from" msgid "From" msgstr "Par" -#: models.py:533 +#: models.py:538 msgctxt "delegation to" msgid "To" msgstr "À" -#: models.py:568 +#: models.py:573 msgid "Mailing list" msgstr "Liste de destinataires" -#: models.py:569 +#: models.py:574 msgid "Mailing lists" msgstr "Listes de destinataires" -#: models.py:571 +#: models.py:576 msgid "Members" msgstr "Membres" -#: models.py:574 +#: models.py:579 msgid "Mailing lists members" msgstr "Listes membres" -#: models.py:618 +#: models.py:623 msgid "Mailbox owner" msgstr "Propriétaire de la boite de courrier" -#: models.py:622 +#: models.py:627 msgid "Seen" msgstr "Vu" -#: models.py:623 +#: models.py:628 msgid "Deleted" msgstr "Effacé" -#: models.py:624 +#: models.py:629 msgid "Outbox message" msgstr "Boite d'émission" -#: models.py:630 +#: models.py:635 msgid "Mailbox" msgstr "Boite de réception" -#: models.py:631 +#: models.py:636 msgid "Mailboxes" msgstr "Boites de réception" -#: models.py:635 +#: models.py:640 msgid "" "seen and deleted mailbox entry {id} of user {user}:{user.id} created on " "{date} for {document}" @@ -555,7 +571,7 @@ msgstr "" "entrée {id} de la boite au lettre de l'utilisateur {user}:{user.id} créée le " "{date} pour le document {document} puis lue et supprimée" -#: models.py:640 +#: models.py:645 msgid "" "deleted mailbox entry {id} of user {user}:{user.id} created on {date} for " "{document}" @@ -563,7 +579,7 @@ msgstr "" "entrée {id} de la boite au lettre de l'utilisateur {user}:{user.id} créée le " "{date} pour le document {document} puis jamais lue et supprimée" -#: models.py:645 +#: models.py:650 msgid "" "seen mailbox entry {id} of user {user}:{user.id} created on {date} for " "{document}" @@ -571,42 +587,42 @@ msgstr "" "entrée {id} de la boite au lettre de l'utilisateur {user}:{user.id} créée le " "{date} pour le document {document} puis jamais lue" -#: models.py:650 +#: models.py:655 msgid "" "mailbox entry {id} of user {user}:{user.id} created on {date} for {document}" msgstr "" "entrée {id} de la boite au lettre de l'utilisateur {user}:{user.id} créée le " "{date} pour le document {document}" -#: models.py:657 +#: models.py:662 msgid "Docbow admin user" msgstr "Utilisateur" -#: models.py:664 +#: models.py:669 msgid "Docbow admin group" msgstr "Profil" -#: models.py:672 +#: models.py:677 msgid "Inbox" msgstr "Message(s) reçu(s)" -#: models.py:673 +#: models.py:678 msgid "Inboxes" msgstr "Message(s) reçu(s)" -#: models.py:679 +#: models.py:684 msgid "Outbox" msgstr "Message(s) émi(s)" -#: models.py:680 +#: models.py:685 msgid "Outboxes" msgstr "Message(s) émi(s)" -#: models.py:694 models.py:695 +#: models.py:699 models.py:700 msgid "Limitation par liste de destinataires" msgstr "" -#: models.py:699 +#: models.py:704 msgid "" "sending limitation for list {mailing_list} to filetypes{filetypes} and lists " "{lists}" @@ -614,19 +630,19 @@ msgstr "" "limitation d'envoi pour la liste {mailing_list} restreinte auxtypes de " "fichier {filetypes} et aux listes {lists}" -#: models.py:709 +#: models.py:714 msgid "Guest user" msgstr "Utilisateur invité" -#: models.py:710 +#: models.py:715 msgid "Mobile phone" msgstr "Téléphone mobile" -#: models.py:712 +#: models.py:717 msgid "personal email address" msgstr "Adresse email personnelle" -#: models.py:713 +#: models.py:718 msgid "" "if you provide a personal email address, notifications of new documents will " "also be sent to this address." @@ -635,13 +651,13 @@ msgstr "" "adresse pour chaque nouveau document qui vous est adressé sur la plate-forme " "(identique au mail que vous recevez sur votre adresse institutionnelle)." -#: models.py:717 +#: models.py:722 msgid "" "docbow profile of {user}:{user.id} with mobile phone {mobile_phone} and " "personal email {personal_email}" msgstr "" -#: models.py:755 +#: models.py:760 msgid "notification {0}:{1}" msgstr "" @@ -726,7 +742,7 @@ msgstr "nom de fichier trop long, seulement %d caractères sont permis" msgid "too much file attached, delete to add a new one" msgstr "trop de fichiers attachés, supprimez en un pour en ajouter un autre" -#: views.py:172 +#: views.py:171 msgid "" "An internal error occured, administrators have been notified; sending seems " "blocked at the moment. You should try agrain later. If it still does not " @@ -737,26 +753,26 @@ msgstr "" "incitons à réessayer plus tard. Si cela ne fonctionne toujours pas, prenez " "contact avec les gestionnaires." -#: views.py:233 +#: views.py:232 msgid "back to inbox" msgstr "Retour aux documents reçus" -#: views.py:235 +#: views.py:234 msgid "back to outbox" msgstr "Retour aux documents envoyés" -#: views.py:249 +#: views.py:248 msgid "Document forwarded to {recipients_count} recipient." msgid_plural "Document forwarded to {recipients_count} recipients." msgstr[0] "Document tranféré à {recipients_count} destinataire." msgstr[1] "Document tranféré à {recipients_count} destinataires." -#: views.py:319 views.py:323 +#: views.py:318 views.py:322 #, python-format msgid "Message from %(name)s <%(email)s>" msgstr "Message de %(name)s <%(email)s>" -#: views.py:325 +#: views.py:324 #, python-format msgid "" "\n" @@ -765,17 +781,17 @@ msgstr "" "\n" "Numéro de téléphone: %s" -#: views.py:330 +#: views.py:329 #, python-format msgid "Your message was sent to %d administrators" msgstr "Votre message a été envoyé à %d administrateurs." -#: views.py:365 +#: views.py:364 #, python-format msgid "back to %s" msgstr "Retour à %s" -#: views.py:443 +#: views.py:442 msgid "Email with password reset instruction has been sent." msgstr "" "Un email avec les instructions pour la réinitialisation de votre mot de " @@ -955,10 +971,15 @@ msgstr "Ajouter des fichiers" msgid "Any type" msgstr "Tout type de fichier permis" -#: templates/docbow/upload.html:6 +#: templates/docbow/upload.html:7 #, python-format -msgid ", maximum %(cardinality)s files" -msgstr ", maximum %(cardinality)s fichiers" +msgid ", maximum %(cardinality)s file(s)" +msgstr ", maximum %(cardinality)s fichier(s)" + +#: templates/docbow/upload.html:10 +#, python-format +msgid ", minimum %(minimum)s file(s)" +msgstr ", mnimum %(minimum)s fichier(s)" #: templates/registration/login.html:6 #: templates/registration/password_reset_complete.html:14 @@ -1046,6 +1067,9 @@ msgstr "aux %s" msgid "%(one)s and to lists %(two)s" msgstr "%(one)s ainsi qu'%(two)s" +#~ msgid "You must attach at least one file." +#~ msgstr "Vous devez attacher au moins un fichier." + #~ msgid "password_change_menu" #~ msgstr "Changement du mot de passe" diff --git a/docbow_project/docbow/migrations/0029_auto__add_field_filetypeattachedfilekind_minimum.py b/docbow_project/docbow/migrations/0029_auto__add_field_filetypeattachedfilekind_minimum.py new file mode 100644 index 0000000..6de2dcb --- /dev/null +++ b/docbow_project/docbow/migrations/0029_auto__add_field_filetypeattachedfilekind_minimum.py @@ -0,0 +1,175 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding field 'FileTypeAttachedFileKind.minimum' + db.add_column('docbow_filetypeattachedfilekind', 'minimum', + self.gf('django.db.models.fields.PositiveSmallIntegerField')(default=0), + keep_default=False) + + + def backwards(self, orm): + # Deleting field 'FileTypeAttachedFileKind.minimum' + db.delete_column('docbow_filetypeattachedfilekind', 'minimum') + + + models = { + 'auth.group': { + 'Meta': {'object_name': 'Group'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}), + 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}) + }, + 'auth.permission': { + 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'}, + 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}) + }, + 'auth.user': { + 'Meta': {'object_name': 'User'}, + 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}), + 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}), + 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}) + }, + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'docbow.attachedfile': { + 'Meta': {'object_name': 'AttachedFile'}, + 'content': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'attached_files'", 'to': "orm['docbow.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'kind': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['docbow.FileTypeAttachedFileKind']", 'null': 'True', 'blank': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'docbow.automaticforwarding': { + 'Meta': {'object_name': 'AutomaticForwarding'}, + 'filetypes': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'forwarding_rules'", 'symmetrical': 'False', 'to': "orm['docbow.FileType']"}), + 'forward_to_list': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'as_recipient_forwarding_rules'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['docbow.MailingList']"}), + 'forward_to_user': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'as_recipient_forwarding_rules'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'originaly_to_user': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'as_original_recipient_forwarding_rules'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}) + }, + 'docbow.content': { + 'Meta': {'ordering': "['description']", 'object_name': 'Content'}, + 'description': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}) + }, + 'docbow.delegation': { + 'Meta': {'ordering': "['by']", 'unique_together': "(('by', 'to'),)", 'object_name': 'Delegation', 'db_table': "'auth_delegation'"}, + 'by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'delegations_to'", 'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'to': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'delegations_by'", 'to': "orm['auth.User']"}) + }, + 'docbow.deletedmailbox': { + 'Meta': {'object_name': 'DeletedMailbox'}, + 'delegate': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mailbox': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['docbow.Mailbox']"}) + }, + 'docbow.docbowprofile': { + 'Meta': {'object_name': 'DocbowProfile'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_guest': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'mobile_phone': ('django.db.models.fields.CharField', [], {'max_length': '32', 'blank': 'True'}), + 'personal_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}), + 'user': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.User']", 'unique': 'True'}) + }, + 'docbow.document': { + 'Meta': {'ordering': "['-date']", 'object_name': 'Document'}, + '_timestamp': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'comment': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'date': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}), + 'filetype': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['docbow.FileType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'real_sender': ('django.db.models.fields.CharField', [], {'max_length': '64', 'blank': 'True'}), + 'reply_to': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'replies'", 'null': 'True', 'to': "orm['docbow.Document']"}), + 'sender': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents_sent'", 'to': "orm['auth.User']"}), + 'to_list': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['docbow.MailingList']", 'null': 'True', 'blank': 'True'}), + 'to_user': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'directly_received_documents'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}) + }, + 'docbow.documentforwarded': { + 'Meta': {'object_name': 'DocumentForwarded'}, + 'automatic': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'from_document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'document_forwarded_to'", 'to': "orm['docbow.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'to_document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'document_forwarded_from'", 'to': "orm['docbow.Document']"}) + }, + 'docbow.filetype': { + 'Meta': {'ordering': "['name']", 'object_name': 'FileType'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '128'}) + }, + 'docbow.filetypeattachedfilekind': { + 'Meta': {'ordering': "('file_type', 'position', 'name')", 'unique_together': "(('name', 'file_type'),)", 'object_name': 'FileTypeAttachedFileKind'}, + 'cardinality': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}), + 'file_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['docbow.FileType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'mime_types': ('django.db.models.fields.TextField', [], {'blank': 'True'}), + 'minimum': ('django.db.models.fields.PositiveSmallIntegerField', [], {'default': '0'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}), + 'position': ('django.db.models.fields.PositiveSmallIntegerField', [], {}) + }, + 'docbow.mailbox': { + 'Meta': {'ordering': "['-date']", 'object_name': 'Mailbox'}, + 'date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'mailboxes'", 'to': "orm['docbow.Document']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'outbox': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'owner': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'documents'", 'to': "orm['auth.User']"}), + 'seen': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) + }, + 'docbow.mailinglist': { + 'Meta': {'ordering': "['name']", 'object_name': 'MailingList'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'mailing_list_members': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'members_lists'", 'blank': 'True', 'to': "orm['docbow.MailingList']"}), + 'members': ('django.db.models.fields.related.ManyToManyField', [], {'blank': 'True', 'related_name': "'mailing_lists'", 'null': 'True', 'symmetrical': 'False', 'to': "orm['auth.User']"}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '128'}) + }, + 'docbow.notification': { + 'Meta': {'ordering': "('-id',)", 'object_name': 'Notification'}, + 'create_dt': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), + 'ctx': ('picklefield.fields.PickledObjectField', [], {'null': 'True', 'blank': 'True'}), + 'document': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['docbow.Document']", 'null': 'True', 'blank': 'True'}), + 'done': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), + 'failure': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'kind': ('django.db.models.fields.CharField', [], {'default': "'new-document'", 'max_length': '32'}), + 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}) + }, + 'docbow.sendinglimitation': { + 'Meta': {'object_name': 'SendingLimitation'}, + 'filetypes': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'filetype_limitation'", 'blank': 'True', 'to': "orm['docbow.FileType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'lists': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'lists_limitation'", 'symmetrical': 'False', 'to': "orm['docbow.MailingList']"}), + 'mailing_list': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['docbow.MailingList']", 'unique': 'True'}) + } + } + + complete_apps = ['docbow'] \ No newline at end of file diff --git a/docbow_project/docbow/models.py b/docbow_project/docbow/models.py index e797f58..76f2313 100644 --- a/docbow_project/docbow/models.py +++ b/docbow_project/docbow/models.py @@ -85,10 +85,15 @@ class FileTypeAttachedFileKind(Model): help_text=('mime types separated by spaces, wildcards are allowed'), blank=True) cardinality = PositiveSmallIntegerField(default=0, - verbose_name=_('cardinality')) + verbose_name=_('cardinality'), + help_text=_('zero is a special value setting no limitation')) + minimum = PositiveSmallIntegerField(default=0, + verbose_name=_('minimum number of files')) position = PositiveSmallIntegerField(verbose_name=_('position')) def clean(self): + if self.cardinality != 0 and not self.minimum <= self.cardinality: + raise ValidationError(_('minimum must be inferior to maximum number of files if maximum is not zero')) if self.mime_types: if not self.MIME_TYPES_RE.match(self.mime_types): raise ValidationError(_('invalid mime types list')) diff --git a/docbow_project/docbow/templates/docbow/upload.html b/docbow_project/docbow/templates/docbow/upload.html index a275087..0b95bf0 100644 --- a/docbow_project/docbow/templates/docbow/upload.html +++ b/docbow_project/docbow/templates/docbow/upload.html @@ -3,8 +3,13 @@