Files
WYGIWYH/app/apps/rules/forms.py
2025-03-09 01:54:03 -03:00

384 lines
14 KiB
Python

from crispy_bootstrap5.bootstrap5 import Switch, BS5Accordion
from crispy_forms.bootstrap import FormActions, AccordionGroup
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field, Row, Column
from django import forms
from django.core.exceptions import ValidationError
from django.utils.translation import gettext_lazy as _
from apps.common.widgets.crispy.submit import NoClassSubmit
from apps.common.widgets.tom_select import TomSelect
from apps.rules.models import TransactionRule, UpdateOrCreateTransactionRuleAction
from apps.rules.models import TransactionRuleAction
class TransactionRuleForm(forms.ModelForm):
class Meta:
model = TransactionRule
fields = "__all__"
exclude = ("owner", "shared_with", "visibility")
labels = {
"on_create": _("Run on creation"),
"on_update": _("Run on update"),
"on_delete": _("Run on delete"),
"trigger": _("If..."),
}
widgets = {"description": forms.widgets.TextInput}
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.form_method = "post"
# TO-DO: Add helper with available commands
self.helper.layout = Layout(
Switch("active"),
"name",
Row(
Column(Switch("on_update")),
Column(Switch("on_create")),
Column(Switch("on_delete")),
),
"description",
"trigger",
)
if self.instance and self.instance.pk:
self.helper.layout.append(
FormActions(
NoClassSubmit(
"submit", _("Update"), css_class="btn btn-outline-primary w-100"
),
),
)
else:
self.helper.layout.append(
FormActions(
NoClassSubmit(
"submit", _("Add"), css_class="btn btn-outline-primary w-100"
),
),
)
class TransactionRuleActionForm(forms.ModelForm):
class Meta:
model = TransactionRuleAction
fields = ("value", "field")
labels = {
"field": _("Set field"),
"value": _("To"),
}
widgets = {"field": TomSelect(clear_button=False)}
def __init__(self, *args, **kwargs):
self.rule = kwargs.pop("rule", None)
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.form_method = "post"
# TO-DO: Add helper with available commands
self.helper.layout = Layout(
"field",
"value",
)
if self.instance and self.instance.pk:
self.helper.layout.append(
FormActions(
NoClassSubmit(
"submit", _("Update"), css_class="btn btn-outline-primary w-100"
),
),
)
else:
self.helper.layout.append(
FormActions(
NoClassSubmit(
"submit", _("Add"), css_class="btn btn-outline-primary w-100"
),
),
)
def clean(self):
cleaned_data = super().clean()
field = cleaned_data.get("field")
if field and self.rule:
# Create a queryset that excludes the current instance
existing_action = TransactionRuleAction.objects.filter(
rule=self.rule, field=field
)
if self.instance.pk:
existing_action = existing_action.exclude(pk=self.instance.pk)
if existing_action.exists():
raise ValidationError(
_("A value for this field already exists in the rule.")
)
return cleaned_data
def save(self, commit=True):
instance = super().save(commit=False)
instance.rule = self.rule
if commit:
instance.save()
return instance
class UpdateOrCreateTransactionRuleActionForm(forms.ModelForm):
class Meta:
model = UpdateOrCreateTransactionRuleAction
exclude = ("rule",)
widgets = {
"search_account_operator": TomSelect(clear_button=False),
"search_type_operator": TomSelect(clear_button=False),
"search_is_paid_operator": TomSelect(clear_button=False),
"search_date_operator": TomSelect(clear_button=False),
"search_reference_date_operator": TomSelect(clear_button=False),
"search_amount_operator": TomSelect(clear_button=False),
"search_description_operator": TomSelect(clear_button=False),
"search_notes_operator": TomSelect(clear_button=False),
"search_category_operator": TomSelect(clear_button=False),
"search_internal_note_operator": TomSelect(clear_button=False),
"search_internal_id_operator": TomSelect(clear_button=False),
}
labels = {
"search_account_operator": _("Operator"),
"search_type_operator": _("Operator"),
"search_is_paid_operator": _("Operator"),
"search_date_operator": _("Operator"),
"search_reference_date_operator": _("Operator"),
"search_amount_operator": _("Operator"),
"search_description_operator": _("Operator"),
"search_notes_operator": _("Operator"),
"search_category_operator": _("Operator"),
"search_internal_note_operator": _("Operator"),
"search_internal_id_operator": _("Operator"),
"search_tags_operator": _("Operator"),
"search_entities_operator": _("Operator"),
"search_account": _("Account"),
"search_type": _("Type"),
"search_is_paid": _("Paid"),
"search_date": _("Date"),
"search_reference_date": _("Reference Date"),
"search_amount": _("Amount"),
"search_description": _("Description"),
"search_notes": _("Notes"),
"search_category": _("Category"),
"search_internal_note": _("Internal Note"),
"search_internal_id": _("Internal ID"),
"search_tags": _("Tags"),
"search_entities": _("Entities"),
"set_account": _("Account"),
"set_type": _("Type"),
"set_is_paid": _("Paid"),
"set_date": _("Date"),
"set_reference_date": _("Reference Date"),
"set_amount": _("Amount"),
"set_description": _("Description"),
"set_tags": _("Tags"),
"set_entities": _("Entities"),
"set_notes": _("Notes"),
"set_category": _("Category"),
"set_internal_note": _("Internal Note"),
"set_internal_id": _("Internal ID"),
}
def __init__(self, *args, **kwargs):
self.rule = kwargs.pop("rule", None)
super().__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = False
self.helper.form_method = "post"
self.helper.layout = Layout(
BS5Accordion(
AccordionGroup(
_("Search Criteria"),
Field("filter", rows=1),
Row(
Column(
Field("search_type_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_type", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_is_paid_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_is_paid", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_account_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_account", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_entities_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_entities", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_date_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_date", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_reference_date_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_reference_date", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_description_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_description", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_amount_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_amount", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_category_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_category", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_tags_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_tags", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_notes_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_notes", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_internal_note_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_internal_note", rows=1),
css_class="form-group col-md-8",
),
),
Row(
Column(
Field("search_internal_id_operator"),
css_class="form-group col-md-4",
),
Column(
Field("search_internal_id", rows=1),
css_class="form-group col-md-8",
),
),
active=True,
),
AccordionGroup(
_("Set Values"),
Field("set_type", rows=1),
Field("set_is_paid", rows=1),
Field("set_account", rows=1),
Field("set_entities", rows=1),
Field("set_date", rows=1),
Field("set_reference_date", rows=1),
Field("set_description", rows=1),
Field("set_amount", rows=1),
Field("set_category", rows=1),
Field("set_tags", rows=1),
Field("set_notes", rows=1),
Field("set_internal_note", rows=1),
Field("set_internal_id", rows=1),
css_class="mb-3",
active=True,
),
always_open=True,
),
)
if self.instance and self.instance.pk:
self.helper.layout.append(
FormActions(
NoClassSubmit(
"submit", _("Update"), css_class="btn btn-outline-primary w-100"
),
),
)
else:
self.helper.layout.append(
FormActions(
NoClassSubmit(
"submit", _("Add"), css_class="btn btn-outline-primary w-100"
),
),
)
def save(self, commit=True):
instance = super().save(commit=False)
instance.rule = self.rule
if commit:
instance.save()
return instance