class MRSRequestCreateForm(MRSRequestForm): layouts = dict(above=material.Layout( material.Fieldset( 'Votre caisse d\'assurance maladie', 'caisse', ), ), top=material.Layout( material.Fieldset( 'Votre prescription médicale', 'pmt', ), ), bottom=material.Layout( material.Row('distance', ), 'expense', 'bills', )) def clean(self): cleaned_data = super().clean() expense = cleaned_data.get('expense') bills = cleaned_data.get('bills') if expense and not bills: self.add_error( 'bills', 'Merci de soumettre vos justificatifs de transport') return cleaned_data class Meta: model = MRSRequest fields = [ 'caisse', 'distance', 'expense', ]
class AssociadoForm(forms.ModelForm): layout = material.Layout( material.Fieldset("Informações Pessoais", material.Row('nome', 'sobrenome'), material.Row('email', 'telefone'), ), material.Fieldset("Informações de Curso", material.Row('matricula', 'ano_matricula', 'previsao_conclusao') ), ) telefone = forms.CharField(widget=forms.TextInput(attrs={'class': 'mascara-telefone'}), required=False) class Meta: model = models.Associado fields = ( "nome", "sobrenome", "matricula", "email", "ano_matricula", "previsao_conclusao", "telefone", "password", )
class PersonForm(forms.ModelForm): birth_date = DateField(label='Date de naissance', ) layout = material.Layout( material.Fieldset( 'Identité de la personne transportée', material.Row( 'first_name', 'last_name', ), 'birth_date', ), material.Fieldset('Identité de l\'assuré', material.Row( 'nir', 'email', )), ) def clean_birth_date(self): data = self.cleaned_data['birth_date'] if data and (now().date() - data).days < 0: raise forms.ValidationError( 'Doit être antèrieure à la date du jour') return data def get_or_create(self): # Return existing person untouched if possible # Case of twins : we added a unicity check # with the person's first name person = Person.objects.filter( birth_date=self.cleaned_data['birth_date'], nir=self.cleaned_data['nir'], first_name=self.cleaned_data['first_name']).first() if person: return person # Otherwise create a new Person return super().save() class Meta: model = Person fields = [ 'nir', 'email', 'first_name', 'last_name', 'birth_date', ]
class EgressoForm(forms.ModelForm): layout = material.Layout( material.Fieldset( "Informações Pessoais", material.Row('nome', 'sobrenome'), material.Row('email', 'telefone'), ), material.Fieldset( "Informações de Curso", material.Row('matricula', 'ano_matricula', 'previsao_conclusao')), material.Fieldset("Informações de Acesso", material.Row('password', 'password_confirm')), ) password = forms.CharField(label='Senha', widget=forms.PasswordInput()) password_confirm = forms.CharField(label='Confirmar Senha', widget=forms.PasswordInput()) telefone = forms.CharField( widget=forms.TextInput(attrs={'class': 'mascara-telefone'}), required=False) def clean(self): cleaned_data = super(EgressoForm, self).clean() password = cleaned_data.get("password") password_confirm = cleaned_data.get("password_confirm") if password != password_confirm: raise forms.ValidationError( "password and password_confirm does not match") class Meta: model = models.Egresso fields = ( "nome", "sobrenome", "matricula", "email", "ano_matricula", "previsao_conclusao", "telefone", "password", )
class ContactForm(forms.Form): nom = forms.CharField() email = forms.EmailField() message = forms.CharField(widget=forms.Textarea) layout = material.Layout( material.Fieldset( 'N\'hésitez pas à nous contacter !', material.Row( 'nom', 'email', ), 'message', ))
class EstoqueForm(forms.ModelForm): quantidade = forms.IntegerField(help_text="Quantidade em estoque") quantidade_minima = forms.IntegerField( label="Quantidade Mínima", help_text="Quantidade mínima em estoque para realização de encomenda", ) quantidade_encomenda = forms.IntegerField( label="Quantidade para Encomenda", help_text="Quantidade mínima de interessados para encomenda") layout = material.Layout( material.Fieldset( 'Informações de Estoque', material.Row('quantidade', 'quantidade_minima', 'quantidade_encomenda')), ) class Meta: model = Estoque fields = ('quantidade', 'quantidade_minima', 'quantidade_encomenda')
class ProdutoForm(forms.ModelForm): preco = forms.CharField( widget=forms.TextInput(attrs={'class': 'mascara-dinheiro'}), label="Preço do Produto") servico = forms.BooleanField( label="Serviço", help_text="Este produto é uma prestação de serviço?", required=False) layout = material.Layout( material.Fieldset('Informações do Produto', material.Row('nome', 'preco', 'servico'), material.Row('foto')), ) def __init__(self, *args, **kwargs): instance = kwargs.get('instance') if instance: preco = str(instance.preco) preco = '{:,.2f}'.format(float(instance.preco)) preco = preco.replace(',', 'v') preco = preco.replace('.', ',') preco = f"R$ {preco}" if 'initial' in kwargs: kwargs['initial']['preco'] = preco super(ProdutoForm, self).__init__(*args, **kwargs) def clean_preco(self): """Tira formatação de moeda""" data = self.cleaned_data.get("preco") data = data.replace('R$', '') data = data.replace('.', '') data = data.replace(',', '.') data = float(data) return data class Meta: model = Produto fields = ('nome', 'preco', 'servico', 'foto')
class TransportIterativeForm(TransportForm): iterative_show = forms.BooleanField( label='Avez-vous des transports itératifs à déclarer ?', widget=forms.CheckboxInput, required=False, ) iterative_number = forms.IntegerField( label='Combien de trajets itératifs souhaitez-vous déclarer ?', initial=1, required=False, ) layout = material.Layout( material.Fieldset( 'Informations sur le transport', material.Row( 'date_depart', 'date_return', ), 'iterative_show', 'iterative_number', ), )
class TransportIterativeForm(forms.Form): iterative_show = forms.BooleanField( label='Avez-vous des transports itératifs* à déclarer ?', widget=forms.CheckboxInput, required=False, help_text='*Les transports itératifs sont des transports' ' réguliers de distance identique (même lieu de' ' départ, même lieu d\'arrivée)', ) iterative_number = forms.IntegerField( label='Combien de trajets itératifs ?', initial=1, required=False, widget=forms.TextInput, min_value=1, ) trip_kind = forms.ChoiceField( label='', choices=( ('return', 'Aller retour'), ('simple', 'Aller simple'), ), widget=forms.RadioSelect, ) layout = material.Layout( material.Fieldset( 'Informations sur le transport', 'trip_kind', 'iterative_show', 'iterative_number', ), ) def __init__(self, *args, **kwargs): kwargs.setdefault('initial', {}) kwargs['initial'].setdefault('trip_kind', 'return') super().__init__(*args, **kwargs)
class MRSRequestCreateForm(forms.ModelForm): # do not trust this field, it's used for javascript and checked # by the view for permission against the request session, but is # NOT to be trusted as input: don't use data['mrsrequest_uuid'] nor # cleaned_data['mrsrequest_uuid'], you've been warned. mrsrequest_uuid = forms.CharField(widget=forms.HiddenInput, required=False) pmt = MRSAttachmentField( PMT, 'mrsrequest:pmt_upload', 'mrsrequest:pmt_download', 20, label='Prescription Médicale de Transport obligatoire', help_text=PMT_HELP, required=False, ) pmt_pel = forms.ChoiceField( choices=( ('pmt', 'PMT (Prescription Papier)'), ('pel', 'PMET (Prescription Électronique)'), ), initial='pmt', label='Avez-vous une ...', widget=forms.RadioSelect, ) pel = forms.CharField( label='Numéro de Prescription Électronique', help_text=PEL_HELP, required=False, ) billvps = MRSAttachmentField( BillVP, 'mrsrequest:billvp_upload', 'mrsrequest:bill_download', 20, label='Justificatifs', required=False, help_text=('Joindre vos justificatifs de péage' ' <span data-parking-enable>' ' / stationnement' ' </span>')) billatps = MRSAttachmentField( BillATP, 'mrsrequest:billatp_upload', 'mrsrequest:bill_download', 20, label='Justificatifs', required=False, help_text=('Joindre vos justificatifs de transport en commun')) caisse = ActiveCaisseChoiceField( label='Votre caisse de rattachement', help_text='Votre caisse n\'apparaît pas dans la liste ? Elle n\'a pas ' 'encore rejoint le dispositif MRS. Cliquez sur "Autre" pour ' 'la sélectionner et recevoir un e-mail dès que celle-ci ' 'sera disponible !') region = ActiveRegionChoiceField(label='Votre région', ) expenseatp = AllowedCommaDecimalField( decimal_places=2, max_digits=6, validators=[validators.MinValueValidator(Decimal('0.00'))], label='Frais de transports', help_text=('Somme totale des frais de transport en commun (en € TTC)'), required=False, widget=forms.TextInput, ) expensevp_toll = AllowedCommaDecimalField( decimal_places=2, max_digits=6, validators=[validators.MinValueValidator(Decimal('0.00'))], label='Frais de péage', help_text=('Somme totale des frais de péage (en € TTC)'), required=False, widget=forms.TextInput, ) expensevp_parking = AllowedCommaDecimalField( decimal_places=2, max_digits=6, validators=[validators.MinValueValidator(Decimal('0.00'))], label='Frais de stationnement', help_text=('Somme totale des frais de stationnement (en € TTC)'), required=False, widget=forms.TextInput, ) layouts = dict( start=material.Layout(material.Fieldset( 'Votre région', 'region', ), ), above=material.Layout( material.Fieldset( 'Votre caisse d\'assurance maladie', 'caisse', ), ), top=material.Layout( material.Fieldset( 'Votre prescription médicale', 'pmt_pel', ), material.Row('pmt', ), material.Row('pel', ), ), modevp=material.Layout('modevp', ), vp_form=material.Layout( material.Row('distancevp', ), material.Row( 'expensevp_toll', 'expensevp_parking', ), 'billvps', ), modeatp=material.Layout('modeatp', ), atp_form=material.Layout( 'expenseatp', 'billatps', ), ) class Meta: model = MRSRequest fields = [ 'caisse', 'expenseatp', 'expensevp_parking', 'expensevp_toll', 'distancevp', 'modevp', 'modeatp', 'pel', ] widgets = dict( distancevp=forms.TextInput, expensevp_toll=forms.TextInput, expensevp_parking=forms.TextInput, ) def __init__(self, *args, **kwargs): kwargs.setdefault('initial', {}) initial = kwargs['initial'] kwargs['initial'].setdefault('expensevp_parking', 0) kwargs['initial'].setdefault('expensevp_toll', 0) if 'mrsrequest_uuid' in kwargs: mrsrequest_uuid = kwargs.pop('mrsrequest_uuid') instance = kwargs.get('instance') if not instance: kwargs['instance'] = MRSRequest() kwargs['instance'].id = mrsrequest_uuid elif 'instance' in kwargs: mrsrequest_uuid = str(kwargs['instance'].id) else: raise Exception('No instance, no uuid, secure it yourself') initial['mrsrequest_uuid'] = mrsrequest_uuid data, files, args, kwargs = self.args_extract(args, kwargs) if data: data, files = self.data_attachments(data, files, mrsrequest_uuid) kwargs['data'] = data kwargs['files'] = files super().__init__(*args, **kwargs) def cleaned_pmt_pel(self, cleaned_data): pmt_pel = cleaned_data.get('pmt_pel', 'pmt') if pmt_pel == 'pmt': cleaned_data.pop('pel', None) if not cleaned_data.get('pmt'): self.add_error('pmt', 'Merci de sélectionner votre PMT') elif pmt_pel == 'pel': if not cleaned_data.get('pel'): self.add_error('pel', 'Merci de saisir votre numéro de PMET') def cleaned_vp_atp(self, cleaned_data): vp = cleaned_data.get('modevp') atp = cleaned_data.get('modeatp') if not vp and not atp: self.add_error( 'modeatp', 'Merci de choisir véhicule personnel et / ou transports en' ' commun', ) self.add_error( 'modevp', 'Merci de choisir véhicule personnel et / ou transports en' ' commun', ) if vp: distancevp = cleaned_data.get('distancevp') if not distancevp: self.add_error( 'distancevp', 'Merci de saisir la distance du trajet', ) expensevp_toll = cleaned_data.get('expensevp_toll') expensevp_parking = cleaned_data.get('expensevp_parking') billvps = cleaned_data.get('billvps') if (expensevp_toll or expensevp_parking) and not billvps: self.add_error( 'billvps', 'Merci de soumettre vos justificatifs de transport') if atp: billatps = cleaned_data.get('billatps') if not billatps: self.add_error( 'billatps', 'Merci de fournir les justificatifs de transport', ) expenseatp = cleaned_data.get('expenseatp') if not expenseatp: self.add_error( 'expenseatp', 'Merci de saisir le total du coût de transports en commun', ) def clean(self): cleaned_data = super().clean() self.cleaned_pmt_pel(cleaned_data) self.cleaned_vp_atp(cleaned_data) return cleaned_data def data_attachments(self, data, files, mrsrequest_uuid): data['pmt'] = PMT.objects.recorded_uploads(mrsrequest_uuid) data['billvps'] = BillVP.objects.recorded_uploads(mrsrequest_uuid) data['billatps'] = BillATP.objects.recorded_uploads(mrsrequest_uuid) if files: files.update(data) else: files = data return data, files def args_extract(self, args, kwargs): """Extract data and files args, return mutable objects.""" # make popable (can't pop tuple of args) args = list(args) def getarg(name, num): if args and len(args) > num: return args.pop(num) elif kwargs.get('files'): return kwargs.pop('files') return None # First to not affect data = args.pop(0) files = getarg('files', 1) data = getarg('data', 0) # make mutable if something if files: files = MultiValueDict(files) if data: data = MultiValueDict(data) return data, files, args, kwargs def save(self, commit=True): if self.cleaned_data.get('parking_expensevp', None): self.instance.expensevp += self.cleaned_data.get( 'parking_expensevp') obj = super().save(commit=commit) def save_attachments(form, obj): if form.cleaned_data.get('pmt_pel') == 'pmt': obj.save_pmt() else: obj.delete_pmt() obj.save_bills() save_m2m = getattr(self, 'save_m2m', None) if save_m2m: def _save_m2m(): save_attachments(self, obj) save_m2m() self.save_m2m = _save_m2m else: save_attachments(self, obj) return obj
class ContactForm(forms.Form): motif = forms.ChoiceField( label='Motif', choices=MOTIF_CHOICES, ) caisse = forms.ModelChoiceField( queryset=Caisse.objects.filter(active=True), label='Votre caisse de rattachement', ) nom = forms.CharField( # noqa max_length=70, validators=name_validators, ) email = forms.EmailField() mrsrequest_display_id = forms.CharField( label='Numéro de demande (optionnel)', required=False, max_length=12, validators=[ validators.RegexValidator( regex=r'^\d{12}$', message=_('MRSREQUEST_UNEXPECTED_DISPLAY_ID'), ) ]) message = forms.CharField(widget=forms.Textarea, max_length=3000) captcha = CaptchaField(required=True) layout = material.Layout( material.Fieldset( ' ', material.Row( 'motif', 'caisse', ), 'mrsrequest_display_id', material.Row( 'nom', 'email', ), 'message', 'captcha', )) def clean_nom(self): return name_clean(self.cleaned_data['nom']) def clean_message(self): message = self.cleaned_data['message'] if re.findall('https?://', message): raise forms.ValidationError( 'Votre message ne doit pas contenir de lien.') if '<' in message: raise forms.ValidationError( 'Votre message ne doit pas contenir de chevrons.') return message def get_email_kwargs(self): data = self.cleaned_data email = getattr(data['caisse'], 'liquidation_email', None) if email: to = [email] else: to = [settings.TEAM_EMAIL] if data['motif'].startswith('request'): subject = 'RÉCLAMATION MRS' else: subject = 'Nouveau message envoyé depuis le site mrs.beta.gouv.fr' body = template.loader.get_template( 'contact/contact_mail_body.txt').render( dict( data=data, motif=dict(self.fields['motif'].choices)[data['motif']], )).strip() return dict( subject=subject, body=body, to=to, reply_to=[data['email']], ) def save(self): instance = Contact( subject=self.cleaned_data['motif'], name=self.cleaned_data['nom'], email=self.cleaned_data['email'], message=self.cleaned_data['message'], ) mid = self.cleaned_data['mrsrequest_display_id'] if mid: mrs = MRSRequest.objects.filter(display_id=mid).first() if mrs: instance.mrsrequest = mrs caisse = self.cleaned_data['caisse'] if caisse != 'other': instance.caisse = self.cleaned_data['caisse'] instance.save() return instance
class PersonForm(forms.ModelForm): nir = forms.CharField( label='Numéro de sécurité sociale', max_length=13, min_length=13, ) birth_date = DateField( label='Date de naissance', ) layout = material.Layout( material.Fieldset( 'Identité de la personne transportée', material.Row( 'first_name', 'last_name', ), 'birth_date', ), material.Fieldset( 'Identité de l\'assuré', material.Row( 'nir', 'email', ) ), ) layout = material.Layout( material.Fieldset( 'Identité de la personne transportée', material.Row( 'first_name', 'last_name', ), 'birth_date', ), material.Fieldset( 'Identité de l\'assuré', material.Row( 'nir', 'email', ) ), ) def clean_nir(self): nir = self.cleaned_data['nir'] try: int(nir) except ValueError: raise forms.ValidationError( 'Doit être composé de 13 chiffres' ) return nir def clean_birth_date(self): data = self.cleaned_data['birth_date'] if data and (now().date() - data).days < 0: raise forms.ValidationError( 'Doit être antèrieure à la date du jour') return data def get_or_create(self): # Return existing person untouched if possible person = Person.objects.filter( birth_date=self.cleaned_data['birth_date'], nir=self.cleaned_data['nir'], ).first() if person: return person # Otherwise create a new Person return super().save() class Meta: model = Person fields = [ 'nir', 'email', 'first_name', 'last_name', 'birth_date', ]
class PersonForm(forms.ModelForm): birth_date = DateFieldNativeWithoutDatepicker(label='Date de naissance', ) nir = CharFieldNative( label='Numéro de Sécurité sociale', help_text='<b>Si le patient transporté est mineur, indiquer ' 'le numéro de Sécurité sociale de son parent</b>', max_length=13, ) first_name = CharFieldNative( label='Prénom', max_length=70, ) last_name = CharFieldNative( label='Nom de famille', max_length=70, ) email = CharFieldNative( label='Adresse email', max_length=254, ) layout = material.Layout( material.Fieldset( '', material.Row( 'first_name', 'last_name', ), 'nir', 'birth_date', material.Row('email', ), )) def clean_birth_date(self): data = self.cleaned_data['birth_date'] if data and (now().date() - data).days < 0: raise forms.ValidationError( 'Doit être antèrieure à la date du jour') return data def clean_first_name(self): return name_clean(self.cleaned_data['first_name']) def clean_last_name(self): return name_clean(self.cleaned_data['last_name']) def get_or_create(self): # Return existing person untouched if possible # Case of twins : we added a unicity check # with the person's first name person = Person.objects.filter( birth_date=self.cleaned_data['birth_date'], nir=self.cleaned_data['nir'], first_name__iexact=self.cleaned_data['first_name']).first() if person: save = False # Ensure legacy data containing invalid last name are fixed try: person.full_clean() except ValidationError as e: if 'last_name' in e.error_dict: person.last_name = self.cleaned_data['last_name'] save = True if ('email' in self.cleaned_data and person.email != self.cleaned_data['email']): save = True person.email = self.cleaned_data['email'] if save: person.save() return person # Otherwise create a new Person return super().save() class Meta: model = Person fields = [ 'nir', 'email', 'first_name', 'last_name', 'birth_date', ]
class GrupoForm(forms.ModelForm): layout = material.Layout( material.Row('name'), material.Fieldset('Permissões de Gestão', material.Row( material.Fieldset("Diretório Acadêmico", material.Column('change_diretorioacademico', 'view_diretorioacademico') ), material.Fieldset("Atas de Reunião", material.Column('add_reuniao', 'change_reuniao', 'delete_reuniao', 'view_reuniao') ), material.Fieldset("Áreas", material.Column('add_area', 'change_area', 'delete_area', 'view_area') ), ), material.Row( material.Fieldset("Alunos", material.Column('add_aluno', 'change_aluno', 'delete_aluno', 'view_aluno') ), material.Fieldset("Egressos", material.Column('add_egresso', 'change_egresso', 'delete_egresso', 'view_egresso') ), material.Fieldset("Diretores", material.Column('add_diretor', 'change_diretor', 'delete_diretor', 'view_diretor') ), material.Fieldset("Grupos", material.Column('add_group', 'change_group', 'delete_group', 'view_group') ), ), ), material.Fieldset('Permissões de Finanças', material.Row( material.Fieldset("Carteiras Financeiras", material.Column('add_carteira', 'change_carteira', 'delete_carteira', 'view_carteira') ), material.Fieldset("Entradas Financeiras", material.Column('add_entradafinanceira', 'change_entradafinanceira', 'delete_entradafinanceira', 'view_entradafinanceira') ), material.Fieldset("Saídas Financeiras", material.Column('add_saidafinanceira', 'change_saidafinanceira', 'delete_saidafinanceira', 'view_saidafinanceira') ), material.Fieldset("Transferências Financeiras", material.Column('add_transferenciafinanceira', 'change_transferenciafinanceira', 'delete_transferenciafinanceira', 'view_transferenciafinanceira') ), ), material.Row( material.Fieldset("Produtos", material.Column('add_produto', 'change_produto', 'delete_produto', 'view_produto') ), material.Fieldset("Recibos de Pagamento", material.Column('add_recibopagamento', 'change_recibopagamento', 'delete_recibopagamento', 'view_recibopagamento') ), material.Fieldset("Vendas", material.Column('add_venda', 'change_venda', 'delete_venda', 'view_venda') ), ), ), material.Fieldset('Permissões de Eventos', material.Row( material.Fieldset("Eventos", material.Column('add_evento', 'change_evento', 'delete_evento', 'view_evento') ), material.Fieldset("Atrações de Eventos", material.Column('add_atracaoevento', 'change_atracaoevento', 'delete_atracaoevento', 'view_atracaoevento') ), material.Fieldset("Inscrições de Eventos", material.Column('add_inscricaoevento', 'change_inscricaoevento', 'delete_inscricaoevento', 'view_inscricaoevento') ), material.Fieldset("Inscrições em Atrações de Eventos", material.Column('add_inscricaoatracao', 'change_inscricaoatracao', 'delete_inscricaoatracao', 'view_inscricaoatracao') ), ), ), ) __content_type_black_list = [ 'logentry', 'permission', 'content_type', 'session', 'cargo', ] __permission_black_list = [ 'add_diretorioacademico', 'delete_diretorioacademico', ] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) permissions_add = Permission.objects.exclude(content_type__model__in=self.__content_type_black_list).exclude( codename__in=self.__permission_black_list).filter(codename__startswith='add_') permissions_change = Permission.objects.exclude(content_type__model__in=self.__content_type_black_list).exclude( codename__in=self.__permission_black_list).filter(codename__startswith='change_') permissions_delete = Permission.objects.exclude(content_type__model__in=self.__content_type_black_list).exclude( codename__in=self.__permission_black_list).filter(codename__startswith='delete_') permissions_view = Permission.objects.exclude(content_type__model__in=self.__content_type_black_list).exclude( codename__in=self.__permission_black_list).filter(codename__startswith='view_') for permission in permissions_add: self.fields[permission.codename] = forms.BooleanField(required=False, initial=False, label='Adicionar') for permission in permissions_change: self.fields[permission.codename] = forms.BooleanField(required=False, initial=False, label='Alterar') for permission in permissions_delete: self.fields[permission.codename] = forms.BooleanField(required=False, initial=False, label='Remover') for permission in permissions_view: self.fields[permission.codename] = forms.BooleanField(required=False, initial=False, label='Visualizar') if self.instance.id: group_permissions = self.instance.permissions.all() for permission in group_permissions: self.fields[permission.codename].initial = True def clean(self): data = {} data['name'] = self.cleaned_data.pop('name') data['permissions'] = [] for permissao in self.cleaned_data: if self.cleaned_data[permissao]: data['permissions'].append(Permission.objects.get(codename=permissao)) self.cleaned_data = data def save(self): group = super().save() group.permissions.clear() for permissao in self.cleaned_data['permissions']: group.permissions.add(permissao) return group class Meta: model = Group fields = ("name",)