Commit f6fbd3ed authored by MOREAU Ulysse's avatar MOREAU Ulysse
Browse files

Merge branch 'shop-options' into 'master'

Shop options

See merge request pole-web/website!47
parents a7f6bae1 0ab9bcc1
......@@ -20,14 +20,52 @@ User = get_user_model()
class OrderItemForm(forms.ModelForm):
quantity = forms.IntegerField(min_value=1, label="Quantité")
quantity = forms.IntegerField(min_value=1, label="Quantité", initial=1)
customization = forms.CharField(label="Perso", required=False)
option = forms.ChoiceField(label="Option 1", required=False)
second_option = forms.ChoiceField(label="Option 2", required=False)
def __init__(self, *args, **kwargs) -> None:
def __init__(self, item=None, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
instance = getattr(self, "instance", None)
if item is None:
item = instance.item
if not item.customization:
self.fields["customization"].widget = forms.HiddenInput()
if item.option == "":
self.fields["option"].widget = forms.HiddenInput()
self.fields["option"].required = False
else:
self.fields["option"].label = item.option_label
options = item.option.split(";")
choices = []
for choice in options:
choices.append((choice, choice))
self.fields["option"].choices = choices
if item.second_option == "":
self.fields["second_option"].widget = forms.HiddenInput()
self.fields["second_option"].required = False
else:
self["second_option"].label = item.second_option_label
options = item.second_option.split(";")
choices = []
for choice in options:
choices.append((choice, choice))
self.fields["second_option"].choices = choices
if item.customizable:
self.fields["quantity"].widget.attrs["disabled"] = False
self.fields["quantity"].widget.attrs["readonly"] = True
if hasattr(instance, "item"):
if instance.pack_parent or instance.item.special:
self.fields["quantity"].widget.attrs["readonly"] = True
if instance.pack_parent:
self.fields["quantity"].widget.attrs[
"title"
......@@ -36,11 +74,18 @@ class OrderItemForm(forms.ModelForm):
self.fields["quantity"].widget.attrs[
"title"
] = "Vous ne pouvez pas modifier la quantité d'un item contenu dans un pack"
self.fields["customization"].initial = instance.customization
self.fields["option"].initial = instance.option
self.fields["second_option"].initial = instance.second_option
self.fields["quantity"].initial = instance.quantity
class Meta:
model = OrderItem
fields = [
"quantity",
"customization",
"option",
"second_option",
]
......@@ -55,6 +100,10 @@ class SellForm(forms.Form):
quantity = forms.IntegerField(min_value=1, initial=1)
mean = forms.ChoiceField(choices=settings.PAYMENT_MEANS)
customization = forms.CharField(label="Perso", required=False)
option = forms.ChoiceField(label="Option 1", required=False)
second_option = forms.ChoiceField(label="Option 2", required=False)
def __init__(self, *args, instance: Optional[OrderItem] = None, **kwargs) -> None:
# adds `instance` parameter to emulate ModelForm interface
super().__init__(*args, **kwargs)
......@@ -77,6 +126,16 @@ class SellForm(forms.Form):
class ItemForm(forms.ModelForm):
option = forms.CharField(
label="Option 1 (séparer les choix par ';' )", required=False
)
option_label = forms.CharField(label="Titre option 1", required=False)
second_option = forms.CharField(
label="Option 2 (séparer les choix par ';' )", required=False
)
second_option_label = forms.CharField(label="Titre option 2", required=False)
class Meta:
model = Item
fields = [
......@@ -91,6 +150,11 @@ class ItemForm(forms.ModelForm):
"children",
"action",
"event",
"customization",
"option",
"option_label",
"second_option",
"second_option_label",
]
labels = {
"name": "Nom",
......@@ -101,6 +165,11 @@ class ItemForm(forms.ModelForm):
"hidden": "Produit caché",
"children": "Produits inclus",
"event": "Événement",
"customization": "Personalisation",
"option": "Option 1 (séparer les choix par ';' )",
"option_label": "Nom de l'option 1",
"second_option": "Option 2 (séparer les choix par ';' )",
"second_option_label": "Nom de l'option 2",
}
widgets = {
"children": forms.CheckboxSelectMultiple,
......
......@@ -13,7 +13,9 @@ class Migration(migrations.Migration):
operations = [
migrations.RenameField(
model_name="item", old_name="childrens", new_name="children",
model_name="item",
old_name="childrens",
new_name="children",
),
migrations.AlterField(
model_name="order",
......
......@@ -11,7 +11,10 @@ class Migration(migrations.Migration):
]
operations = [
migrations.RemoveField(model_name="orderitem", name="delivered",),
migrations.RemoveField(
model_name="orderitem",
name="delivered",
),
migrations.AddField(
model_name="orderitem",
name="quantity_delivered",
......
......@@ -11,6 +11,8 @@ class Migration(migrations.Migration):
operations = [
migrations.AddField(
model_name="item", name="hidden", field=models.BooleanField(default=False),
model_name="item",
name="hidden",
field=models.BooleanField(default=False),
),
]
......@@ -5,9 +5,9 @@ from django.db import models
def migrate_data(apps, schema_editor):
Payment = apps.get_model("boutique", "Payment")
Payment.objects.using(schema_editor.connection.alias).filter(
mean="cb"
).update(mean="card")
Payment.objects.using(schema_editor.connection.alias).filter(mean="cb").update(
mean="card"
)
class Migration(migrations.Migration):
......
# Generated by Django 2.2.16 on 2020-11-17 17:42
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("boutique", "0016_auto_20200904_2132"),
]
operations = [
migrations.AddField(
model_name="item",
name="customization",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name="item",
name="option",
field=models.CharField(default=None, max_length=255),
),
migrations.AddField(
model_name="item",
name="option_label",
field=models.CharField(default=None, max_length=255),
),
migrations.AddField(
model_name="item",
name="second_option",
field=models.CharField(default=None, max_length=255),
),
migrations.AddField(
model_name="item",
name="second_option_label",
field=models.CharField(default=None, max_length=255),
),
migrations.AddField(
model_name="orderitem",
name="customization",
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name="orderitem",
name="option",
field=models.CharField(default=None, max_length=255),
),
migrations.AddField(
model_name="orderitem",
name="second_option",
field=models.CharField(default=None, max_length=255),
),
]
# Generated by Django 2.2.16 on 2020-11-17 18:36
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("boutique", "0017_auto_20201117_1842"),
]
operations = [
migrations.AddField(
model_name="item",
name="price_contributor_custom",
field=models.DecimalField(decimal_places=2, default=None, max_digits=10),
),
migrations.AddField(
model_name="item",
name="price_custom",
field=models.DecimalField(decimal_places=2, default=None, max_digits=10),
),
]
# Generated by Django 2.2.16 on 2020-11-17 20:56
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("boutique", "0018_auto_20201117_1936"),
]
operations = [
migrations.RemoveField(
model_name="item",
name="price_contributor_custom",
),
migrations.RemoveField(
model_name="item",
name="price_custom",
),
migrations.AlterField(
model_name="orderitem",
name="customization",
field=models.CharField(default=None, max_length=255),
),
]
# Generated by Django 2.2.16 on 2020-11-17 21:31
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("boutique", "0019_auto_20201117_2156"),
]
operations = [
migrations.AlterField(
model_name="item",
name="customization",
field=models.BooleanField(blank=True, default=False),
),
migrations.AlterField(
model_name="item",
name="option",
field=models.CharField(max_length=255),
),
migrations.AlterField(
model_name="orderitem",
name="customization",
field=models.CharField(blank=True, default=None, max_length=255),
),
migrations.AlterField(
model_name="orderitem",
name="option",
field=models.CharField(blank=True, default=None, max_length=255),
),
migrations.AlterField(
model_name="orderitem",
name="second_option",
field=models.CharField(blank=True, default=None, max_length=255),
),
]
# Generated by Django 2.2.16 on 2020-11-17 21:34
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("boutique", "0020_auto_20201117_2231"),
]
operations = [
migrations.AlterField(
model_name="orderitem",
name="customization",
field=models.CharField(blank=True, default=None, max_length=255, null=True),
),
migrations.AlterField(
model_name="orderitem",
name="option",
field=models.CharField(blank=True, default=None, max_length=255, null=True),
),
migrations.AlterField(
model_name="orderitem",
name="second_option",
field=models.CharField(blank=True, default=None, max_length=255, null=True),
),
]
# Generated by Django 2.2.16 on 2020-11-22 19:52
from django.db import migrations
from django.db import models
class Migration(migrations.Migration):
dependencies = [
("boutique", "0021_auto_20201117_2234"),
]
operations = [
migrations.AlterField(
model_name="item",
name="customization",
field=models.BooleanField(default=False),
),
migrations.AlterField(
model_name="item",
name="option",
field=models.CharField(blank=True, default="", max_length=255),
),
migrations.AlterField(
model_name="item",
name="option_label",
field=models.CharField(blank=True, default="", max_length=255),
),
migrations.AlterField(
model_name="item",
name="second_option",
field=models.CharField(blank=True, default="", max_length=255),
),
migrations.AlterField(
model_name="item",
name="second_option_label",
field=models.CharField(blank=True, default="", max_length=255),
),
migrations.AlterField(
model_name="orderitem",
name="customization",
field=models.CharField(blank=True, default="", max_length=255),
),
migrations.AlterField(
model_name="orderitem",
name="option",
field=models.CharField(blank=True, default="", max_length=255),
),
migrations.AlterField(
model_name="orderitem",
name="second_option",
field=models.CharField(blank=True, default="", max_length=255),
),
]
......@@ -53,6 +53,11 @@ class Item(models.Model):
action = models.CharField(max_length=10, default="no", choices=ACTIONS)
children = models.ManyToManyField("Item", related_name="parents", blank=True)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
customization = models.BooleanField(default=False)
option = models.CharField(max_length=255, default="", blank=True)
option_label = models.CharField(max_length=255, default="", blank=True)
second_option = models.CharField(max_length=255, default="", blank=True)
second_option_label = models.CharField(max_length=255, default="", blank=True)
event = models.ForeignKey(
Event, on_delete=models.PROTECT, blank=True, null=True, default=None
......@@ -64,6 +69,14 @@ class Item(models.Model):
("sell", "Can sell items to anybody"),
)
@property
def customizable(self) -> bool:
return (
(self.customization is True)
or (self.option != "")
or (self.second_option != "")
)
@property
def is_pack(self) -> bool:
return self.children.count() > 0
......@@ -125,33 +138,75 @@ class Item(models.Model):
else:
return static("images/default_product.png")
def add_to_order(self, order: "Order", quantity: int = 1) -> "OrderItem":
def add_to_order(
self,
order: "Order",
quantity: int = 1,
customization: str = "",
option: str = "",
second_option: str = "",
) -> "OrderItem":
oi, created = None, False
try:
oi, created = OrderItem.objects.get_or_create(
order=order, item=self, defaults={"quantity": quantity}
if self.customizable:
oi = OrderItem.objects.create(
order=order,
item=self,
quantity=quantity,
customization=customization,
option=option,
second_option=second_option,
)
created = True
else:
try:
oi, created = OrderItem.objects.get_or_create(
order=order,
item=self,
defaults={
"quantity": quantity,
"customization": customization,
"option": option,
"second_option": second_option,
},
)
except MultipleObjectsReturned:
# Find an object that is not in a pack
orderitems = OrderItem.objects.filter(order=order, item=self)
for oi in orderitems:
if not oi.is_pack_item:
break
if (
oi is None or oi.is_pack_item
): # The preceding queries in the try-except block were empty or they
# ended on a pack_item
oi = OrderItem.objects.create(
order=order,
item=self,
quantity=quantity,
customization=customization,
option=option,
second_option=second_option,
)
except MultipleObjectsReturned:
# Find an object that is not in a pack
orderitems = OrderItem.objects.filter(order=order, item=self)
for oi in orderitems:
if not oi.is_pack_item:
break
if oi is None or oi.is_pack_item:
oi = OrderItem.objects.create(order=order, item=self, quantity=quantity)
created = True
if not created:
oi.quantity = F("quantity") + quantity
oi.customization = customization
oi.save()
oi.refresh_from_db()
return oi
def add_to_user(self, user, quantity: int = 1) -> "OrderItem":
def add_to_user(
self,
user,
quantity: int = 1,
customization: str = "",
option: str = "",
second_option: str = "",
) -> "OrderItem":
order = Order.objects.get_current_order(user)
return self.add_to_order(order, quantity)
return self.add_to_order(order, quantity, customization, option, second_option)
def __str__(self) -> str:
return self.name
......@@ -193,7 +248,7 @@ class Order(models.Model):
for orderitem in self.items.all():
orderitem.post_payment()
def save(self, *args, **kwargs,) -> None:
def save(self, *args, **kwargs) -> None:
if self.ordered and self.ordered_date is None:
self.ordered_date = timezone.now()
......@@ -235,6 +290,9 @@ class OrderItem(models.Model):
quantity = models.PositiveIntegerField(validators=[MinValueValidator(1)])
beeing_delivered = models.BooleanField(default=False)
quantity_delivered = models.PositiveIntegerField(default=0)
customization = models.CharField(max_length=255, default="", blank=True)
option = models.CharField(max_length=255, default="", blank=True, null=False)
second_option = models.CharField(max_length=255, default="", blank=True, null=False)
pack_parent = models.ForeignKey(
"self", related_name="pack", on_delete=models.CASCADE, null=True, blank=True
)
......
......@@ -31,8 +31,13 @@ window.addEventListener("load", function (e) {
for (let i = orders.length - 1; i >= 0; i--) {
let order = orders[i];
let li = document.createElement('li');
let content = order.user + ": " + order.quantity;
content = order.paid ? content : content + " Impayé";
let content = order.user + " : " + order.quantity;
console.log(orders)
content = (order.customization === '') ? content : content + ' ; ' + order.customization;
content = (order.option === '') ? content : content + ' ; ' + order.option;
content = (order.second_option === '') ? content : content + ' ; ' + order.customization;
content = order.paid ? content : content + " ; Impayé";
content = (order.quantity_delivered === 0) ? content : content + " ; " + order.quantity_delivered + " livré(s)"
li.appendChild(document.createTextNode(content));
ul.appendChild(li);
}
......
......@@ -19,7 +19,30 @@
<div class="image_container">
<img class="product_img" src="{{ object.get_image_url }}"/>
</div>
<div id="description">
<div></div>
<div id="addtobasket">
<form method="post">
{% csrf_token %}
{% if is_special %}
<span id="special" title = "Ce produit ne peut être commandé qu'une fois">
{{ form.as_p }}
</span>
{% else %}
{{ form.as_p }}
{% endif %}
{% if already_ordered and is_special %}
<input type="submit" value="Ajouter au panier" title="Vous avez déjà commandé ce produit !" disabled="disabled" />
{% else %}
<input type="submit" value="Ajouter au panier" class="button" />
{% endif %}
</form>
</div>
</div>
<div id="description">
<h2>
{% if object.price == object.price_contributor or not is_contributor %}
......@@ -39,27 +62,27 @@
{{ object.description|markdown }}
<hr/>
<p> La vente se termine le {{ object.end_date }}</p>
<p> Catégorie : {{ object.category }}</p>
{% if object.event %}