from django import forms from django.contrib.auth.forms import UserCreationForm from django.core.exceptions import FieldDoesNotExist from django.forms import ModelForm from mixins.restrictions import RestrictedFormMixin from .models import ( Ad, Aggregator, Asset, LinkGroup, NotificationSettings, OperatorWallets, Platform, Provider, Requisition, User, Wallet, ) # flake8: noqa: E501 class NewUserForm(UserCreationForm): email = forms.EmailField(required=True) class Meta: model = User fields = ( "username", "email", "first_name", "last_name", "password1", "password2", ) def save(self, commit=True): user = super(NewUserForm, self).save(commit=False) user.email = self.cleaned_data["email"] if commit: user.save() return user class CustomUserCreationForm(UserCreationForm): class Meta: model = User fields = "__all__" class NotificationSettingsForm(RestrictedFormMixin, ModelForm): class Meta: model = NotificationSettings fields = ( "ntfy_topic", "ntfy_url", ) help_texts = { "ntfy_topic": "The topic to send notifications to.", "ntfy_url": "Custom NTFY server. Leave blank to use the default server.", } class AggregatorForm(RestrictedFormMixin, ModelForm): def __init__(self, *args, **kwargs): super(AggregatorForm, self).__init__(*args, **kwargs) self.fields["secret_id"].label = "Secret ID" class Meta: model = Aggregator fields = ( "name", "service", "secret_id", "secret_key", "poll_interval", "link_group", "enabled", ) help_texts = { "name": "The name of the aggregator connection.", "service": "The aggregator service to use.", "secret_id": "The secret ID for the aggregator service.", "secret_key": "The secret key for the aggregator service.", "poll_interval": "The interval in seconds to poll the aggregator service.", "link_group": "The link group to use for this aggregator connection.", "enabled": "Whether or not the aggregator connection is enabled.", } class PlatformForm(RestrictedFormMixin, ModelForm): def __init__(self, *args, **kwargs): super(PlatformForm, self).__init__(*args, **kwargs) upper = ["usd", "otp"] for field in self.fields: for up in upper: if self.fields[field].label: if up in self.fields[field].label: self.fields[field].label = self.fields[field].label.replace( up, up.upper() ) class Meta: model = Platform fields = ( "name", "service", "token", "password", "otp_token", "username", "send", "cheat", "dummy", "cheat_interval_seconds", "margin", "max_margin", "min_margin", "min_trade_size_usd", "max_trade_size_usd", "accept_within_usd", "no_reference_amount_check_max_usd", "base_usd", "withdrawal_trigger", "payees", "link_group", "enabled", ) help_texts = { "name": "The name of the platform connection.", "service": "The platform service to use.", "token": "The JWT auth token.", "password": "Account password", "otp_token": "The OTP secret key.", "username": "Account username", "send": "Whether or not to send messages on new trades.", "cheat": "Whether or not to run the Autoprice cheat.", "dummy": "When enabled, the trade escrow feature will be disabled.", "cheat_interval_seconds": "The interval in seconds to run the Autoprice cheat.", "margin": "The current margin. Only valid for initial ads post. Autoprice will override this.", "max_margin": "The maximum margin to use.", "min_margin": "The minimum margin to use.", "min_trade_size_usd": "The minimum trade size in USD.", "max_trade_size_usd": "The maximum trade size in USD.", "accept_within_usd": "When a trade is wrong by less than this amount, it will be accepted.", "no_reference_amount_check_max_usd": "When ticked, when no reference was found and a trade is higher than this amount, we will not accept payment even if it is the only one with this amount.", "base_usd": "The amount in USD to keep in the platform.", "withdrawal_trigger": "The amount above the base USD to trigger a withdrawal.", "payees": "The wallet addresses to send profit concerning this platform to.", "link_group": "The link group to use for this platform.", "enabled": "Whether or not the platform connection is enabled.", } payees = forms.ModelMultipleChoiceField( queryset=Wallet.objects.all(), widget=forms.CheckboxSelectMultiple, help_text=Meta.help_texts["payees"], required=False, ) class AdForm(RestrictedFormMixin, ModelForm): def __init__(self, *args, **kwargs): super(AdForm, self).__init__(*args, **kwargs) class Meta: model = Ad fields = ( "name", "text", "payment_details", "payment_details_real", "payment_method_details", "dist_list", "asset_list", "provider_list", # "platforms", # "aggregators", "require_feedback_score", "account_whitelist", "send_reference", "visible", "link_group", "enabled", ) help_texts = { "name": "The name of the ad.", "text": "The content of the ad.", "payment_details": "Shown before a user opens a trade.", "payment_details_real": "Shown after a user opens a trade.", "payment_method_details": "Shown in the list", "dist_list": "Currency and country, space separated, one pair per line.", "asset_list": "List of assets to distribute ads for.", "provider_list": "List of providers to distribute ads for.", # "platforms": "Enabled platforms for this ad", # "aggregators": "Enabled aggregators for this ad", "require_feedback_score": "Mminimum feedback score for users. Set to 0 to disable.", "account_whitelist": "List of account IDs to use, one per line.", "send_reference": "Whether or not to send the reference on new trades.", "visible": "Whether or not this ad is visible.", "link_group": "The link group to use for this ad.", "enabled": "Whether or not this ad is enabled.", } asset_list = forms.ModelMultipleChoiceField( queryset=Asset.objects.all(), widget=forms.CheckboxSelectMultiple, help_text=Meta.help_texts["asset_list"], required=True, ) provider_list = forms.ModelMultipleChoiceField( queryset=Provider.objects.all(), widget=forms.CheckboxSelectMultiple, help_text=Meta.help_texts["provider_list"], required=True, ) # platforms = forms.ModelMultipleChoiceField( # queryset=Platform.objects.all(), # widget=forms.CheckboxSelectMultiple, # help_text=Meta.help_texts["platforms"], # required=True, # ) # aggregators = forms.ModelMultipleChoiceField( # queryset=Aggregator.objects.all(), # widget=forms.CheckboxSelectMultiple, # help_text=Meta.help_texts["aggregators"], # required=True, # ) class RequisitionForm(RestrictedFormMixin, ModelForm): class Meta: model = Requisition fields = ( "payment_details", "owner_name", "transaction_source", "payees", ) help_texts = { "payment_details": "Shown once a user opens a trade.", "owner_name": "Owner name to send with payment details if not provided by aggregator.", "transaction_source": "Whether to check pending or booked transactions.", "payees": "The wallet addresses to send profit concerning this requisition to.", } payees = forms.ModelMultipleChoiceField( queryset=Wallet.objects.all(), widget=forms.CheckboxSelectMultiple, help_text=Meta.help_texts["payees"], required=False, ) class WalletForm(RestrictedFormMixin, ModelForm): class Meta: model = Wallet fields = ( "name", "address", ) help_texts = { "name": "The name of the wallet.", "address": "The XMR address to send funds to.", } class LinkGroupForm(RestrictedFormMixin, ModelForm): class Meta: model = LinkGroup fields = ( "name", "platform_owner_cut_percentage", "requisition_owner_cut_percentage", "operator_cut_percentage", "enabled", ) help_texts = { "name": "The name of the link group.", "platform_owner_cut_percentage": "The percentage of the total profit of this group to give to the platform owners.", "requisition_owner_cut_percentage": "The percentage of the total profit of this group to give to the requisition owners.", "operator_cut_percentage": "The percentage of the total profit of this group to give to the operator.", "enabled": "Whether or not this link group is enabled.", } def clean(self): cleaned_data = super(LinkGroupForm, self).clean() platform_owner_cut_percentage = cleaned_data.get( "platform_owner_cut_percentage" ) requisition_owner_cut_percentage = cleaned_data.get( "requisition_owner_cut_percentage" ) operator_cut_percentage = cleaned_data.get("operator_cut_percentage") total_sum = ( platform_owner_cut_percentage + requisition_owner_cut_percentage + operator_cut_percentage ) if total_sum != 100: self.add_error( "platform_owner_cut_percentage", f"The sum of the percentages must be 100, not {total_sum}.", ) self.add_error( "requisition_owner_cut_percentage", f"The sum of the percentages must be 100, not {total_sum}.", ) self.add_error( "operator_cut_percentage", f"The sum of the percentages must be 100, not {total_sum}.", ) return return cleaned_data class OperatorWalletsForm(RestrictedFormMixin, ModelForm): class Meta: model = OperatorWallets fields = ("payees",) help_texts = { "payees": "Wallets to designate as payees for this operator.", } payees = forms.ModelMultipleChoiceField( queryset=Wallet.objects.all(), widget=forms.CheckboxSelectMultiple, help_text=Meta.help_texts["payees"], required=False, )