Fix inline product forms POST, Add limits to default page, add all orders menu entry and GET option, fix imported modules

This commit is contained in:
Argiris Deligiannidis 2023-08-09 21:01:34 +00:00
parent cd206988ac
commit 7cb48152a0
13 changed files with 458 additions and 101 deletions

View File

@ -1,5 +1,5 @@
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout, Field, Fieldset, Div, HTML, ButtonHolder, Submit
from crispy_forms.layout import Layout, Field, Fieldset, Div, Row, HTML, ButtonHolder, Submit
from django import forms
from django.urls import reverse_lazy
from django.forms.models import inlineformset_factory
@ -8,6 +8,11 @@ from django_addanother.widgets import AddAnotherWidgetWrapper
from orders_app.custom_layout_object import Formset
from orders_app.models import Order, OrderProduct, Customer, Product, Store
from .models import *
from .custom_layout_object import Formset
import re
class CustomerForm(forms.ModelForm):
class Meta:
@ -78,6 +83,7 @@ class StoreForm(forms.ModelForm):
class OrderLine(forms.ModelForm):
class Meta:
model = OrderProduct
exclude = ()
fields = ['id', 'order', 'product', 'amount', 'cake_type', 'cake_type_num', 'cake_color', 'cake_color_other', 'fyt_color', 'fyt_color_other', 'cake_flavor', 'cake_img', 'cream_cake_3d', 'cream_cake_height', 'cream_cake_img', 'engagement_cake_type', 'engagement_cake_base', 'engagement_cake_pcs', 'engagement_cake_pcs_other', 'engagement_cake_glaze', 'cup_flavor', 'cup_color', 'cup_color_other', 'cup_type', 'candy_bar_type', 'candy_bar_decor', 'candy_bar_decor_other', 'candy_bar_wrap', 'info']
widgets = {
'product': AddAnotherWidgetWrapper(
@ -92,9 +98,13 @@ class OrderLine(forms.ModelForm):
'info': forms.Textarea(attrs={'rows': 2, 'cols': 30}),
}
def __init__(self, *arg, **kwarg):
super(OrderLine, self).__init__(*arg, **kwarg)
self.empty_permitted = False
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
formtag_prefix = re.sub('-[0-9]+$', '', kwargs.get('prefix', ''))
self.helper = FormHelper()
self.helper.form_tag = False
self.fields['product'].label = "Προϊόν"
self.fields['amount'].label = "Ποσότητα"
self.fields['cake_type'].label = "Τύπος"
@ -122,6 +132,40 @@ class OrderLine(forms.ModelForm):
self.fields['candy_bar_decor_other'].label = "Ντεκόρ CandyBar Άλλο"
self.fields['candy_bar_wrap'].label = "Τύλιγμα CandyBar"
self.fields['info'].label = "Πληροφορίες"
self.helper.layout = Layout(
Row(
Field('product'),
Field('amount'),
Field('cake_type'),
Field('cake_type_num'),
Field('cake_color'),
Field('cake_color_other'),
Field('fyt_color'),
Field('fyt_color_other'),
Field('cake_flavor'),
Field('cake_img'),
Field('cream_cake_3d'),
Field('cream_cake_height'),
Field('cream_cake_img'),
Field('engagement_cake_type'),
Field('engagement_cake_base'),
Field('engagement_cake_pcs'),
Field('engagement_cake_pcs_other'),
Field('engagement_cake_glaze'),
Field('cup_flavor'),
Field('cup_color'),
Field('cup_color_other'),
Field('cup_type'),
Field('candy_bar_type'),
Field('candy_bar_decor'),
Field('candy_bar_decor_other'),
Field('candy_bar_wrap'),
Field('info'),
Field('DELETE'),
css_class='formset_row-{}'.format(formtag_prefix)
)
)
OrderLineFormSet = inlineformset_factory(
@ -138,6 +182,7 @@ OrderLineFormSetEdit = inlineformset_factory(
class OrderForm(forms.ModelForm):
class Meta:
model = Order
exclude = ()
fields = ['order_status', 'customer_name', 'customer_address', 'customer_telephone', 'customer_email', 'delivery', 'delivery_date', 'store', 'order_info', 'order_products']
widgets = {
'delivery_date': forms.DateInput(attrs={'type': 'text', 'id': 'delivery_date', 'class': 'datepicker'}),
@ -153,7 +198,7 @@ class OrderForm(forms.ModelForm):
super(OrderForm, self).__init__(*args, **kwargs)
self.helper = FormHelper()
self.helper.form_tag = True
self.helper.render_hidden_fields = True
#self.helper.render_hidden_fields = True
self.helper.form_class = 'form-horizontal'
self.helper.label_class = 'col-md-3 create-label'
self.helper.field_class = 'col-md-9'

View File

@ -3,7 +3,6 @@ from django.core.validators import MinValueValidator, MaxValueValidator
from django.db import models
from phonenumber_field.modelfields import PhoneNumberField
class Store(models.Model):
name = models.CharField(max_length=128)
address = models.CharField(max_length=128)
@ -190,7 +189,7 @@ class OrderProduct(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
amount = models.FloatField(validators=[MinValueValidator(0.01), MaxValueValidator(999)])
#az = 'ΚΙΛΑ ΓΕΥΣΗ KARDASIS Νο ΧΡΩΜΑ ΦΥΤΙΛΑΚΙ ΠΑΡΑΤΗΡΗΣΕΙΣ'
#vars = 'ΚΙΛΑ ΓΕΥΣΗ KARDASIS Νο ΧΡΩΜΑ ΦΥΤΙΛΑΚΙ ΠΑΡΑΤΗΡΗΣΕΙΣ'
cake_type = models.CharField(max_length=45, choices=CAKE_TYPES, blank=True, null=True)
cake_type_num = models.FloatField(max_length=128, default="0", blank=True, null=True)
cake_color = models.CharField(max_length=45, choices=COLOR_OPTIONS, blank=True, null=True)
@ -199,19 +198,19 @@ class OrderProduct(models.Model):
fyt_color_other = models.CharField(max_length=128, blank=True, null=True)
cake_flavor = models.CharField(max_length=45, choices=CAKE_FLAVORS, blank=True, null=True)
cake_img = models.ImageField(blank=True, null=True)
#az = 'ΜΕΓΕΘΟΣ ΥΨΟΣ ΓΕΥΣΗ ΠΑΡΑΤΗΡΗΣΕΙΣ'
#vars = 'ΜΕΓΕΘΟΣ ΥΨΟΣ ΓΕΥΣΗ ΠΑΡΑΤΗΡΗΣΕΙΣ'
cream_cake_3d = models.CharField(max_length=45, choices=CREAM_3D, default="ΟΧΙ", blank=True)
cream_cake_height = models.FloatField(max_length=128, default="0", blank=True, null=True)
cream_cake_img = models.ImageField(blank=True, null=True)
#az = 'ΓΑΜΟΣ ΒΑΣΗ ΤΕΜΑΧΙΑ ΓΕΥΣΗ ΠΑΡΑΤΗΡΗΣΕΙΣ'
#vars = 'ΓΑΜΟΣ ΒΑΣΗ ΤΕΜΑΧΙΑ ΓΕΥΣΗ ΠΑΡΑΤΗΡΗΣΕΙΣ'
engagement_cake_type = models.CharField(max_length=45, choices=ENGAMENT_TYPE, blank=True, null=True)
engagement_cake_base = models.CharField(max_length=128, blank=True, null=True)
engagement_cake_pcs = models.CharField(max_length=45, choices=ENGAMENT_CAKE_PIECES, blank=True, null=True)
engagement_cake_pcs_other = models.CharField(max_length=128, blank=True, null=True)
engagement_cake_glaze = models.CharField(max_length=45, choices=ENGAMENT_CAKE_GLAZE, blank=True, null=True)
#az = 'ΤΕΜΑΧΙΑ ΓΕΥΣΗ ΚΥΠΕΛΛΟ ΧΡΩΜΑ ΤΕΜΑΧΙΑ ΧΡΩΜΑ ΔΙΑΚΟΣΜΗΣΗ ΤΥΛΙΓΜΕΝΑ ΠΑΡΑΤΗΡΗΣΕΙΣ'
#vars = 'ΤΕΜΑΧΙΑ ΓΕΥΣΗ ΚΥΠΕΛΛΟ ΧΡΩΜΑ ΤΕΜΑΧΙΑ ΧΡΩΜΑ ΔΙΑΚΟΣΜΗΣΗ ΤΥΛΙΓΜΕΝΑ ΠΑΡΑΤΗΡΗΣΕΙΣ'
cup_flavor = models.CharField(max_length=45, choices=CUP_FLAVORS, blank=True, null=True)
cup_color = models.CharField(max_length=45, choices=COLOR_OPTIONS, blank=True, null=True)
cup_color_other = models.CharField(max_length=128, blank=True, null=True)

View File

@ -7,6 +7,9 @@ sp1!glk2
spiti3
sp4$glku3
spiti4
sp5%glku4
pronorth
pro1!north123!@#

View File

@ -15,6 +15,10 @@ from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
from reportlab.pdfgen import canvas
from textwrap import wrap
from .models import *
from .forms import *
from django.views.generic.edit import CreateView, UpdateView
from django.db import transaction
from orders_app.forms import OrderForm, OrderLineFormSet, CustomerForm, ProductForm, StoreForm,\
@ -270,14 +274,36 @@ class DashboardPageView(LoginRequiredMixin, TemplateView):
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
time_delta = datetime.today() - timedelta(days=30)
time_delta = datetime.today() - timedelta(days=90)
try:
all_orders = self.request.GET['all_orders']
except KeyError:
all_orders = False
if self.request.user.id == 3:
context["DB_Objects"] = Order.objects.filter(store=1).filter(order_date__gte=time_delta).order_by('id').reverse()
if all_orders:
context["DB_Objects"] = Order.objects.filter(store_id=3).order_by('id').reverse()
else:
context["DB_Objects"] = Order.objects.filter(store_id=3).filter(order_date__gte=time_delta).order_by('id').reverse()
elif self.request.user.id == 4:
context["DB_Objects"] = Order.objects.filter(store=2).filter(order_date__gte=time_delta).order_by('id').reverse()
if all_orders:
context["DB_Objects"] = Order.objects.filter(store_id=4).order_by('id').reverse()
else:
context["DB_Objects"] = Order.objects.filter(store_id=4).filter(order_date__gte=time_delta).order_by('id').reverse()
elif self.request.user.id == 5:
context["DB_Objects"] = Order.objects.filter(store=3).filter(order_date__gte=time_delta).order_by('id').reverse()
if all_orders:
context["DB_Objects"] = Order.objects.filter(store_id=5).order_by('id').reverse()
else:
context["DB_Objects"] = Order.objects.filter(store_id=5).filter(order_date__gte=time_delta).order_by('id').reverse()
elif self.request.user.id == 6:
if all_orders:
context["DB_Objects"] = Order.objects.filter(store_id=6).order_by('id').reverse()
else:
context["DB_Objects"] = Order.objects.filter(store_id=6).filter(order_date__gte=time_delta).order_by('id').reverse()
elif self.request.user.id == 7:
if all_orders:
context["DB_Objects"] = Order.objects.filter(store_id=7).order_by('id').reverse()
else:
context["DB_Objects"] = Order.objects.filter(store_id=7).filter(order_date__gte=time_delta).order_by('id').reverse()
else:
context["DB_Objects"] = Order.objects.filter(order_date__gte=time_delta).order_by('id').reverse()
context["active_page"] = 'dashboard'
@ -297,24 +323,32 @@ class ProductPageView(LoginRequiredMixin, TemplateView):
class OrderProductsPageView(LoginRequiredMixin, TemplateView):
template_name = "diaxeirisi/Dashboard.OrderProducts.html"
time_delta = datetime.today() - timedelta(days=30)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
print(self.request.user.id)
if self.request.user.id == 3:
order_ids = Order.objects.filter(store=1).filter(order_date__gte=time_delta).order_by('id').reverse()
order_ids = Order.objects.filter(store_id=3).order_by('-id')[:200]
order_ids = list(answer.id for answer in order_ids)
context["DB_Objects"] = OrderProduct.objects.filter(order_id__in=order_ids)
elif self.request.user.id == 4:
order_ids = Order.objects.filter(store=2).filter(order_date__gte=time_delta).order_by('id').reverse()
order_ids = Order.objects.filter(store_id=4).order_by('-id')[:200]
order_ids = list(answer.id for answer in order_ids)
context["DB_Objects"] = OrderProduct.objects.filter(order_id__in=order_ids)
elif self.request.user.id == 5:
order_ids = Order.objects.filter(store=3).filter(order_date__gte=time_delta).order_by('id').reverse()
order_ids = Order.objects.filter(store_id=5).order_by('-id')[:200]
order_ids = list(answer.id for answer in order_ids)
context["DB_Objects"] = OrderProduct.objects.filter(order_id__in=order_ids)
elif self.request.user.id == 6:
order_ids = Order.objects.filter(store_id=6).order_by('-id')[:200]
order_ids = list(answer.id for answer in order_ids)
context["DB_Objects"] = OrderProduct.objects.filter(order_id__in=order_ids)
elif self.request.user.id == 7:
order_ids = Order.objects.filter(store_id=7).order_by('-id')[:200]
order_ids = list(answer.id for answer in order_ids)
context["DB_Objects"] = OrderProduct.objects.filter(order_id__in=order_ids)
else:
context["DB_Objects"] = OrderProduct.objects.all().filter(order_date__gte=time_delta).order_by('id').reverse()
context["DB_Objects"] = OrderProduct.objects.all().order_by('-id')[:200]
context["active_page"] = 'products'
return context
@ -449,6 +483,7 @@ class OrderUpdate(UpdateView):
form_class = OrderForm
template_name = 'orders/order_create.html'
def get_success_url(self):
return reverse_lazy('orders_app:order_update', kwargs={'pk': self.object.pk})
@ -458,25 +493,27 @@ class OrderUpdate(UpdateView):
def get_order_id(self):
return self.kwargs['pk']
def get_context_data(self, **kwargs):
context = super(OrderUpdate, self).get_context_data(**kwargs)
def get_context_data(self, *args, **kwargs):
data = super(OrderUpdate, self).get_context_data(**kwargs)
if self.request.POST:
context['order_products'] = OrderLineFormSetEdit(self.request.POST, self.request.FILES, instance=self.object)
data['order_products'] = OrderLineFormSetEdit(self.request.POST, instance=self.object)
else:
context['order_products'] = OrderLineFormSetEdit(instance=self.object)
return context
data['order_products'] = OrderLineFormSetEdit(instance=self.object)
return data
def post(self, request, *args, **kwargs):
order_data = Order.objects.get(id=self.get_order_id())
#order_line_data = OrderProduct.objects.filter(order=self.get_order_id())
form = OrderForm(self.request.POST, self.request.FILES, instance=order_data) #, initial={model_to_dict(order_data)}
order_products = OrderLineFormSetEdit(self.request.POST, self.request.FILES, instance=form.instance)
if form.is_valid() and order_products.is_valid():
form.save()
for inline_form in order_products:
if not inline_form.cleaned_data['DELETE']:
inline_form.save()
messages.success(self.request, "Η παραγγελία αποθηκευτηκέ")
return HttpResponseRedirect(request.META['HTTP_REFERER'])
else:

View File

@ -0,0 +1,248 @@
/**
* jQuery Formset 1.5-pre
* @author Stanislaus Madueke (stan DOT madueke AT gmail DOT com)
* @requires jQuery 1.2.6 or later
*
* Copyright (c) 2009, Stanislaus Madueke
* All rights reserved.
*
* Licensed under the New BSD License
* See: http://www.opensource.org/licenses/bsd-license.php
*/
;(function($) {
$.fn.formset = function(opts)
{
var options = $.extend({}, $.fn.formset.defaults, opts),
flatExtraClasses = options.extraClasses.join(' '),
totalForms = $('#id_' + options.prefix + '-TOTAL_FORMS'),
maxForms = $('#id_' + options.prefix + '-MAX_NUM_FORMS'),
minForms = $('#id_' + options.prefix + '-MIN_NUM_FORMS'),
childElementSelector = 'input,select,textarea,label,div',
$$ = $(this),
applyExtraClasses = function(row, ndx) {
if (options.extraClasses) {
row.removeClass(flatExtraClasses);
row.addClass(options.extraClasses[ndx % options.extraClasses.length]);
}
},
updateElementIndex = function(elem, prefix, ndx) {
var idRegex = new RegExp(prefix + '-(\\d+|__prefix__)-'),
replacement = prefix + '-' + ndx + '-';
if (elem.attr("for")) elem.attr("for", elem.attr("for").replace(idRegex, replacement));
if (elem.attr('id')) elem.attr('id', elem.attr('id').replace(idRegex, replacement));
if (elem.attr('name')) elem.attr('name', elem.attr('name').replace(idRegex, replacement));
},
hasChildElements = function(row) {
return row.find(childElementSelector).length > 0;
},
showAddButton = function() {
return maxForms.length == 0 || // For Django versions pre 1.2
(maxForms.val() == '' || (maxForms.val() - totalForms.val() > 0));
},
/**
* Indicates whether delete link(s) can be displayed - when total forms > min forms
*/
showDeleteLinks = function() {
return minForms.length == 0 || // For Django versions pre 1.7
(minForms.val() == '' || (totalForms.val() - minForms.val() > 0));
},
insertDeleteLink = function(row) {
var delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.'),
addCssSelector = $.trim(options.addCssClass).replace(/\s+/g, '.');
var delButtonHTML = '<a class="' + options.deleteCssClass + '" href="javascript:void(0);">' + options.deleteText +'</a>';
if (options.deleteContainerClass) {
// If we have a specific container for the remove button,
// place it as the last child of that container:
row.find('[class*="' + options.deleteContainerClass + '"]').append(delButtonHTML);
} else if (row.is('TR')) {
// If the forms are laid out in table rows, insert
// the remove button into the last table cell:
row.children(':last').append(delButtonHTML);
} else if (row.is('UL') || row.is('OL')) {
// If they're laid out as an ordered/unordered list,
// insert an <li> after the last list item:
row.append('<li>' + delButtonHTML + '</li>');
} else {
// Otherwise, just insert the remove button as the
// last child element of the form's container:
row.append(delButtonHTML);
}
// Check if we're under the minimum number of forms - not to display delete link at rendering
if (!showDeleteLinks()){
row.find('a.' + delCssSelector).hide();
}
row.find('a.' + delCssSelector).click(function() {
var row = $(this).parents('.' + options.formCssClass),
del = row.find('input:hidden[id $= "-DELETE"]'),
buttonRow = row.siblings("a." + addCssSelector + ', .' + options.formCssClass + '-add'),
forms;
if (del.length) {
// We're dealing with an inline formset.
// Rather than remove this form from the DOM, we'll mark it as deleted
// and hide it, then let Django handle the deleting:
del.val('on');
row.hide();
forms = $('.' + options.formCssClass).not(':hidden');
totalForms.val(forms.length);
} else {
row.remove();
// Update the TOTAL_FORMS count:
forms = $('.' + options.formCssClass).not('.formset-custom-template');
totalForms.val(forms.length);
}
for (var i=0, formCount=forms.length; i<formCount; i++) {
// Apply `extraClasses` to form rows so they're nicely alternating:
applyExtraClasses(forms.eq(i), i);
if (!del.length) {
// Also update names and IDs for all child controls (if this isn't
// a delete-able inline formset) so they remain in sequence:
forms.eq(i).find(childElementSelector).each(function() {
updateElementIndex($(this), options.prefix, i);
});
}
}
// Check if we've reached the minimum number of forms - hide all delete link(s)
if (!showDeleteLinks()){
$('a.' + delCssSelector).each(function(){$(this).hide();});
}
// Check if we need to show the add button:
if (buttonRow.is(':hidden') && showAddButton()) buttonRow.show();
// If a post-delete callback was provided, call it with the deleted form:
if (options.removed) options.removed(row);
return false;
});
};
$$.each(function(i) {
var row = $(this),
del = row.find('input:checkbox[id $= "-DELETE"]');
if (del.length) {
// If you specify "can_delete = True" when creating an inline formset,
// Django adds a checkbox to each form in the formset.
// Replace the default checkbox with a hidden field:
if (del.is(':checked')) {
// If an inline formset containing deleted forms fails validation, make sure
// we keep the forms hidden (thanks for the bug report and suggested fix Mike)
del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" value="on" />');
row.hide();
} else {
del.before('<input type="hidden" name="' + del.attr('name') +'" id="' + del.attr('id') +'" />');
}
// Hide any labels associated with the DELETE checkbox:
$('label[for="' + del.attr('id') + '"]').hide();
del.remove();
}
if (hasChildElements(row)) {
row.addClass(options.formCssClass);
insertDeleteLink(row);
applyExtraClasses(row, i);
}
});
if ($$.length) {
var hideAddButton = !showAddButton(),
addButton, template;
if (options.formTemplate) {
// If a form template was specified, we'll clone it to generate new form instances:
template = (options.formTemplate instanceof $) ? options.formTemplate : $(options.formTemplate);
template.removeAttr('id').addClass(options.formCssClass + ' formset-custom-template');
template.find(childElementSelector).each(function() {
updateElementIndex($(this), options.prefix, '__prefix__');
});
insertDeleteLink(template);
} else {
// Otherwise, use the last form in the formset; this works much better if you've got
// extra (>= 1) forms (thnaks to justhamade for pointing this out):
if (options.hideLastAddForm) $('.' + options.formCssClass + ':last').hide();
template = $('.' + options.formCssClass + ':last').clone(true).removeAttr('id');
template.find('input:hidden[id $= "-DELETE"]').remove();
// Clear all cloned fields, except those the user wants to keep (thanks to brunogola for the suggestion):
template.find(childElementSelector).not(options.keepFieldValues).each(function() {
var elem = $(this);
// If this is a checkbox or radiobutton, uncheck it.
// This fixes Issue 1, reported by Wilson.Andrew.J:
if (elem.is('input:checkbox') || elem.is('input:radio')) {
elem.attr('checked', false);
} else {
elem.val('');
}
});
}
// FIXME: Perhaps using $.data would be a better idea?
options.formTemplate = template;
var addButtonHTML = '<a class="' + options.addCssClass + '" href="javascript:void(0);">' + options.addText + '</a>';
if (options.addContainerClass) {
// If we have a specific container for the "add" button,
// place it as the last child of that container:
var addContainer = $('[class*="' + options.addContainerClass + '"');
addContainer.append(addButtonHTML);
addButton = addContainer.find('[class="' + options.addCssClass + '"]');
} else if ($$.is('TR')) {
// If forms are laid out as table rows, insert the
// "add" button in a new table row:
var numCols = $$.eq(0).children().length, // This is a bit of an assumption :|
buttonRow = $('<tr><td colspan="' + numCols + '">' + addButtonHTML + '</tr>').addClass(options.formCssClass + '-add');
$$.parent().append(buttonRow);
addButton = buttonRow.find('a');
} else {
// Otherwise, insert it immediately after the last form:
$$.filter(':last').after(addButtonHTML);
addButton = $$.filter(':last').next();
}
if (hideAddButton) addButton.hide();
addButton.click(function() {
var formCount = parseInt(totalForms.val()),
row = options.formTemplate.clone(true).removeClass('formset-custom-template'),
buttonRow = $($(this).parents('tr.' + options.formCssClass + '-add').get(0) || this),
delCssSelector = $.trim(options.deleteCssClass).replace(/\s+/g, '.');
applyExtraClasses(row, formCount);
row.insertBefore(buttonRow).show();
row.find(childElementSelector).each(function() {
updateElementIndex($(this), options.prefix, formCount);
});
totalForms.val(formCount + 1);
// Check if we're above the minimum allowed number of forms -> show all delete link(s)
if (showDeleteLinks()){
$('a.' + delCssSelector).each(function(){$(this).show();});
}
// Check if we've exceeded the maximum allowed number of forms:
if (!showAddButton()) buttonRow.hide();
// If a post-add callback was supplied, call it with the added form:
if (options.added) options.added(row);
return false;
});
}
return $$;
};
/* Setup plugin defaults */
$.fn.formset.defaults = {
prefix: 'form', // The form prefix for your django formset
formTemplate: null, // The jQuery selection cloned to generate new form instances
addText: 'add another', // Text for the add link
deleteText: 'remove', // Text for the delete link
addContainerClass: null, // Container CSS class for the add link
deleteContainerClass: null, // Container CSS class for the delete link
addCssClass: 'add-row', // CSS class applied to the add link
deleteCssClass: 'delete-row', // CSS class applied to the delete link
formCssClass: 'dynamic-form', // CSS class applied to each form in a formset
extraClasses: [], // Additional CSS classes, which will be applied to each form in turn
keepFieldValues: '', // jQuery selector for fields whose values should be kept when the form is cloned
added: null, // Function called each time a new form is added
removed: null, // Function called each time a form is deleted
hideLastAddForm: false // When set to true, hide last empty add form (becomes visible when clicking on add button)
};
})(jQuery);

View File

@ -122,14 +122,19 @@
</li>
<li>
<a href="/dx">
<i class="simple-icon-book-open"></i> <span class="d-inline-block">Παραγγελίες Μήνα</span>
<i class="simple-icon-book-open"></i> <span class="d-inline-block">Παραγγελίες 3μήνου</span>
</a>
</li>
<li>
<a href="/dx?all_orders=true">
<i class="simple-icon-folder-alt"></i> <span class="d-inline-block">Όλες οι Παραγγελίες</span>
</a>
</li>
</ul>
<ul class="list-unstyled" data-link="products">
<li>
<a href="/dx/order_products/">
<i class="simple-icon-basket-loaded"></i> <span class="d-inline-block">Προϊόντα Παραγγελιών</span>
<i class="simple-icon-basket-loaded"></i> <span class="d-inline-block">Προϊόντα Παραγγελιών (μέχρι 200)</span>
</a>
</li>
<li>

View File

@ -1,77 +1,41 @@
{% load crispy_forms_tags %}
{% load static %}
{% if 'order/update' in current_view %}
<p class="badge badge-outline-warning mb-1">*Για να <b>διαγράψουμε</b> προϊόντα επιλέγουμε τη διαγραφή σε όσα θέλουμε και πατάμε Αποθήκευση. <b>ΔΕΝ</b> πατάμε αφαίρεση.
<button type="button" class="badge badge-pill badge-warning mb-1" data-toggle="modal" data-target="#myModal"> Παράδειγμα</button>
<div id="myModal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p>Παράδειγμα:</p>
<hr>
<img src="{% static 'images/empty_form.png' %}" width="100%" class="img-responsive">
</div>
</div>
</div>
</div>
<br>
</p>
</div>
{% endif %}
<table class="table table-striped col-md-10" style="margin-left: 10px;">
{% block css %}
<style>
.delete-row {
align-self: center;
}
.form-row {
margin: 20px;
border-bottom: 5px solid #1a0505;
}
.form-group{
margin: 20px;
}
[id^="id_orderproduct_set"]{
width: 110%;
}
</style>
{% endblock css %}
{{ formset.management_form|crispy }}
{% for form in formset.forms %}
<tr style="border: solid thin;" class="form-row {% cycle 'row1' 'row2' %} formset_row-{{ formset.prefix }}">
<form method="post" enctype="multipart/form-data">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for form in formset.forms %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{{ hidden|as_crispy_field }}
{% endfor %}
{% endif %}
{% if field.name == "cake_img" or field.name == "cream_cake_img" %}
{{ field|as_crispy_field }}
{% if field.value %}
<img src ="/media/{{field.value}}" alt="" width="200px">
{% endif %}
{% else %}
{{ field|as_crispy_field }}
{% endif %}
{% crispy form %}
{% endfor %}
</td>
{% endfor %}
{{ field.errors.as_ul }}
</form>
</tr>
{% endfor %}
</table>
<script src="{% static 'gogo/js/vendor/jquery-3.3.1.min.js' %}"></script>
{% if 'order/update' in current_view %}
<script src="{% static 'formset/formset_update.js' %}"></script>
<script type="text/javascript">
$('.formset_row-{{ formset.prefix }}').formset({
addText: '<span class="badge badge-pill badge-info mb-1">Προσθήκη Προϊόντος</span>',
deleteText: 'Αφαίρεση',
prefix: '{{ formset.prefix }}',
});
</script>
{% else %}
<script src="{% static 'formset/formset.js' %}"></script>
<script type="text/javascript">
<br>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="{% static 'formset/formset.js' %}"></script>
<script type="text/javascript">
$('.formset_row-{{ formset.prefix }}').formset({
addText: '<span class="badge badge-pill badge-info mb-1">Προσθήκη Προϊόντος</span>',
deleteText: '<span class="badge badge-pill badge-danger mb-1">Αφαίρεση</span>',
prefix: '{{ formset.prefix }}',
});
</script>
{% endif %}

View File

@ -0,0 +1,57 @@
{% load crispy_forms_tags %}
{% load static %}
{% if 'order/update' in current_view %}
<p class="badge badge-outline-warning mb-1">*Για να <b>διαγράψουμε</b> προϊόντα επιλέγουμε τη διαγραφή σε όσα θέλουμε και πατάμε Αποθήκευση. <b>ΔΕΝ</b> πατάμε αφαίρεση.
<button type="button" class="badge badge-pill badge-warning mb-1" data-toggle="modal" data-target="#myModal"> Παράδειγμα</button>
<div id="myModal" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-body">
<p>Παράδειγμα:</p>
<hr>
<img src="{% static 'images/empty_form.png' %}" width="100%" class="img-responsive">
</div>
</div>
</div>
</div>
<br>
</p>
</div>
{% endif %}
<table class="table table-striped col-md-10" style="margin-left: 10px;">
{{ formset.management_form|crispy }}
{% for form in formset.forms %}
<tr style="border: solid thin;" class="form-row {% cycle 'row1' 'row2' %} formset_row-{{ formset.prefix }}">
<form method="post" enctype="multipart/form-data">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{% if field.name == "cake_img" or field.name == "cream_cake_img" %}
{{ field|as_crispy_field }}
{% if field.value %}
<img src ="/media/{{field.value}}" alt="" width="200px">
{% endif %}
{% else %}
{{ field|as_crispy_field }}
{% endif %}
</td>
{% endfor %}
{{ field.errors.as_ul }}
</form>
</tr>
{% endfor %}
</table>
<script src="{% static 'gogo/js/vendor/jquery-3.3.1.min.js' %}"></script>

View File

@ -1,6 +1,6 @@
{% extends "orders/order_detail.html" %}
{% block content %}
<div class="modal-dialog">
<div class="modal-dialog" style="margin-top:150px;">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title">Διαγραφή?</h3>
@ -15,11 +15,10 @@
<strong>
<ul>
<li>Αριθμός: {{ object.id }}</li>
<li>Πελάτης: {{ object.customer }}</li>
<li>Πελάτης: {{ object.customer_name }}</li>
<li>Ημ/νία Παραγγελίας: {{ object.order_date }}</li>
<li>Ημ/νία Παράδοσης: {{ object.delivery_date }}</li>
<li>Κατάστημα: {{ object.store }}</li>
<li>Κατάστημα: {{ object.order_products.all| cut:":"| cut:"<QuerySet"| cut:"<Product"| cut:">" }}</li>
</ul>
</strong>
<input class="btn btn-danger" type="submit" value="Ναι, Θέλω να τη διαγράψω" />