Commit 29515baf authored by HEVELINE Thomas's avatar HEVELINE Thomas Committed by HEVELINE Thomas

(44): delivery popup

parent d4a491da
......@@ -72,9 +72,9 @@ class Item(models.Model):
@property
def customizable(self) -> bool:
return (
(self.customization is True)
or (self.option != "")
or (self.second_option != "")
(self.customization is True)
or (self.option != "")
or (self.second_option != "")
)
@property
......@@ -159,12 +159,12 @@ class Item(models.Model):
return static("images/default_product.png")
def add_to_order(
self,
order: "Order",
quantity: int = 1,
customization: str = "",
option: str = "",
second_option: str = "",
self,
order: "Order",
quantity: int = 1,
customization: str = "",
option: str = "",
second_option: str = "",
) -> "OrderItem":
oi, created = None, False
if self.customizable:
......@@ -196,7 +196,7 @@ class Item(models.Model):
if not oi.is_pack_item:
break
if (
oi is None or oi.is_pack_item
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(
......@@ -218,12 +218,12 @@ class Item(models.Model):
return oi
def add_to_user(
self,
user,
quantity: int = 1,
customization: str = "",
option: str = "",
second_option: str = "",
self,
user,
quantity: int = 1,
customization: str = "",
option: str = "",
second_option: str = "",
) -> "OrderItem":
if self.hidden or self.end_date < timezone.now():
raise ValidationError(
......@@ -262,6 +262,13 @@ class Order(models.Model):
except Payment.DoesNotExist:
return False
@property
def mean(self) -> str:
try:
return self.payment.mean
except Payment.DoesNotExist:
return None
@property
def contains_cotiz(self) -> bool:
return any(i.item.is_cotiz for i in self.items.all())
......@@ -315,10 +322,10 @@ class OrderItemManager(models.Manager):
def get_ordered_quantity(self, item: "Item", user) -> int:
"""Get the total quantity ever ordered/in order by that user"""
return (
self.filter(item=item, order__user=user, order__rejected=False).aggregate(
quantity=Sum("quantity")
)["quantity"]
or 0
self.filter(item=item, order__user=user, order__rejected=False).aggregate(
quantity=Sum("quantity")
)["quantity"]
or 0
)
......@@ -446,7 +453,7 @@ class OrderItem(models.Model):
)
def delete(
self, *args, override_pack=False, **kwargs
self, *args, override_pack=False, **kwargs
) -> Tuple[int, Dict[str, int]]:
deleted = 0
which: typing.Counter[str] = Counter()
......@@ -476,7 +483,7 @@ class OrderItem(models.Model):
@receiver(pre_save, sender=OrderItem)
@receiver(pre_delete, sender=OrderItem)
def orderitem_price_computing(
sender: Type[OrderItem], instance: OrderItem, **kwargs
sender: Type[OrderItem], instance: OrderItem, **kwargs
) -> None:
if kwargs.get("raw", False):
return
......@@ -488,9 +495,9 @@ def orderitem_price_computing(
@receiver(pre_delete, sender=OrderItem)
@receiver(pre_delete, sender=Order)
def no_delete_for_ordered(
sender: Union[Type[Order], Type[OrderItem]],
instance: Union[Order, OrderItem],
**kwargs,
sender: Union[Type[Order], Type[OrderItem]],
instance: Union[Order, OrderItem],
**kwargs,
) -> None:
if instance.ordered:
raise ValueError("Deletion of ordered instances is not allowed")
......@@ -498,7 +505,7 @@ def no_delete_for_ordered(
@receiver(pre_save, sender=lydiaRequest)
def mark_payment_as_paid(
sender: Type[lydiaRequest], instance: lydiaRequest, **kwargs
sender: Type[lydiaRequest], instance: lydiaRequest, **kwargs
) -> None:
if kwargs.get("raw", False):
return
......
......@@ -24,41 +24,97 @@
}
</script>
<form>
<form onchange="generateTable()">
<label for="delivered">Déjà remis</label>
<input type="checkbox" id="delivered">
<label for="delivery_in_progress">Distribution en cours</label>
<input type="checkbox" id="delivery_in_progress">
<select id="delivered"
onchange="generateTable()">
<option value="both">Tous</option>
<option value="true">Oui</option>
<option value="false">Non</option>
</select>
<label for="beeing_delivered">Distribution en cours</label>
<select id="beeing_delivered"
onchange="generateTable()">
<option value="true">Oui</option>
<option value="false">Non</option>
<option value="both">Tous</option>
</select>
<label for="hidden">Produits cachés</label>
<select id="hidden"
onchange="generateTable()">
<option value="true">Oui</option>
<option value="false">Non</option>
<option value="both">Tous</option>
</select>
<label for="paid">Payé</label>
<select id="paid"
onchange="generateTable()">
<option value="true">Oui</option>
<option value="false">Non</option>
<option value="both">Tous</option>
</select>
<label for="sort">Tri</label>
<select id="sort">
<option value="true"> --</option>
<option value="false">Personalisation</option>
<option value="both">Acheteur</option>
<option value="both">Date de commande</option>
<option value="both">Option 1</option>
<option value="both">Option 2</option>
</select>
</form>
<button onclick="applyFilter()">Appliquer</button>
<form onblur="generateTable()"
onkeypress="onEnter(event)">
<input placeholder="Email"
type="search"
id="emailContains">
<input placeholder="Produit"
type="search"
id="productContains">
<input placeholder="Option (valeur exacte)"
type="search"
id="optionContains">
<input placeholder="Personalisation"
type="search"
id="customizationContains">
</form>
<div id="deliveries"></div>
<script>
window.addEventListener('load', function () {
window.addEventListener('load', generateTable);
function onEnter(event) {
if (event.keyCode === 13) {
blur(event.target)
generateTable()
}
}
function generateTable() {
var params = new URLSearchParams();
params.append('delivered', document.getElementById('delivered').checked);
params.append('delivery_in_progress', document.getElementById('delivery_in_progress').checked);
var orderedItemList = new OrderedItemList('deliveries', '/boutique/ordered_items?'+params.toString(), function() {
function sendMail() {
console.log(1)
};
function viewProfile() {
console.log(2)
};
return [
new OrderedItemList.ItemAction('Remettre', sendMail),
];
});
});
params.set('delivered', document.getElementById('delivered').value);
params.set('beeing_delivered', document.getElementById('beeing_delivered').value);
params.set('hidden', document.getElementById('hidden').value);
params.set('paid', document.getElementById('paid').value);
params.set('customizationContains', document.getElementById('customizationContains').value);
params.set('optionContains', document.getElementById('optionContains').value);
params.set('productContains', document.getElementById('productContains').value);
params.set('emailContains', document.getElementById('emailContains').value);
var orderedItemList = new OrderedItemList('deliveries', '/boutique/delivery?' + params.toString());
}
</script>
{% endblock %}
{% block scripts %}
<script src="{% static 'boutique/js/deliver.js' %}"></script>
<script src="{% static 'js/json_request.js' %}"></script>
<script src="{% static 'js/table_list.js' %}"></script>
<script src="{% static 'js/ordered_items.js' %}"></script>
<script src="{% static 'js/popup.js' %}"></script>
{% endblock %}
......@@ -3,7 +3,6 @@
{% load static %}
{% block styles %}
<link rel="stylesheet" href="{% static 'boutique/css/item_manage.css' %}"/>
{% endblock %}
{% block header %}
......
......@@ -49,7 +49,5 @@ urlpatterns = [
),
),
path("delivery", views.DeliveryView.as_view(), name="delivery"),
path("ordered_items", views.orderedItems, name="ordered_items"),
]
This diff is collapsed.
......@@ -26,9 +26,9 @@ SECRET_KEY = "&d3ykoj75pkdv_q^4%ens@047+qi^_^379rg#!o%zg1j=pmwi&"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
INTERNAL_IPS = ["127.0.0.1"]
INTERNAL_IPS = ["192.168.0.181"]
ALLOWED_HOSTS: List[str] = []
ALLOWED_HOSTS: List[str] = ["192.168.0.181"]
# Application definition
......@@ -101,8 +101,8 @@ DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "sde",
"USER": "root",
"PASSWORD": "",
"USER": "fenwick",
"PASSWORD": "fenwick",
"HOST": "127.0.0.1",
"PORT": 3306,
}
......
This diff is collapsed.
This diff is collapsed.
......@@ -2,20 +2,23 @@
(function () {
var OrderedItemList = function (containerId, listProvider, buildCallback) {
TableList.call(this, containerId, buildCallback);
var OrderedItemList = function (containerId, listProvider) {
TableList.call(this, containerId);
queryJson(listProvider, {}, this.populate.bind(this));
};
OrderedItemList.prototype = Object.create(TableList.prototype, {
populate: {
value: function (json) {
this.searchInput.setAttribute('placeholder', 'Acheteur')
this.elems = json['orderedItems']
var header = document.createElement('tr');
header.appendChild(document.createElement('th'));
header.appendChild(document.createElement('th')).appendChild(document.createTextNode('Produit'));
header.appendChild(document.createElement('th')).appendChild(document.createTextNode('Client'));
header.appendChild(document.createElement('th')).appendChild(document.createTextNode('Acheteur'));
header.appendChild(document.createElement('th')).appendChild(document.createTextNode('Personalisation'));
header.appendChild(document.createElement('th')).appendChild(document.createTextNode('Payement'));
header.appendChild(document.createElement('th')).appendChild(document.createTextNode('Remis'));
header.appendChild(document.createElement('th'));
this.header.appendChild(header);
......@@ -26,17 +29,18 @@
var pictureContainer = document.createElement('div');
pictureContainer.setAttribute('class', 'picture_container');
pictureContainer.setAttribute('style', 'background-color: ' + item['color']);
pictureContainer.appendChild(document.createElement('img'))
.setAttribute('src', '/medias/' + item['image']);
var actionContainer = document.createElement('div');
actionContainer.setAttribute('class', 'action_container');
var customization = document.createElement('td');
let customization = document.createElement('td');
if (item['customization'] !== '') customization.appendChild(document.createElement('div'))
.appendChild(document.createTextNode(item['customization']));
.appendChild(document.createTextNode('Personalisation : ' + item['customization']));
if (item['option_label'] !== '') customization.appendChild(document.createElement('div'))
.appendChild(document.createTextNode(item['option_label'] + ' : ' + item['option']));
if (item['seccon_option_label'] !== '') customization.appendChild(document.createElement('div'))
.appendChild(document.createTextNode( item['second_option_label'] + ' : ' + item['second_option']));
if (item['second_option_label'] !== '') customization.appendChild(document.createElement('div'))
.appendChild(document.createTextNode(item['second_option_label'] + ' : ' + item['second_option']));
if (this.onElemBuild) {
......@@ -45,17 +49,57 @@
actionContainer.appendChild(actions[i].element);
}
}
let button = document.createElement('button');
button.addEventListener('click', deliver);
button.disabled= !item['paid'];
if(item['quantity_delivered'] >= item['quantity']) {
button.innerHTML = 'Reprendre';
button.setAttribute('class', 'red_button');
}
else{
button.innerHTML = 'Remettre';
}
actionContainer.appendChild(button);
let payement = document.createElement('td');
if (!item['paid']) {
payement.innerHTML = 'Non payé';
payement.setAttribute('style', 'color: red');
} else {
const mean = {"card": "Carte", "online": "Lydia", "cash": "Espèces", "check": "Chèque"};
const date = new Date(item['ordered_date']);
function pad(s) {
return (s < 10) ? '0' + s : s;
}
payement.innerHTML = (mean[item['mean']] ? mean[item['mean']] : item['mean'])
+ '<br>'
+ [pad(date.getDate()), pad(date.getMonth() + 1), date.getFullYear()].join('/');
}
let buyer = document.createElement('td');
buyer.innerHTML = (item['display_name'] === item['email'] ? item['display_name'] : item['display_name'] + '<br>' + item['email'])
item.element = document.createElement('tr');
pictureContainer.appendChild(document.createElement('td')).appendChild(document.createElement('img'))
.setAttribute('src', '/medias/' + item['image']);
item.element.appendChild(pictureContainer);
item.element.appendChild(document.createElement('td')).appendChild(document.createTextNode(item['item']));
item.element.appendChild(document.createElement('td')).appendChild(document.createTextNode(item['display_name']));
item.element.appendChild(document.createElement('td')).appendChild(customization);
item.element.appendChild(document.createElement('td')).appendChild(document.createTextNode(item['quantity_delivered'] + ' / ' + item['quantity']));
item.element.setAttribute('data-id', item['id']);
item.element.setAttribute('data-item', item['item']);
item.element.setAttribute('data-quantity_ordered', item['quantity']);
item.element.setAttribute('data-quantity_delivered', item['quantity_delivered']);
item.element.setAttribute('data-quantity_delivered', item['quantity_delivered']);
item.element.setAttribute('data-display_name', item['display_name']);
item.element.setAttribute('data-paid', item['paid']);
item.element.appendChild(document.createElement('td')).appendChild(pictureContainer);
item.element.appendChild(document.createElement('td')).innerHTML = item['item'];
item.element.appendChild(buyer);
item.element.appendChild(customization);
item.element.appendChild(payement);
item.element.appendChild(document.createElement('td')).innerHTML = item['quantity_delivered'] + ' / ' + item['quantity'];
item.element.appendChild(document.createElement('td')).appendChild(actionContainer);
this.body.appendChild(item.element);
}
......@@ -87,3 +131,29 @@
window.OrderedItemList.ItemAction = Action;
})();
function deliver(event) {
let tr = event.target.closest('tr')
let item = {
"id": tr.dataset.id,
"item": tr.dataset.item,
"quantity_ordered": tr.dataset.quantity_ordered,
"quantity_delivered": tr.dataset.quantity_delivered,
"display_name": tr.dataset.display_name
}
let deliverPopup = new DeliverPopup(item, function (id, quantity) {
queryJson(document.location, {
"message": "deliver",
"id": id,
"quantity": parseInt(quantity)
}, function (data) {
add_message(data.status, data.message);
if (data.code === 200) {
generateTable();
}
}, "POST");
})
deliverPopup.pop();
}
\ No newline at end of file
......@@ -89,6 +89,78 @@ SelectionPopup.prototype = Object.create(Popup.prototype, {});
SelectionPopup.prototype.constructor = SelectionPopup;
/*
* Selection popup
*
* Open a pupop with the given choices and call the callback with the selected
* one as it's first argument. choises is an array with a key as the choice
* name and the value as the choice displayed
*/
function DeliverPopup(item, callback) {
Popup.call(this, 'Remettre un article');
this.baseClass = 'selection_popup';
this.callback = callback;
let max = parseInt(item['quantity_ordered']) - parseInt(item["quantity_delivered"]);
let body = document.createElement("div")
body.innerHTML =
"<h4> Article : <i>" + item['item'] + "</i><br> Acheteur : <i>" + item["display_name"] + " </i></h4>" +
"<span> Quantité commandée : " + item["quantity_ordered"] +
"<br>Déjà remis : " + item["quantity_delivered"] +
"<br>Reste à remettre : " + max +
"<br><br></span>" +
"<label for='quantity_to_deliver'>Quantité à remettre :</label> "
let form = document.createElement('form')
let quantityInput = document.createElement('input')
quantityInput.setAttribute('id', 'quantity_to_deliver')
quantityInput.setAttribute('type', 'number');
quantityInput.setAttribute('max', max);
quantityInput.value = max;
quantityInput.setAttribute('min', parseInt(-item['quantity_delivered']));
quantityInput.setAttribute('step', 1);
quantityInput.setAttribute('style', 'font-size: larger');
quantityInput.addEventListener('change', is_valid)
quantityInput = body.appendChild(quantityInput);
this.main.appendChild(body);
let button = document.createElement('button');
button.setAttribute('type', 'button');
let warning = document.createElement('h4');
warning.innerHTML='Quantité négative : vous reprenez l\'article'
warning.setAttribute('style', 'color: red');
this.main.appendChild(warning);
this.main.appendChild(button);
is_valid();
function is_valid() {
let quantity = quantityInput.value;
button.disabled = (parseInt(quantity) === 0 |
quantity > item['quantity_ordered'] - item['quantity_delivered'] |
-quantity > item['quantity_delivered']);
quantityInput.value < 0 ? button.innerHTML= 'Reprendre' : button.innerHTML = 'Remettre';
quantityInput.value < 0 ? warning.hidden= false: warning.hidden= true;
}
button.addEventListener('click', function (event) {
this.callback(item['id'], quantityInput.value);
this.close();
}.bind(this));
}
DeliverPopup.prototype = Object.create(Popup.prototype, {});
DeliverPopup.prototype.constructor = DeliverPopup;
/*
* Customization popup
*
......
......@@ -46,6 +46,7 @@ var Action = function(name, callback, toggled){
var TableList = function(containerId, buildCallback){
this.element = document.getElementById(containerId);
this.element.innerHTML='';
this.table = document.createElement('table');
this.body = document.createElement('tbody');
this.header = document.createElement('thead');
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment