mirror of
https://github.com/eitchtee/WYGIWYH.git
synced 2026-03-19 07:54:08 +01:00
refactor: move some fields and widgets around
This commit is contained in:
@@ -14,7 +14,7 @@ from apps.common.fields.forms.dynamic_select import (
|
||||
from apps.common.widgets.crispy.submit import NoClassSubmit
|
||||
from apps.common.widgets.tom_select import TomSelect
|
||||
from apps.transactions.models import TransactionCategory, TransactionTag
|
||||
from apps.transactions.widgets import ArbitraryDecimalDisplayNumberInput
|
||||
from apps.common.widgets.decimal import ArbitraryDecimalDisplayNumberInput
|
||||
|
||||
|
||||
class AccountGroupForm(forms.ModelForm):
|
||||
|
||||
@@ -4,10 +4,10 @@ from django import forms
|
||||
from django.db import models
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from apps.transactions.widgets import MonthYearWidget
|
||||
from apps.common.widgets.month_year import MonthYearWidget
|
||||
|
||||
|
||||
class MonthYearField(models.DateField):
|
||||
class MonthYearModelField(models.DateField):
|
||||
def to_python(self, value):
|
||||
if value is None or isinstance(value, datetime.date):
|
||||
return value
|
||||
@@ -27,6 +27,8 @@ class MonthYearField(models.DateField):
|
||||
|
||||
|
||||
class MonthYearFormField(forms.DateField):
|
||||
widget = MonthYearWidget
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.input_formats = ["%Y-%m"]
|
||||
@@ -34,11 +36,13 @@ class MonthYearFormField(forms.DateField):
|
||||
def to_python(self, value):
|
||||
if value in self.empty_values:
|
||||
return None
|
||||
if isinstance(value, datetime.datetime):
|
||||
return value.date()
|
||||
try:
|
||||
date = datetime.datetime.strptime(value, "%Y-%m")
|
||||
return date.replace(day=1).date()
|
||||
except ValueError:
|
||||
raise ValidationError("Invalid date format. Use YYYY-MM.")
|
||||
raise ValidationError(_("Invalid date format. Use YYYY-MM."))
|
||||
|
||||
def prepare_value(self, value):
|
||||
if isinstance(value, datetime.date):
|
||||
@@ -1,9 +1,6 @@
|
||||
from datetime import datetime, date
|
||||
|
||||
from django import forms
|
||||
from decimal import Decimal, InvalidOperation
|
||||
|
||||
from django.template.defaultfilters import floatformat
|
||||
from django import forms
|
||||
from django.utils.formats import get_format, number_format
|
||||
|
||||
|
||||
@@ -25,19 +22,6 @@ def convert_to_decimal(value: str):
|
||||
return None
|
||||
|
||||
|
||||
class MonthYearWidget(forms.DateInput):
|
||||
"""
|
||||
Custom widget to display a month-year picker.
|
||||
"""
|
||||
|
||||
input_type = "month" # Set the input type to 'month'
|
||||
|
||||
def format_value(self, value):
|
||||
if isinstance(value, (datetime, date)):
|
||||
return value.strftime("%Y-%m")
|
||||
return value
|
||||
|
||||
|
||||
class ArbitraryDecimalDisplayNumberInput(forms.TextInput):
|
||||
"""A widget for displaying and inputing decimal numbers with the least amount of trailing zeros possible. You
|
||||
must set this on your Form's __init__ method."""
|
||||
16
app/apps/common/widgets/month_year.py
Normal file
16
app/apps/common/widgets/month_year.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from datetime import datetime, date
|
||||
|
||||
from django import forms
|
||||
|
||||
|
||||
class MonthYearWidget(forms.DateInput):
|
||||
"""
|
||||
Custom widget to display a month-year picker.
|
||||
"""
|
||||
|
||||
input_type = "month" # Set the input type to 'month'
|
||||
|
||||
def format_value(self, value):
|
||||
if isinstance(value, (datetime, date)):
|
||||
return value.strftime("%Y-%m")
|
||||
return value
|
||||
@@ -1,11 +1,10 @@
|
||||
from crispy_bootstrap5.bootstrap5 import Switch
|
||||
from crispy_forms.bootstrap import FormActions
|
||||
from crispy_forms.helper import FormHelper
|
||||
from crispy_forms.layout import Layout, Row, Column, Field, Fieldset
|
||||
from crispy_forms.layout import Layout, Row, Column, Field
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from django import forms
|
||||
from django.db import transaction
|
||||
from django.utils.safestring import mark_safe
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from apps.accounts.models import Account
|
||||
@@ -14,17 +13,15 @@ from apps.common.fields.forms.dynamic_select import (
|
||||
DynamicModelMultipleChoiceField,
|
||||
)
|
||||
from apps.common.widgets.crispy.submit import NoClassSubmit
|
||||
from apps.common.widgets.tom_select import TomSelect, TomSelectMultiple
|
||||
from apps.common.widgets.tom_select import TomSelect
|
||||
from apps.transactions.models import (
|
||||
Transaction,
|
||||
TransactionCategory,
|
||||
TransactionTag,
|
||||
InstallmentPlan,
|
||||
)
|
||||
from apps.transactions.widgets import (
|
||||
ArbitraryDecimalDisplayNumberInput,
|
||||
MonthYearWidget,
|
||||
)
|
||||
from apps.common.widgets.decimal import ArbitraryDecimalDisplayNumberInput
|
||||
from apps.common.fields.month_year import MonthYearFormField
|
||||
|
||||
|
||||
class TransactionForm(forms.ModelForm):
|
||||
@@ -40,6 +37,7 @@ class TransactionForm(forms.ModelForm):
|
||||
required=False,
|
||||
label=_("Tags"),
|
||||
)
|
||||
reference_date = MonthYearFormField(label=_("Reference Date"), required=False)
|
||||
|
||||
class Meta:
|
||||
model = Transaction
|
||||
@@ -190,7 +188,7 @@ class TransferForm(forms.Form):
|
||||
date = forms.DateField(
|
||||
label="Date", widget=forms.DateInput(attrs={"type": "date"}, format="%Y-%m-%d")
|
||||
)
|
||||
reference_date = forms.CharField(label="Reference Date", widget=MonthYearWidget())
|
||||
reference_date = MonthYearFormField(label=_("Reference Date"), required=False)
|
||||
description = forms.CharField(max_length=500, label="Description")
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
@@ -324,6 +322,7 @@ class InstallmentPlanForm(forms.Form):
|
||||
label=_("Start Date"),
|
||||
widget=forms.DateInput(attrs={"type": "date"}, format="%Y-%m-%d"),
|
||||
)
|
||||
reference_date = MonthYearFormField(label=_("Reference Date"), required=False)
|
||||
description = forms.CharField(max_length=500, label=_("Description"))
|
||||
number_of_installments = forms.IntegerField(
|
||||
min_value=1, label=_("Number of Installments")
|
||||
@@ -372,9 +371,13 @@ class InstallmentPlanForm(forms.Form):
|
||||
"account",
|
||||
"description",
|
||||
Row(
|
||||
Column("start_date", css_class="form-group col-md-4 mb-0"),
|
||||
Column("number_of_installments", css_class="form-group col-md-4 mb-0"),
|
||||
Column("recurrence", css_class="form-group col-md-4 mb-0"),
|
||||
Column("number_of_installments", css_class="form-group col-md-6 mb-0"),
|
||||
Column("recurrence", css_class="form-group col-md-6 mb-0"),
|
||||
css_class="form-row",
|
||||
),
|
||||
Row(
|
||||
Column("start_date", css_class="form-group col-md-6 mb-0"),
|
||||
Column("reference_date", css_class="form-group col-md-6 mb-0"),
|
||||
css_class="form-row",
|
||||
),
|
||||
"installment_amount",
|
||||
@@ -396,12 +399,16 @@ class InstallmentPlanForm(forms.Form):
|
||||
number_of_installments = self.cleaned_data["number_of_installments"]
|
||||
transaction_type = self.cleaned_data["type"]
|
||||
start_date = self.cleaned_data["start_date"]
|
||||
reference_date = self.cleaned_data["reference_date"] or start_date
|
||||
recurrence = self.cleaned_data["recurrence"]
|
||||
account = self.cleaned_data["account"]
|
||||
description = self.cleaned_data["description"]
|
||||
installment_amount = self.cleaned_data["installment_amount"]
|
||||
category = self.cleaned_data["category"]
|
||||
|
||||
print(reference_date, type(reference_date))
|
||||
print(start_date, type(start_date))
|
||||
|
||||
with transaction.atomic():
|
||||
installment_plan = InstallmentPlan.objects.create(
|
||||
account=account,
|
||||
@@ -421,11 +428,13 @@ class InstallmentPlanForm(forms.Form):
|
||||
delta = relativedelta(days=i)
|
||||
|
||||
transaction_date = start_date + delta
|
||||
transaction_reference_date = (reference_date + delta).replace(day=1)
|
||||
new_transaction = Transaction.objects.create(
|
||||
account=account,
|
||||
type=transaction_type,
|
||||
date=transaction_date,
|
||||
reference_date=transaction_date.replace(day=1),
|
||||
is_paid=False,
|
||||
reference_date=transaction_reference_date,
|
||||
amount=installment_amount,
|
||||
description=description,
|
||||
notes=f"{i + 1}/{number_of_installments}",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Generated by Django 5.1.1 on 2024-09-19 02:11
|
||||
|
||||
import apps.transactions.fields
|
||||
import apps.common.fields.month_year
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
@@ -8,19 +8,31 @@ class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
dependencies = []
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Transaction',
|
||||
name="Transaction",
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('is_paid', models.BooleanField(default=True)),
|
||||
('date', models.DateField()),
|
||||
('reference_date', apps.transactions.fields.MonthYearField(help_text='Please enter a month and year in the format MM/YYYY.')),
|
||||
('description', models.CharField(max_length=500)),
|
||||
('notes', models.TextField(blank=True)),
|
||||
(
|
||||
"id",
|
||||
models.BigAutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("is_paid", models.BooleanField(default=True)),
|
||||
("date", models.DateField()),
|
||||
(
|
||||
"reference_date",
|
||||
apps.common.fields.month_year.MonthYearModelField(
|
||||
help_text="Please enter a month and year in the format MM/YYYY."
|
||||
),
|
||||
),
|
||||
("description", models.CharField(max_length=500)),
|
||||
("notes", models.TextField(blank=True)),
|
||||
],
|
||||
),
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Generated by Django 5.1.1 on 2024-09-19 13:35
|
||||
|
||||
import apps.transactions.fields
|
||||
import apps.common.fields.month_year
|
||||
import apps.transactions.validators
|
||||
import django.db.models.deletion
|
||||
from django.db import migrations, models
|
||||
@@ -9,46 +9,62 @@ from django.db import migrations, models
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('accounts', '0001_initial'),
|
||||
('transactions', '0001_initial'),
|
||||
("accounts", "0001_initial"),
|
||||
("transactions", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='transaction',
|
||||
name='account',
|
||||
field=models.ForeignKey(default=0, on_delete=django.db.models.deletion.PROTECT, to='accounts.account', verbose_name='Account'),
|
||||
model_name="transaction",
|
||||
name="account",
|
||||
field=models.ForeignKey(
|
||||
default=0,
|
||||
on_delete=django.db.models.deletion.PROTECT,
|
||||
to="accounts.account",
|
||||
verbose_name="Account",
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='transaction',
|
||||
name='amount',
|
||||
field=models.DecimalField(decimal_places=18, default=0, max_digits=30, validators=[apps.transactions.validators.validate_non_negative, apps.transactions.validators.validate_decimal_places], verbose_name='Amount'),
|
||||
model_name="transaction",
|
||||
name="amount",
|
||||
field=models.DecimalField(
|
||||
decimal_places=18,
|
||||
default=0,
|
||||
max_digits=30,
|
||||
validators=[
|
||||
apps.transactions.validators.validate_non_negative,
|
||||
apps.transactions.validators.validate_decimal_places,
|
||||
],
|
||||
verbose_name="Amount",
|
||||
),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='transaction',
|
||||
name='date',
|
||||
field=models.DateField(verbose_name='Date'),
|
||||
model_name="transaction",
|
||||
name="date",
|
||||
field=models.DateField(verbose_name="Date"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='transaction',
|
||||
name='description',
|
||||
field=models.CharField(max_length=500, verbose_name='Description'),
|
||||
model_name="transaction",
|
||||
name="description",
|
||||
field=models.CharField(max_length=500, verbose_name="Description"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='transaction',
|
||||
name='is_paid',
|
||||
field=models.BooleanField(default=True, verbose_name='Paid'),
|
||||
model_name="transaction",
|
||||
name="is_paid",
|
||||
field=models.BooleanField(default=True, verbose_name="Paid"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='transaction',
|
||||
name='notes',
|
||||
field=models.TextField(blank=True, verbose_name='Notes'),
|
||||
model_name="transaction",
|
||||
name="notes",
|
||||
field=models.TextField(blank=True, verbose_name="Notes"),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='transaction',
|
||||
name='reference_date',
|
||||
field=apps.transactions.fields.MonthYearField(verbose_name='Reference Date'),
|
||||
model_name="transaction",
|
||||
name="reference_date",
|
||||
field=apps.common.fields.month_year.MonthYearModelField(
|
||||
verbose_name="Reference Date"
|
||||
),
|
||||
),
|
||||
]
|
||||
|
||||
@@ -6,9 +6,9 @@ from django.utils.functional import cached_property
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from apps.common.functions.decimals import truncate_decimal
|
||||
from apps.transactions.fields import MonthYearField
|
||||
from apps.transactions.validators import validate_decimal_places, validate_non_negative
|
||||
from apps.currencies.utils.convert import convert
|
||||
from apps.common.fields.month_year import MonthYearModelField
|
||||
|
||||
|
||||
class TransactionCategory(models.Model):
|
||||
@@ -76,7 +76,7 @@ class Transaction(models.Model):
|
||||
)
|
||||
is_paid = models.BooleanField(default=True, verbose_name=_("Paid"))
|
||||
date = models.DateField(verbose_name=_("Date"))
|
||||
reference_date = MonthYearField(verbose_name=_("Reference Date"))
|
||||
reference_date = MonthYearModelField(verbose_name=_("Reference Date"))
|
||||
|
||||
amount = models.DecimalField(
|
||||
max_digits=42,
|
||||
|
||||
Reference in New Issue
Block a user