Source code for richy.transactions.forms

import re

from django import forms
from django.core.validators import MinValueValidator, RegexValidator
from django.utils.translation import gettext as _

from ..core.fields import MultipleFileField
from ..core.models import Item
from ..core.widgets import NoLabelCheckboxSelectMultiple
from ..staking.models import Staking
from .models import Attachment, Transaction


[docs] class TransactionForm(forms.ModelForm): attachments = MultipleFileField( required=False, delete_url_pattern="transactions:delete_attachment" ) class Meta: model = Transaction fields = ( "parents", "item", "price", "amount", "fee", "currency", "target", "date", "exchange", "note", "is_closing", "is_closed", "is_deposit", "closed_on", ) def __init__(self, user, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["item"].empty_label = "" self.fields["item"].queryset = Item.objects.filter( pk__in=user.useritem_set.values_list("item", flat=True) ).order_by("symbol") self.fields["exchange"].empty_label = "" self.fields["date"].widget.attrs["autocomplete"] = "off" self.fields["closed_on"].widget.attrs["autocomplete"] = "off" self.fields["parents"].queryset = ( Transaction.objects.by_user(user) .select_related("item", "exchange") .order_by("-date") ) self.fields["currency"].validators = [ RegexValidator( "^[a-zA-Z]{3}$", message=_("Please enter 3 alpha only chars") ), ] self.fields["price"].validators = [MinValueValidator(0)] self.fields["fee"].validators = [MinValueValidator(0)] self.fields["target"].help_text = _( 'Use as a price target or percentage gain with "%" character.' ) self.fields["is_deposit"].help_text = _( "Marks the transaction as an entrypoint of transaction chain." ) self.fields["is_closing"].help_text = _( "Marks the transaction as an endpoint of transaction chain." ) self.fields["is_closed"].help_text = _( "Marks the transaction as closed. Closed transactions are those whose assets has been sold." )
[docs] def clean(self): """ Validates: * if exchange is filled for coins * echanging is forbidden for shares (not possbible) """ data = super().clean() # Coins must have exchange filled. if hasattr(data.get("item"), "coin") and not data.get("exchange"): self.add_error("exchange", _("Please choose an exchange.")) # Deposit cannot be closing. if data.get("is_closing") and data.get("is_deposit"): self.add_error("is_closing", _("Deposit cannot be closing.")) # Positive transaction cannot be closing - only negative ones. if 0 < data.get("amount") and data.get("is_closing"): self.add_error("is_closing", _("Positive transaction cannot be closing.")) # Closed transaction must have closed date filled. if (data.get("is_closing") or data.get("is_closed")) and not data.get( "closed_on" ): self.add_error("closed_on", _("Please fill in closed date.")) # Negative amount (sell transaction) must have a parent(s). if 0 > data.get("amount") and not data.get("parents"): self.add_error("parents", _("Please select parent transaction.")) return data
[docs] def clean_target(self): target = self.cleaned_data["target"] # Match numbers only with the possibility of trailing "%". if target and not re.match("^[0-9]+%?$", target): raise forms.ValidationError( 'Target must contains of numbers and one "%" symbol only.' ) return target
[docs] def save(self, *args, **kwargs): to_return = super().save(*args, **kwargs) for file in self.files.getlist("attachments"): Attachment.objects.create( transaction=self.instance, file=file, ) return to_return
[docs] class PostClosedOrClosingTransactionForm(forms.Form): parents = forms.ModelMultipleChoiceField( queryset=Transaction.objects.all(), required=False, widget=NoLabelCheckboxSelectMultiple(), ) stakings = forms.ModelMultipleChoiceField( queryset=Staking.objects.all(), required=False, widget=forms.CheckboxSelectMultiple(), ) def __init__(self, parents, stakings, *args, **kwargs): super().__init__(*args, **kwargs) self.fields["parents"].queryset = parents self.fields["stakings"].queryset = stakings