Commit 5e2c7b3f authored by Patrick's avatar Patrick

WIP after feed back

parent a0d059b9
......@@ -138,7 +138,7 @@ class PurchaseFilterByCustomer(SimpleListFilter):
permanence_id = request.GET.get('permanence', None)
list_filter = []
for c in Customer.objects.filter(may_order=True):
ci = CustomerInvoice.objects.filter(permanence=permanence_id, customer_id=c.id).order_by('?').first()
ci = CustomerInvoice.objects.filter(permanence_id=permanence_id, customer_id=c.id).order_by('?').first()
if ci is not None:
if ci.is_order_confirm_send:
list_filter.append(
......@@ -165,7 +165,7 @@ class PurchaseFilterByProducerForThisPermanence(SimpleListFilter):
permanence_id = request.GET.get('permanence', None)
list_filter = []
for p in Producer.objects.filter(permanence=permanence_id):
pi = ProducerInvoice.objects.filter(permanence=permanence_id, producer_id=p.id).order_by('?').first()
pi = ProducerInvoice.objects.filter(permanence_id=permanence_id, producer_id=p.id).order_by('?').first()
if pi is not None:
list_filter.append((p.id, "%s (%s)" % (p.short_profile_name, pi.total_price_with_tax,)))
else:
......
......@@ -8,7 +8,6 @@ from django.conf import settings
from django.contrib import admin
from django.contrib import messages
from django.contrib.admin import TabularInline
from django.db.models import Sum
from django.forms import ModelForm, BaseInlineFormSet
from django.forms.formsets import DELETION_FIELD_NAME
from django.shortcuts import render
......@@ -20,9 +19,10 @@ from parler.forms import TranslatableModelForm
from repanier.admin.fkey_choice_cache_mixin import ForeignKeyCacheMixin
from repanier.const import DECIMAL_ZERO, ORDER_GROUP, INVOICE_GROUP, \
COORDINATION_GROUP
COORDINATION_GROUP, PERMANENCE_OPENED, PERMANENCE_PLANNED, PERMANENCE_CLOSED
from repanier.models.box import BoxContent, Box
from repanier.models.product import Product
from repanier.models.offeritem import OfferItemWoReceiver
from repanier.task import task_box
from repanier.tools import update_offer_item
......@@ -99,6 +99,29 @@ class BoxContentInline(ForeignKeyCacheMixin, TabularInline):
readonly_fields = [
'get_calculated_customer_content_price'
]
has_add_or_delete_permission = None
def has_delete_permission(self, request, obj=None):
if self.has_add_or_delete_permission is None:
try:
parent_object = Box.objects.filter(
id=request.resolver_match.args[0]
).only(
"id").order_by('?').first()
if parent_object is not None and OfferItemWoReceiver.objects.filter(
product=parent_object.id,
permanence__status__gt=PERMANENCE_PLANNED,
permanence__status__lt=PERMANENCE_CLOSED
).order_by('?').exists():
self.has_add_or_delete_permission = False
else:
self.has_add_or_delete_permission = True
except:
self.has_add_or_delete_permission = True
return self.has_add_or_delete_permission
def has_add_permission(self, request):
return self.has_delete_permission(request)
def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == "product":
......@@ -119,7 +142,7 @@ class BoxContentInline(ForeignKeyCacheMixin, TabularInline):
class BoxForm(TranslatableModelForm):
calculated_stock = forms.DecimalField(
label=_("Current stock"), max_digits=9, decimal_places=3, required=False, initial=DECIMAL_ZERO)
label=_("Calculated current stock"), max_digits=9, decimal_places=3, required=False, initial=DECIMAL_ZERO)
calculated_customer_box_price = forms.DecimalField(
label=_("calculated customer box price"), max_digits=8, decimal_places=2, required=False, initial=DECIMAL_ZERO)
calculated_box_deposit = forms.DecimalField(
......@@ -127,19 +150,13 @@ class BoxForm(TranslatableModelForm):
def __init__(self, *args, **kwargs):
super(BoxForm, self).__init__(*args, **kwargs)
if self.instance.id is not None:
result_set = BoxContent.objects.filter(box_id=self.instance.id).aggregate(
Sum('calculated_customer_content_price'),
Sum('calculated_content_deposit')
)
calculated_customer_box_price = result_set["calculated_customer_content_price__sum"] \
if result_set["calculated_customer_content_price__sum"] is not None else DECIMAL_ZERO
calculated_box_deposit = result_set["calculated_content_deposit__sum"] \
if result_set["calculated_content_deposit__sum"] is not None else DECIMAL_ZERO
box = self.instance
if box.id is not None:
box_price, box_deposit = box.get_calculated_price()
self.fields["calculated_stock"].initial = self.instance.stock
self.fields["calculated_customer_box_price"].initial = calculated_customer_box_price
self.fields["calculated_box_deposit"].initial = calculated_box_deposit
self.fields["calculated_stock"].initial = box.get_calculated_stock()
self.fields["calculated_customer_box_price"].initial = box_price
self.fields["calculated_box_deposit"].initial = box_deposit
self.fields["calculated_customer_box_price"].disabled = True
self.fields["calculated_stock"].disabled = True
......@@ -182,10 +199,11 @@ class BoxAdmin(TranslatableAdmin):
return self.has_delete_permission(request, box)
def get_list_display(self, request):
self.list_editable = ('stock',)
if settings.DJANGO_SETTINGS_MULTIPLE_LANGUAGE:
return ('is_into_offer', 'get_long_name', 'language_column')
return ('get_is_into_offer', 'get_long_name', 'language_column', 'stock')
else:
return ('is_into_offer', 'get_long_name')
return ('get_is_into_offer', 'get_long_name', 'stock')
def flip_flop_select_for_offer_status(self, request, queryset):
task_box.flip_flop_is_into_offer(queryset)
......@@ -222,9 +240,9 @@ class BoxAdmin(TranslatableAdmin):
def get_fieldsets(self, request, box=None):
fields_basic = [
('long_name', 'picture2', 'calculated_stock'),
('calculated_customer_box_price', 'calculated_box_deposit'),
('customer_unit_price', 'unit_deposit'),
('long_name', 'picture2'),
('calculated_stock', 'calculated_customer_box_price', 'calculated_box_deposit'),
('stock', 'customer_unit_price', 'unit_deposit'),
]
fields_advanced_descriptions = [
'placement',
......@@ -243,7 +261,7 @@ class BoxAdmin(TranslatableAdmin):
return fieldsets
def get_readonly_fields(self, request, customer=None):
return ['stock', 'is_updated_on']
return ['is_updated_on']
def get_form(self, request, box=None, **kwargs):
form = super(BoxAdmin, self).get_form(request, box, **kwargs)
......@@ -271,18 +289,21 @@ class BoxAdmin(TranslatableAdmin):
if not hasattr(formset, 'changed_objects'): formset.changed_objects = []
if not hasattr(formset, 'deleted_objects'): formset.deleted_objects = []
box = form.instance
formset = formsets[0]
for box_content_form in formset:
box_content = box_content_form.instance
previous_product = box_content_form.fields['previous_product'].initial
if previous_product is not None and previous_product != box_content.product:
# Delete the box_content because the product has changed
box_content_form.instance.delete()
if box_content.product is not None:
if box_content.id is None:
box_content.box_id = box.id
if box_content_form.cleaned_data.get(DELETION_FIELD_NAME, False):
try:
formset = formsets[0]
for box_content_form in formset:
box_content = box_content_form.instance
previous_product = box_content_form.fields['previous_product'].initial
if previous_product is not None and previous_product != box_content.product:
# Delete the box_content because the product has changed
box_content_form.instance.delete()
elif box_content_form.has_changed():
box_content_form.instance.save()
box.save_update_stock()
if box_content.product is not None:
if box_content.id is None:
box_content.box_id = box.id
if box_content_form.cleaned_data.get(DELETION_FIELD_NAME, False):
box_content_form.instance.delete()
elif box_content_form.has_changed():
box_content_form.instance.save()
except IndexError:
# No formset present in list admin, but well in detail admin
pass
......@@ -76,7 +76,7 @@ class UserDataForm(forms.ModelForm):
may_order = self.cleaned_data["may_order"]
if may_order:
delivery_point = LUT_DeliveryPoint.objects.filter(
customer_responsible=self.instance.id
customer_responsible_id=self.instance.id
).order_by('?').first()
if delivery_point is not None:
self.add_error(
......@@ -87,7 +87,7 @@ class UserDataForm(forms.ModelForm):
is_active = self.cleaned_data.get("is_active")
if is_active is not None and not is_active:
delivery_point = LUT_DeliveryPoint.objects.filter(
customer_responsible=self.instance.id
customer_responsible_id=self.instance.id
).order_by('?').first()
if delivery_point is not None:
self.add_error(
......
......@@ -113,7 +113,7 @@ class LUTDeliveryPointDataForm(TranslatableModelForm):
if self.instance.id:
self.fields['customers'].initial = self.instance.customer_set.all()
self.fields['customers'].queryset = Customer.objects.filter(
Q(may_order=True, delivery_point__isnull=True) | Q(delivery_point=self.instance.id)
Q(may_order=True, delivery_point__isnull=True) | Q(delivery_point_id=self.instance.id)
).distinct()
def clean(self):
......@@ -146,7 +146,7 @@ class LUTDeliveryPointDataForm(TranslatableModelForm):
# The LUT_DeliveryPoint.price_list_multiplier will be used when invoicing the consumer responsible
# The link between the customer invoice and this customer responsible is made with
# CustomerInvoice.customer_charged
Customer.objects.filter(delivery_point=self.instance.id).update(price_list_multiplier=DECIMAL_ONE)
Customer.objects.filter(delivery_point_id=self.instance.id).update(price_list_multiplier=DECIMAL_ONE)
return instance
......
......@@ -73,7 +73,9 @@ class DeliveryBoardInline(ForeignKeyCacheMixin, TranslatableTabularInline):
def has_delete_permission(self, request, obj=None):
if self.has_add_or_delete_permission is None:
try:
parent_object = PermanenceInPreparation.objects.filter(id=request.resolver_match.args[0]).only(
parent_object = PermanenceInPreparation.objects.filter(
id=request.resolver_match.args[0]
).only(
"highest_status").order_by('?').first()
if parent_object is not None and parent_object.highest_status > PERMANENCE_PLANNED:
self.has_add_or_delete_permission = False
......@@ -515,7 +517,7 @@ class PermanenceInPreparationAdmin(TranslatableAdmin):
producer_invoices = ProducerInvoice.objects.none()
else:
producer_invoices = ProducerInvoice.objects.filter(
permanence=permanence.id,
permanence_id=permanence.id,
status=PERMANENCE_OPENED,
producer__represent_this_buyinggroup=False
).order_by("producer")
......@@ -697,11 +699,11 @@ class PermanenceInPreparationAdmin(TranslatableAdmin):
else:
producer_invoices = ProducerInvoice.objects.filter(
Q(
permanence=permanence.id,
permanence_id=permanence.id,
status=PERMANENCE_OPENED,
producer__represent_this_buyinggroup=False
) | Q(
permanence=permanence.id,
permanence_id=permanence.id,
status=PERMANENCE_CLOSED,
producer__represent_this_buyinggroup=False
)
......
......@@ -68,7 +68,7 @@ class RepanierSettings(AppConfig):
db_started = connection.cursor() is not None
except:
time.sleep(1)
from models import Configuration, LUT_DepartmentForCustomer, Staff, Purchase, CustomerInvoice
from models import Configuration, LUT_DepartmentForCustomer, Product
from const import DECIMAL_ONE, PERMANENCE_NAME_PERMANENCE, CURRENCY_EUR, ORDER_GROUP, \
INVOICE_GROUP, CONTRIBUTOR_GROUP, COORDINATION_GROUP, WEBMASTER_GROUP
try:
......@@ -96,7 +96,8 @@ class RepanierSettings(AppConfig):
# customer_charged__isnull=True).select_related("customer_invoice").order_by('?'):
# purchase.customer_charged = purchase.customer_invoice.customer_charged
# purchase.save(update_fields=["customer_charged",])
Staff.objects.rebuild()
# Staff.objects.rebuild()
Product.objects.filter(is_box=True).order_by('?').update(limit_order_quantity_to_stock=True)
# Create groups with correct rights
order_group = Group.objects.filter(name=ORDER_GROUP).only('id').order_by('?').first()
if order_group is None:
......
......@@ -62,14 +62,15 @@ class PermanenceMenu(Menu):
first_pass = True
closed_separator = separator
for permanence in Permanence.objects.filter(status__in=[PERMANENCE_CLOSED, PERMANENCE_SEND]) \
.only("id", "permanence_date") \
.order_by('-permanence_date'):
for permanence in Permanence.objects.filter(
status__in=[PERMANENCE_CLOSED, PERMANENCE_SEND],
master_permanence__isnull=True
).only("id", "permanence_date").order_by('-permanence_date'):
displayed_permanence_counter += 1
if first_pass and closed_separator:
submenu_id = self.append_separator(nodes, master_id, submenu_id)
first_pass = False
separator = True
# separator = True
closed_separator = False
submenu_id = self.append_permanence(is_anonymous, permanence, nodes, master_id, submenu_id)
if displayed_permanence_counter > 4:
......
......@@ -36,6 +36,7 @@ DECIMAL_0_10 = Decimal('0.10')
DECIMAL_0_12 = Decimal('0.12')
DECIMAL_0_20 = Decimal('0.20')
DECIMAL_0_21 = Decimal('0.21')
DECIMAL_MAX_STOCK = Decimal('999999')
ZERO_DECIMAL = Decimal('0')
ONE_DECIMAL = Decimal('0.1')
TWO_DECIMALS = Decimal('0.01')
......
......@@ -30,7 +30,7 @@ def send_invoice(permanence_id):
# To the producer we speak of "payment".
# This is the detail of the payment to the producer, i.e. received products
for producer in Producer.objects.filter(
permanence=permanence.id,
permanence_id=permanence.id,
language=language_code
).order_by('?'):
long_profile_name = producer.long_profile_name \
......@@ -80,7 +80,7 @@ def send_invoice(permanence_id):
'invoice_description', any_language=True, default=EMPTY_STRING
)
for customer in Customer.objects.filter(
customerinvoice__permanence=permanence.id,
customerinvoice__permanence_id=permanence.id,
customerinvoice__customer_charged_id=F('customer_id'),
represent_this_buyinggroup=False,
language=language_code
......
......@@ -66,7 +66,7 @@ def email_order(permanence_id, all_producers=True, producers_id=None, closed_del
# At least one order
to_email_board = []
for permanence_board in PermanenceBoard.objects.filter(
permanence=permanence.id).order_by('?'):
permanence_id=permanence.id).order_by('?'):
if permanence_board.customer:
to_email_board.append(permanence_board.customer.user.email)
......@@ -108,7 +108,7 @@ def email_order(permanence_id, all_producers=True, producers_id=None, closed_del
# Orders send to our producers
if REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_PRODUCER:
producer_set = Producer.objects.filter(
permanence=permanence.id,
permanence_id=permanence.id,
language=language_code,
).order_by('?')
if producers_id:
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -46,7 +46,7 @@ class Command(BaseCommand):
# self.move(record=obj, to_subdir="LUT_PermanenceRole", size="S")
for product in Product.objects.all():
if product.picture is not None:
self.move(record=product, to_subdir="product" + os.sep + str(product.producer.id), size="M")
self.move(record=product, to_subdir="product" + os.sep + str(product.producer_id), size="M")
for obj in OfferItem.objects.filter(product_id=product.id).order_by('?'):
obj.picture2 = product.picture2
obj.save()
......
......@@ -12,7 +12,7 @@ class Command(BaseCommand):
def handle(self, *args, **options):
for permanence in Permanence.objects.filter(
id=229
id=223
).order_by('permanence_date'):
print ("Cancel %s %s" % (permanence.permanence_date, permanence.get_status_display()))
permanence.recalculate_order_amount(re_init=True)
......
......@@ -3,6 +3,7 @@ from __future__ import unicode_literals
from django.core.validators import MinValueValidator
from django.db import models
from django.db.models import Sum
from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.utils.encoding import python_2_unicode_compatible
......@@ -16,9 +17,10 @@ from repanier.models.product import Product, product_pre_save
@python_2_unicode_compatible
class Box(Product):
def save_update_stock(self):
def get_calculated_stock(self):
# stock : max_digits=9, decimal_places=3 => 1000000 > max(stock)
stock = 1000000
stock = DECIMAL_MAX_STOCK
for box_content in BoxContent.objects.filter(
box_id=self.id,
product__limit_order_quantity_to_stock=True,
......@@ -30,12 +32,19 @@ class Box(Product):
"content_quantity", "product__stock", "product__limit_order_quantity_to_stock"
).order_by('?'):
stock = min(stock, box_content.product.stock // box_content.content_quantity)
if stock < 1000000:
self.stock = stock
else:
self.stock = DECIMAL_ZERO
self.limit_order_quantity_to_stock = True
self.save(update_fields=['stock', 'limit_order_quantity_to_stock'])
return stock
def get_calculated_price(self):
result_set = BoxContent.objects.filter(box_id=self.id).aggregate(
Sum('calculated_customer_content_price'),
Sum('calculated_content_deposit')
)
box_price = result_set["calculated_customer_content_price__sum"] \
if result_set["calculated_customer_content_price__sum"] is not None else DECIMAL_ZERO
box_deposit = result_set["calculated_content_deposit__sum"] \
if result_set["calculated_content_deposit__sum"] is not None else DECIMAL_ZERO
return box_price, box_deposit
class Meta:
proxy = True
......@@ -57,6 +66,7 @@ def box_pre_save(sender, **kwargs):
box.order_unit = PRODUCT_ORDER_UNIT_PC
box.producer_unit_price = box.customer_unit_price
box.producer_vat = box.customer_vat
box.limit_order_quantity_to_stock = True
# ! Important to initialise all fields of the box. Remember : a box is a product.
product_pre_save(sender, **kwargs)
......
......@@ -14,6 +14,7 @@ from django.utils.translation import ugettext_lazy as _
import producer
import purchase
import deliveryboard
from repanier.apps import DJANGO_IS_MIGRATION_RUNNING
from repanier.const import *
from repanier.fields.RepanierMoneyField import ModelMoneyField
......@@ -23,7 +24,7 @@ from repanier.tools import create_or_update_one_cart_item, get_signature
def permanence_verbose_name():
if DJANGO_IS_MIGRATION_RUNNING:
return EMPTY_STRING
from repanier.apps import REPANIER_SETTINGS_PERMANENCE_NAME
# from repanier.apps import REPANIER_SETTINGS_PERMANENCE_NAME
return _('order') # lambda: "%s" % REPANIER_SETTINGS_PERMANENCE_NAME
@python_2_unicode_compatible
......@@ -166,14 +167,18 @@ class CustomerInvoice(Invoice):
# self.customer_charged_id = self.customer_id
# price_list_multiplier may vary
from repanier.apps import REPANIER_SETTINGS_TRANSPORT, REPANIER_SETTINGS_MIN_TRANSPORT
self.delivery = delivery
if delivery is None:
if self.permanence.with_delivery_point:
delivery_point = self.customer.delivery_point
delivery = deliveryboard.DeliveryBoard.objects.filter(
delivery_point=delivery_point,
permanence=self.permanence
).order_by('?').first()
else:
delivery_point = None
else:
delivery_point = delivery.delivery_point
self.delivery = delivery
if delivery_point is None:
self.customer_charged = self.customer
......
......@@ -16,7 +16,7 @@ from repanier.const import BOX_UNICODE, DECIMAL_ZERO, PRODUCT_ORDER_UNIT_PC_KG,
DECIMAL_ONE, PRODUCT_ORDER_UNIT_PC_PRICE_KG, PRODUCT_ORDER_UNIT_PC_PRICE_LT, PRODUCT_ORDER_UNIT_PC_PRICE_PC, \
TWO_DECIMALS, PRODUCT_ORDER_UNIT_LT, DICT_VAT, DICT_VAT_RATE, FOUR_DECIMALS, PRODUCT_ORDER_UNIT_DEPOSIT, \
LUT_PRODUCT_ORDER_UNIT, PRODUCT_ORDER_UNIT_PC, LUT_PRODUCT_PLACEMENT, PRODUCT_PLACEMENT_BASKET, LUT_ALL_VAT, \
LIMIT_ORDER_QTY_ITEM
LIMIT_ORDER_QTY_ITEM, DECIMAL_MAX_STOCK
from repanier.fields.RepanierMoneyField import RepanierMoney, ModelMoneyField
from repanier.tools import get_display
......@@ -108,7 +108,7 @@ class Item(TranslatableModel):
stock = models.DecimalField(
_("Current stock"),
default=DECIMAL_ZERO, max_digits=9, decimal_places=3,
default=DECIMAL_MAX_STOCK, max_digits=9, decimal_places=3,
validators=[MinValueValidator(0)])
limit_order_quantity_to_stock = models.BooleanField(
_("limit maximum order qty of the group to stock qty"),
......
......@@ -24,9 +24,8 @@ class OfferItem(Item):
translations = TranslatedFields(
long_name=models.CharField(_("long_name"), max_length=100,
default=EMPTY_STRING, blank=True, null=True),
cache_part_a=HTMLField(configuration='CKEDITOR_SETTINGS_MODEL2', default=EMPTY_STRING, blank=True),
cache_part_b=HTMLField(configuration='CKEDITOR_SETTINGS_MODEL2', default=EMPTY_STRING, blank=True),
cache_part_e=HTMLField(configuration='CKEDITOR_SETTINGS_MODEL2', default=EMPTY_STRING, blank=True),
cache_part_a=HTMLField(default=EMPTY_STRING, blank=True),
cache_part_b=HTMLField(default=EMPTY_STRING, blank=True),
order_sort_order=models.IntegerField(
_("customer sort order for optimization"),
default=0, db_index=True),
......
......@@ -6,10 +6,11 @@ import datetime
from django.conf import settings
from django.core import urlresolvers
from django.core.cache import cache
from django.db import models
from django.db import models, transaction
from django.db.models import F, Sum
from django.utils import timezone, translation
from django.utils.encoding import python_2_unicode_compatible
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from djangocms_text_ckeditor.fields import HTMLField
from menus.menu_pool import menu_pool
......@@ -27,7 +28,7 @@ from repanier.picture.const import SIZE_L
from repanier.picture.fields import AjaxPictureField
from repanier.fields.RepanierMoneyField import ModelMoneyField
from repanier.const import *
from repanier.tools import get_full_status_display, cap
from repanier.tools import cap
# def verbose_name():
......@@ -144,6 +145,9 @@ class Permanence(TranslatableModel):
verbose_name=_("picture"),
null=True, blank=True,
upload_to="permanence", size=SIZE_L)
gauge = models.IntegerField(
default=0, editable=False
)
def get_producers(self):
if self.status == PERMANENCE_PLANNED:
......@@ -215,7 +219,7 @@ class Permanence(TranslatableModel):
))
else:
if pi.invoice_reference:
if pi.to_be_invoiced_balance != DECIMAL_ZERO:
if pi.to_be_invoiced_balance != DECIMAL_ZERO or pi.total_price_with_tax != DECIMAL_ZERO:
label = "%s (%s - %s)" % (
pi.producer.short_profile_name,
pi.to_be_invoiced_balance,
......@@ -227,7 +231,7 @@ class Permanence(TranslatableModel):
cap(pi.invoice_reference, 15)
)
else:
if pi.to_be_invoiced_balance != DECIMAL_ZERO:
if pi.to_be_invoiced_balance != DECIMAL_ZERO or pi.total_price_with_tax != DECIMAL_ZERO:
label = "%s (%s)" % (
pi.producer.short_profile_name,
pi.to_be_invoiced_balance
......@@ -293,22 +297,22 @@ class Permanence(TranslatableModel):
else:
link.append("<br/><br/>--")
total_price_with_tax = ci.get_total_price_with_tax(customer_charged=True)
if ci.is_order_confirm_send:
label = '%s%s (%s) %s%s' % (
"<b><i>" if ci.is_group else EMPTY_STRING,
ci.customer.short_basket_name,
"-" if ci.is_group or total_price_with_tax == DECIMAL_ZERO else total_price_with_tax,
ci.get_is_order_confirm_send_display(),
"</i></b>" if ci.is_group else EMPTY_STRING,
)
else:
label = '%s%s (%s) %s%s' % (
"<b><i>" if ci.is_group else EMPTY_STRING,
ci.customer.short_basket_name,
"-" if ci.is_group or total_price_with_tax == DECIMAL_ZERO else total_price_with_tax,
ci.get_is_order_confirm_send_display(),
"</i></b>" if ci.is_group else EMPTY_STRING,
)
# if ci.is_order_confirm_send:
label = '%s%s (%s) %s%s' % (
"<b><i>" if ci.is_group else EMPTY_STRING,
ci.customer.short_basket_name,
"-" if ci.is_group or total_price_with_tax == DECIMAL_ZERO else total_price_with_tax,
ci.get_is_order_confirm_send_display(),
"</i></b>" if ci.is_group else EMPTY_STRING,
)
# else:
# label = '%s%s (%s) %s%s' % (
# "<b><i>" if ci.is_group else EMPTY_STRING,
# ci.customer.short_basket_name,
# "-" if ci.is_group or total_price_with_tax == DECIMAL_ZERO else total_price_with_tax,
# ci.get_is_order_confirm_send_display(),
# "</i></b>" if ci.is_group else EMPTY_STRING,
# )
# Important : no target="_blank"
link.append(
'<a href="%s?permanence=%d&customer=%d">%s</a>'
......@@ -758,7 +762,65 @@ class Permanence(TranslatableModel):
self.total_selling_vat += customer_vat
def get_full_status_display(self):
return get_full_status_display(self)
need_to_refresh_status = self.status in [
PERMANENCE_WAIT_FOR_PRE_OPEN,
PERMANENCE_WAIT_FOR_OPEN,
PERMANENCE_WAIT_FOR_CLOSED,
PERMANENCE_WAIT_FOR_SEND,
PERMANENCE_WAIT_FOR_INVOICED
]
if self.with_delivery_point:
status_list = []
status = None
status_counter = 0
for delivery in deliveryboard.DeliveryBoard.objects.filter(permanence_id=self.id).order_by("status", "id"):
need_to_refresh_status |= delivery.status in [
PERMANENCE_WAIT_FOR_PRE_OPEN,
PERMANENCE_WAIT_FOR_OPEN,
PERMANENCE_WAIT_FOR_CLOSED,
PERMANENCE_WAIT_FOR_SEND,
PERMANENCE_WAIT_FOR_INVOICED
]
if status != delivery.status:
status = delivery.status
status_counter += 1
status_list.append("<b>%s</b>" % delivery.get_status_display())
status_list.append("- %s" % delivery.get_delivery_display(admin=True))
if status_counter > 1:
message = "<br/>".join(status_list)
else:
message = self.get_status_display()
else:
message = self.get_status_display()
if need_to_refresh_status:
url = urlresolvers.reverse(
'display_status',
args=(self.id,)
)
progress = "◤◥◢◣"[self.gauge] # "◴◷◶◵" "▛▜▟▙"
self.gauge = (self.gauge + 1) % 4
self.save(update_fields=['gauge'])
msg_html = """
<div class="wrap-text" id="id_get_status_%d">
<script type="text/javascript">
window.setTimeout(function(){
django.jQuery.ajax({
url: '%s',
cache: false,
async: false,
success: function (result) {
django.jQuery("#id_get_status_%d").html(result);
}
});
}, 500);
</script>
%s %s</div>
""" % (
self.id, url, self.id, progress, message
)
return mark_safe(msg_html)
else:
return mark_safe('<div class="wrap-text">%s</div>' % message)
get_full_status_display.short_description = (_("permanence_status"))
get_full_status_display.allow_tags = True
......@@ -819,9 +881,9 @@ class Permanence(TranslatableModel):
verbose_name = _('order')
verbose_name_plural = _('orders')
index_together = [
["permanence_date"],
]
# index_together = [
# ["permanence_date"],
# ]
class PermanenceInPreparation(Permanence):
......
......@@ -124,13 +124,12 @@ def product_pre_save(sender, **kwargs):
if producer.producer_pre_opening or producer.manage_production:
product.producer_order_by_quantity = DECIMAL_ZERO
product.limit_order_quantity_to_stock = True
if not product.is_box:
# IMPORTANT : Deactivate offeritem whose stock is not > 0 and product is into offer
product.is_into_offer = product.stock > DECIMAL_ZERO
# IMPORTANT : Deactivate offeritem whose stock is not > 0 and product is into offer
product.is_into_offer = product.stock > DECIMAL_ZERO
elif not producer.manage_replenishment:
product.limit_order_quantity_to_stock = False
if product.is_box:
product.limit_order_quantity_to_stock = False
product.limit_order_quantity_to_stock = True
if product.limit_order_quantity_to_stock:
product.customer_alert_order_quantity = min(999, product.stock)
elif product.order_unit == PRODUCT_ORDER_UNIT_SUBSCRIPTION:
......@@ -144,9 +143,9 @@ def product_pre_save(sender, **kwargs):
if not product.reference:
product.reference = uuid.uuid4()
# Update stock of boxes containing this product
for box_content in product.box_content.all():
if box_content.box is not None:
box_content.box.save_update_stock()
# for box_content in product.box_content.all():
# if box_content.box is not None:
# box_content.box.save_update_stock()
@receiver(post_save, sender=Product)
......
......@@ -10,10 +10,17 @@ from repanier.tools import cap
def flip_flop_is_into_offer(queryset):
for product in queryset.order_by('?'):
if product.is_active:
for product in queryset.filter(is_active=True).order_by('?'):
if product.limit_order_quantity_to_stock:
if product.stock > DECIMAL_ZERO:
product.is_into_offer = False
product.stock = DECIMAL_ZERO
else:
product.is_into_offer = True
product.stock = 999999
else:
product.is_into_offer = not product.is_into_offer
product.save(update_fields=['is_into_offer'])
product.save(update_fields=['is_into_offer', 'stock'])
def admin_duplicate(queryset):
......
......@@ -2,7 +2,7 @@
import threading
from django.contrib import messages
from django.db.models import Sum
from django.db.models import Sum, ProtectedError
from django.utils.translation import ugettext_lazy as _