108 lines
3.4 KiB
Python
108 lines
3.4 KiB
Python
from django import forms
|
|
|
|
from .models import Item, ItemNote, ItemTemplate
|
|
|
|
|
|
class ItemTemplateForm(forms.ModelForm):
|
|
class Meta:
|
|
model = ItemTemplate
|
|
fields = [
|
|
"name",
|
|
"description",
|
|
"category",
|
|
"field_definitions",
|
|
"default_purchase_price",
|
|
"default_estimated_resale_price",
|
|
"default_notes",
|
|
"is_active",
|
|
]
|
|
widgets = {
|
|
"field_definitions": forms.Textarea(attrs={"rows": 4, "placeholder": '[{"name":"rewind","label":"Rewind?","type":"boolean"}]'}),
|
|
}
|
|
|
|
def clean_field_definitions(self):
|
|
raw = self.cleaned_data.get("field_definitions")
|
|
# Allow users to provide a JSON string or a python list
|
|
if raw in (None, ""):
|
|
return []
|
|
|
|
if isinstance(raw, str):
|
|
import json
|
|
|
|
try:
|
|
parsed = json.loads(raw)
|
|
except Exception as e:
|
|
raise forms.ValidationError("Invalid JSON for field_definitions: %s" % e)
|
|
else:
|
|
parsed = raw
|
|
|
|
if not isinstance(parsed, list):
|
|
raise forms.ValidationError("field_definitions must be a JSON list of field descriptors")
|
|
|
|
# Basic validation for each field descriptor
|
|
for entry in parsed:
|
|
if not isinstance(entry, dict) or "name" not in entry or "type" not in entry:
|
|
raise forms.ValidationError("Each field definition must be an object with at least 'name' and 'type'")
|
|
|
|
return parsed
|
|
|
|
|
|
class ItemForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Item
|
|
fields = [
|
|
"template",
|
|
"title",
|
|
"brand",
|
|
"category",
|
|
"condition",
|
|
"size",
|
|
"color",
|
|
"purchase_price",
|
|
"estimated_resale_price",
|
|
"notes",
|
|
]
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["category"].required = False
|
|
self.fields["purchase_price"].required = False
|
|
self.fields["estimated_resale_price"].required = False
|
|
|
|
def clean(self):
|
|
cleaned_data = super().clean()
|
|
template = cleaned_data.get("template")
|
|
|
|
if not cleaned_data.get("category") and not template:
|
|
self.add_error("category", "Category is required when no template is selected.")
|
|
if cleaned_data.get("purchase_price") in (None, "") and not template:
|
|
self.add_error("purchase_price", "Purchase price is required when no template is selected.")
|
|
|
|
return cleaned_data
|
|
|
|
|
|
class ItemSoldForm(forms.ModelForm):
|
|
class Meta:
|
|
model = Item
|
|
fields = ["sold_price", "ebay_fee", "shipping_cost", "sold_at"]
|
|
|
|
|
|
class ItemNoteForm(forms.ModelForm):
|
|
class Meta:
|
|
model = ItemNote
|
|
fields = ["body"]
|
|
|
|
|
|
class ItemFilterForm(forms.Form):
|
|
query = forms.CharField(required=False)
|
|
status = forms.ChoiceField(required=False, choices=[("", "All")])
|
|
category = forms.CharField(required=False)
|
|
created_by = forms.CharField(required=False)
|
|
min_purchase_price = forms.DecimalField(required=False, min_value=0)
|
|
max_purchase_price = forms.DecimalField(required=False, min_value=0)
|
|
min_profit = forms.DecimalField(required=False)
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.fields["status"].choices = [("", "All")] + list(Item.Status.choices)
|