# lingo - basket and payment system # Copyright (C) 2019 Entr'ouvert # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU Affero General Public License as published # by the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import datetime from django import forms from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ from .models import Regie, PaymentBackend TYPE_FIELD_MAPPING = { str: forms.CharField, bool: forms.BooleanField, int: forms.IntegerField, float: forms.FloatField, } def get_validator(func, err_msg): def validate(value): if not func(value): message = err_msg or _('Invalid value.') raise ValidationError(message) return validate def create_form_fields(parameters, json_field): fields, initial = [], {} for param in parameters: field_name = param['name'] if field_name in ('normal_return_url', 'automatic_return_url') or param.get('deprecated'): continue field_params = { 'label': param.get('caption') or field_name, 'required': param.get('required', False) } if 'validation' in param: field_params['validators'] = [ get_validator(param['validation'], param.get('validation_err_msg')) ] _type = param.get('type', str) choices = param.get('choices') if choices is not None: field_class = forms.MultipleChoiceField if _type is list else forms.ChoiceField if choices and not isinstance(choices[0], tuple): choices = [(choice, choice) for choice in choices] field_params['choices'] = choices else: field_class = TYPE_FIELD_MAPPING[_type] fields.append((field_name, field_class(**field_params))) initial_value = json_field.get(field_name, param.get('default')) if initial_value: initial[field_name] = initial_value return fields, initial def compute_json_field(parameters, cleaned_data): json_field = {} for param in parameters: param_name = param['name'] if param_name in cleaned_data: json_field[param_name] = cleaned_data[param_name] return json_field class RegieForm(forms.ModelForm): class Meta: model = Regie fields = ['label', 'slug', 'description', 'payment_backend', 'is_default', 'webservice_url', 'extra_fees_ws_url', 'payment_min_amount', 'text_on_success'] def __init__(self, *args, **kwargs): super(RegieForm, self).__init__(*args, **kwargs) fields, initial = create_form_fields( self.instance.payment_backend.get_payment().get_parameters(scope='transaction'), self.instance.transaction_options ) self.fields.update(fields) self.initial.update(initial) def save(self): instance = super(RegieForm, self).save() instance.transaction_options = compute_json_field( self.instance.payment_backend.get_payment().get_parameters(scope='transaction'), self.cleaned_data ) instance.save() return instance class PaymentBackendForm(forms.ModelForm): class Meta: model = PaymentBackend fields = ['label', 'slug', 'service'] def __init__(self, *args, **kwargs): super(PaymentBackendForm, self).__init__(*args, **kwargs) fields, initial = create_form_fields( self.instance.get_payment().get_parameters(scope='global'), self.instance.service_options ) self.fields.update(fields) self.initial.update(initial) if self.fields['service']: self.fields['service'].disabled = True def save(self): instance = super(PaymentBackendForm, self).save() instance.service_options = compute_json_field( self.instance.get_payment().get_parameters(scope='global'), self.cleaned_data ) instance.save() return instance class TransactionExportForm(forms.Form): start_date = forms.DateField( label=_('Start date'), widget=forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d') ) end_date = forms.DateField( label=_('End date'), widget=forms.DateInput(attrs={'type': 'date'}, format='%Y-%m-%d') ) def __init__(self, *args, **kwargs): super(TransactionExportForm, self).__init__(*args, **kwargs) today = datetime.date.today() self.initial['start_date'] = today - datetime.timedelta(days=30) self.initial['end_date'] = today