Commit ccf43cee authored by Patrick's avatar Patrick

Work and tests in progress

parent 2fa467a8
......@@ -57,7 +57,8 @@ class ConfigurationAdmin(TranslatableAdmin):
'customers_must_confirm_orders',
('bank_account', 'max_week_wo_participation'),
('membership_fee', 'membership_fee_duration'),
'how_to_register'),
'notification_is_public',
'notification'),
}),
]
if Producer.objects.filter(producer_pre_opening=True).order_by('?').only('id').exists():
......@@ -109,6 +110,7 @@ class ConfigurationAdmin(TranslatableAdmin):
'sms_gateway_mail',
'invoice',
('currency', 'vat_id'),
'how_to_register'
),
}),
]
......
......@@ -431,11 +431,11 @@ class PermanenceInPreparationAdmin(TranslatableAdmin):
email_will_be_sent, email_will_be_sent_to = send_email_to_who(
repanier.apps.REPANIER_SETTINGS_SEND_OPENING_MAIL_TO_CUSTOMER
)
if 'apply' in request.POST:
if 'apply' in request.POST or 'apply-wo-mail' in request.POST:
form = OpenAndSendOfferForm(request.POST)
if form.is_valid():
user_message, user_message_level = task_order.admin_open_and_send(
request, permanence
request, permanence, 'apply-wo-mail' in request.POST
)
self.message_user(request, user_message, user_message_level)
return HttpResponseRedirect(request.get_full_path())
......
......@@ -291,6 +291,7 @@ class OfferItemSendAdmin(admin.ModelAdmin):
@transaction.atomic
def save_related(self, request, form, formsets, change):
getcontext().rounding = ROUND_HALF_UP
for formset in formsets:
# option.py -> construct_change_message doesn't test the presence of those array not created at form initialisation...
if not hasattr(formset, 'new_objects'): formset.new_objects = []
......@@ -380,6 +381,7 @@ class OfferItemSendAdmin(admin.ModelAdmin):
ratio = DECIMAL_ZERO
else:
ratio = DECIMAL_ONE
# Rule of 3
if ratio != DECIMAL_ONE:
adjusted_invoice = DECIMAL_ZERO
i = 0
......
This diff is collapsed.
......@@ -96,6 +96,7 @@ class Configuration(TranslatableModel):
help_text=_("This is the minimum order amount to avoid shipping cost."),
default=DECIMAL_ZERO, max_digits=5, decimal_places=2,
validators=[MinValueValidator(0)])
notification_is_public = models.BooleanField(_("the notification is public"), default=False)
translations = TranslatedFields(
group_label=models.CharField(_("group label"),
max_length=100,
......@@ -104,11 +105,13 @@ class Configuration(TranslatableModel):
how_to_register=HTMLField(_("how to register"),
help_text=EMPTY_STRING,
configuration='CKEDITOR_SETTINGS_MODEL2',
default=
"""
Pour créer un compte et passer commande, veuillez contacter ....
""",
blank=False),
default=EMPTY_STRING,
blank=True),
notification=HTMLField(_("notification"),
help_text=EMPTY_STRING,
configuration='CKEDITOR_SETTINGS_MODEL2',
default=EMPTY_STRING,
blank=True),
offer_customer_mail=HTMLField(_("offer customer mail"),
help_text=EMPTY_STRING,
configuration='CKEDITOR_SETTINGS_MODEL2',
......
......@@ -8,6 +8,7 @@ from django.db import models
from django.db import transaction
from django.db.models import F, Sum
from django.utils.encoding import python_2_unicode_compatible
from django.utils.formats import number_format
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
......@@ -373,7 +374,8 @@ class CustomerInvoice(models.Model):
customer=a_purchase.customer,
offer_item_id=a_purchase.offer_item_id,
q_order=DECIMAL_ZERO,
batch_job=True
batch_job=True,
comment=_("Cancelled qty : %s") % number_format(purchase.quantity_ordered, 4)
)
def __str__(self):
......
......@@ -19,7 +19,7 @@ import repanier.apps
from repanier.const import *
from repanier.fields.RepanierMoneyField import ModelMoneyField
from repanier.models.box import BoxContent
from repanier.tools import get_or_create_offer_item
from repanier.tools import get_or_create_offer_item, cap
@python_2_unicode_compatible
......@@ -210,6 +210,13 @@ class Purchase(models.Model):
else:
raise AttributeError
def set_comment(self, comment):
if comment:
if self.comment:
self.comment = cap("%s, %s" % (self.comment, comment), 100)
else:
self.comment = cap(comment, 100)
@transaction.atomic
def save(self, *args, **kwargs):
if not self.pk:
......
......@@ -15,7 +15,8 @@ from django.core.files.storage import default_storage
from django.conf import settings
from django.http import HttpResponse
from django.utils.text import slugify
from django.utils.translation import ugettext as _not_lazy
# from django.utils.translation import ugettext as _not_lazy
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.http import require_POST
from .forms import FileForm
......@@ -29,13 +30,14 @@ def ajax_picture(request, upload_to=None, form_class=FileForm, size=SIZE_XS):
if form.is_valid():
size = sint(size)
if size not in [SIZE_XS, SIZE_S, SIZE_M, SIZE_L]:
data = json.dumps({'error': _not_lazy('Wrong size.')})
msg = "%s" % _('Wrong picture size.')
data = json.dumps({'error': msg})
return HttpResponse(data, content_type="application/json", status=403)
disk = os.statvfs(settings.MEDIA_ROOT)
if disk.f_blocks > 0 and ((disk.f_bfree + 1.0) / disk.f_blocks) < 0.2:
data = json.dumps({'error': _not_lazy(
'Please, contact the administrator of the webserver : There is not enough disk space.')})
msg = "%s" % _('Please, contact the administrator of the webserver : There is not enough disk space.')
data = json.dumps({'error': msg})
return HttpResponse(data, content_type="application/json", status=403)
file_ = form.cleaned_data['file']
......@@ -43,7 +45,8 @@ def ajax_picture(request, upload_to=None, form_class=FileForm, size=SIZE_XS):
'image/gif']
if file_.content_type not in image_types:
data = json.dumps({'error': _not_lazy('The system does not recognize the format.')})
msg = "%s" % _('The system does not recognize the format.')
data = json.dumps({'error': msg})
return HttpResponse(data, content_type="application/json", status=403)
file_name, extension = os.path.splitext(file_.name)
......@@ -51,23 +54,27 @@ def ajax_picture(request, upload_to=None, form_class=FileForm, size=SIZE_XS):
name = os.path.join(upload_to or "tmp", safe_name)
if default_storage.exists(name):
msg = "%s" % _(
'A picture with the same file name already exist. This picture will not replace it.'
)
return HttpResponse(
json.dumps(
{'url' : default_storage.url(name),
'filename': name,
'msg' : _not_lazy(
'An image with same file name already exist. Please, check the file name and rename it if necessary.')
'msg' : msg
}
), content_type="application/json")
else:
image = Image.open(file_)
if image.size[0] > size or image.size[1] > size:
return HttpResponse(json.dumps({'error': _not_lazy('Wrong size.')}), content_type="application/json",
msg = "%s" % _('The file size is too big.')
return HttpResponse(json.dumps({'error': msg}), content_type="application/json",
status=403)
file_name = default_storage.save(name, image.fp)
url = default_storage.url(file_name)
return HttpResponse(json.dumps({'url': url, 'filename': file_name}), content_type="application/json")
file_name = default_storage.save(name, image.fp)
url = default_storage.url(file_name)
return HttpResponse(
json.dumps(
{'url': url, 'filename': file_name}
), content_type="application/json")
return HttpResponse(status=403)
......@@ -177,7 +177,7 @@ def pre_open_order(permanence_id):
@transaction.atomic
def open_order(permanence_id):
def open_order(permanence_id, do_not_send_any_mail=False):
permanence = common_to_pre_open_and_open(permanence_id)
# 1 - Disallow access to the producer to his/her products no more into "pre order" status
for producer in Producer.objects.filter(
......@@ -203,7 +203,7 @@ def open_order(permanence_id):
permanence.producers.add(offer_item.producer_id)
try:
if repanier.apps.REPANIER_SETTINGS_SEND_OPENING_MAIL_TO_CUSTOMER:
if repanier.apps.REPANIER_SETTINGS_SEND_OPENING_MAIL_TO_CUSTOMER and not do_not_send_any_mail:
email_offer.send_open_order(permanence_id)
permanence.set_status(PERMANENCE_OPENED)
except Exception as error_str:
......@@ -247,7 +247,7 @@ def admin_undo_back_to_planned(request, permanence):
return user_message, user_message_level
def admin_open_and_send(request, permanence):
def admin_open_and_send(request, permanence, do_not_send_any_mail=False):
producer_pre_opening = Producer.objects.filter(
permanence__id=permanence.id, is_active=True, producer_pre_opening=True
).order_by('?')
......@@ -267,7 +267,7 @@ def admin_open_and_send(request, permanence):
else:
permanence.set_status(PERMANENCE_WAIT_FOR_OPEN)
# open_order(permanence.id)
thread.start_new_thread(open_order, (permanence.id,))
thread.start_new_thread(open_order, (permanence.id, do_not_send_any_mail))
user_message = _("The offers are being generated.")
user_message_level = messages.INFO
return user_message, user_message_level
......
......@@ -96,32 +96,22 @@
</div>
<a name="content"></a><section>
{% if current_page.is_home %}
<div class="container-info" id="containerInfo" style="display: none">
<div class="container">
<div class="row">
<div class="col-md-12">
<div class="panel panel-default" id="homeInfo">
</div>
</div>
</div>
</div>
</div>
{% addtoblock "lastjs" %}{% spaceless %}
<script type="text/javascript">
$(document).ready(function () {
lien = '{% url 'home_info' %}';
$.ajax({
url: lien,
cache: false,
async: false,
success: function (result) {
$("#homeInfo").html(result);
$("#containerInfo").show();
}
});
});
</script>
{% endspaceless %}{% endaddtoblock %}
<div class="container-info" id="containerInfo" style="display: none"></div>
{% addtoblock "lastjs" %}{% spaceless %}
<script type="text/javascript">
$(document).ready(function () {
lien = '{% url 'home_info' %}';
$.ajax({
url: lien,
cache: false,
async: false,
success: function (result) {
$("#containerInfo").html(result).show();
}
});
});
</script>
{% endspaceless %}{% endaddtoblock %}
{% endif %}
{% block base_content%}{% endblock %}
</section>
......
......@@ -10,6 +10,9 @@
<div class="submit-row">
<button type="submit" name="cancel" value="cancel"><h6>{% trans "No, cancel the action" %}</h6></button>
<button type="submit" name="apply" value="apply" class="default"><h6>{% trans "Yes, I'm sure" %}</h6></button>
{% if email_will_be_sent %}
<button type="submit" name="apply-wo-mail" value="apply-wo-mail"><h6>{% trans "Yes, I'm sure but do not send any mail" %}</h6></button>
{% endif %}
</div>
<fieldset class="module aligned ">
<div class="submit-row">
......
......@@ -134,7 +134,7 @@
{% endif %}
{% if download_invoice %}
<a href="{% url 'download_customer_invoice' object.id %}"
class="btn btn-disabled"> {% trans "Download" %} <span class="glyphicon glyphicon glyphicon-save"></span> </a>
class="btn btn-success btn-disabled"> {% trans "Download" %} <span class="glyphicon glyphicon glyphicon-save"></span> </a>
{% endif %}
{% if next_customer_invoice_id %}
<a href="{% url 'customer_invoice_view' next_customer_invoice_id %}"
......
{% extends 'cms_page.html' %}
{% load cms_tags sekizai_tags i18n l10n thumbnail filer_tags filer_image_tags %}
{% block sub_content %}
<div id="containerInfo" style="display: none"></div>
{% addtoblock "lastjs" %}{% spaceless %}
<script type="text/javascript">
$(document).ready(function () {
lien = '{% url 'order_info' %}';
$.ajax({
url: lien,
cache: false,
async: false,
success: function (result) {
$("#containerInfo").html(result).show();
}
});
});
</script>
{% endspaceless %}{% endaddtoblock %}
{% if is_anonymous %}
<div class="row">
<div class="panel-group">
......@@ -9,6 +25,7 @@
<div class="col-xs-3">
<a href="{% url "login_form" %}?next={% url 'order_delivery_view' permanence.id delivery_id %}" class="btn btn-default">{% trans "Login me" %}</a>
</div>
{% if how_to_register %}
<div class="col-xs-9">
<div class="accordion-toggle collapsed" data-toggle="collapse" data-target="#collapse">
<span class="btn btn-info">{% trans "Create an account" %}</span>
......@@ -17,6 +34,7 @@
{{ how_to_register }}
</div>
</div>
{% endif %}
</div>
</div>
</div>
......
......@@ -42,6 +42,7 @@
<input type="hidden" name="this_is_the_login_form" value="1" />
<input type="hidden" name="next" value="{{ next }}" />
</div>
{% if how_to_register %}
<p></p>
<div class="form-group">
<div class="accordion-toggle collapsed" data-toggle="collapse" data-target="#collapse">
......@@ -52,6 +53,7 @@
</div>
</div>
</div>
{% endif %}
<div class="modal-footer">
<div class="form-group">
<button class="btn btn-default" type="submit">{% trans "Login" %}</button>
......
......@@ -26,6 +26,7 @@ from django.utils.safestring import mark_safe
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
from parler.models import TranslationDoesNotExist
from six import string_types
import models
from const import *
......@@ -312,7 +313,7 @@ def cap_to_bytes_length(unicode_text, byte_limit):
def cap(s, l):
if s is not None:
if not isinstance(s, basestring):
if not isinstance(s, string_types):
s = str(s)
s = s if len(s) <= l else s[0:l - 4] + '...'
return s
......@@ -787,21 +788,13 @@ def recalculate_order_amount(permanence_id,
if offer_item.order_unit == PRODUCT_ORDER_UNIT_PC_KG:
purchase.quantity_invoiced = (purchase.quantity_ordered * offer_item.order_average_weight) \
.quantize(FOUR_DECIMALS)
if offer_item.wrapped:
purchase.quantity_for_preparation_sort_order = DECIMAL_ZERO
else:
purchase.quantity_for_preparation_sort_order = purchase.quantity_ordered
elif offer_item.order_unit == PRODUCT_ORDER_UNIT_KG:
purchase.quantity_invoiced = purchase.quantity_ordered
if offer_item.wrapped:
purchase.quantity_for_preparation_sort_order = DECIMAL_ZERO
else:
purchase.quantity_for_preparation_sort_order = purchase.quantity_ordered
else:
purchase.quantity_invoiced = purchase.quantity_ordered
purchase.quantity_for_preparation_sort_order = DECIMAL_ZERO
purchase.save()
if send_to_producer:
reorder_purchases(permanence_id)
def display_selected_value(offer_item, quantity_ordered):
if offer_item.may_order:
......@@ -967,7 +960,8 @@ def update_or_create_purchase(customer=None, offer_item_id=None, q_order=None, v
if quantity_ordered < DECIMAL_ZERO:
quantity_ordered = DECIMAL_ZERO
purchase, updated = create_or_update_one_purchase(
customer.id, box_offer_item, q_order=quantity_ordered, batch_job=batch_job, is_box_content=True
customer.id, box_offer_item, q_order=quantity_ordered,
batch_job=batch_job, is_box_content=True
)
else:
updated = False
......@@ -1304,7 +1298,10 @@ def my_order_confirmation_email_send_to(customer):
return msg_confirmation
def create_or_update_one_purchase(customer_id, offer_item, permanence_date=None, status=PERMANENCE_OPENED, q_order=None, batch_job=False, is_box_content=False):
def create_or_update_one_purchase(
customer_id, offer_item,
permanence_date=None, status=PERMANENCE_OPENED, q_order=None,
batch_job=False, is_box_content=False, comment=EMPTY_STRING):
# The batch_job flag is used because we need to forbid
# customers to add purchases during the close_orders_async or other batch_job process
......@@ -1327,12 +1324,14 @@ def create_or_update_one_purchase(customer_id, offer_item, permanence_date=None,
quantity_ordered=q_order if status < PERMANENCE_SEND else DECIMAL_ZERO,
quantity_invoiced=q_order if status >= PERMANENCE_SEND else DECIMAL_ZERO,
is_box_content=is_box_content,
status=status
status=status,
comment=comment
)
else:
purchase.set_comment(comment)
if status < PERMANENCE_SEND:
if q_order == DECIMAL_ZERO:
purchase.comment = _("Cancelled qty : %s") % number_format(purchase.quantity_ordered, 4)
# if q_order == DECIMAL_ZERO:
# purchase.comment = _("Cancelled qty : %s") % number_format(purchase.quantity_ordered, 4)
purchase.quantity_ordered = q_order
else:
purchase.quantity_invoiced = q_order
......@@ -1370,6 +1369,7 @@ def create_or_update_one_purchase(customer_id, offer_item, permanence_date=None,
else:
q_alert = offer_item.customer_alert_order_quantity
if purchase is not None:
purchase.set_comment(comment)
if q_order <= q_alert:
if purchase.quantity_confirmed <= q_order:
purchase.quantity_ordered = q_order
......@@ -1392,14 +1392,14 @@ def create_or_update_one_purchase(customer_id, offer_item, permanence_date=None,
quantity_ordered=q_order,
quantity_invoiced=DECIMAL_ZERO,
is_box_content=is_box_content,
status=status
status=status,
comment=comment
)
return purchase, True
else:
return purchase, False
def clean_offer_item(permanence, queryset, reset_add_2_stock=False):
if permanence.status > PERMANENCE_SEND:
# The purchases are already invoiced.
......@@ -1488,6 +1488,22 @@ def clean_offer_item(permanence, queryset, reset_add_2_stock=False):
translation.activate(cur_language)
def reorder_purchases(permanence_id):
# Order the purchases such that lower quantity are before larger quantity
models.Purchase.objects.filter(
permanence_id=permanence_id
).update(
quantity_for_preparation_sort_order=DECIMAL_ZERO
)
models.Purchase.objects.filter(
permanence_id=permanence_id,
offer_item__wrapped=False,
offer_item__order_unit__in=[PRODUCT_ORDER_UNIT_KG, PRODUCT_ORDER_UNIT_PC_KG]
).update(
quantity_for_preparation_sort_order=F('quantity_invoiced')
)
def reorder_offer_items(permanence_id):
# calculate the sort order of the order display screen
cur_language = translation.get_language()
......
......@@ -43,6 +43,7 @@ from repanier.views.display_status_ajax import display_status
from repanier.views.is_into_offer_ajax import is_into_offer
from repanier.views.download_customer_invoice import download_customer_invoice
from repanier.views.home_info_ajax import home_info_ajax
from repanier.views.order_info_ajax import order_info_ajax
urlpatterns = [
url(r'^go_repanier/$', login_view, name='login_form'),
......@@ -93,6 +94,7 @@ urlpatterns = [
url(r'^ajax/my-balance/$', my_balance_ajax, name='my_balance'),
url(r'^ajax/order-name/$', customer_name_ajax, name='order_name'),
url(r'^ajax/home-info/$', home_info_ajax, name='home_info'),
url(r'^ajax/order-info/$', order_info_ajax, name='order_info'),
url(r'^ajax/pre-order-name/(?P<offer_uuid>[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})/$',
producer_name_ajax, name='pre_order_name_ajax'),
url(r'^ajax/order-init/$', order_init_ajax, name='order_init_ajax'),
......
......@@ -10,7 +10,7 @@ from django.utils.safestring import mark_safe
from django.views.decorators.cache import never_cache
from django.views.decorators.http import require_GET
from repanier.const import PERMANENCE_OPENED
from repanier.const import PERMANENCE_OPENED, EMPTY_STRING
from repanier.models import Permanence
......@@ -18,12 +18,14 @@ from repanier.models import Permanence
@require_GET
def home_info_ajax(request):
if request.is_ajax():
result = []
from repanier.apps import REPANIER_SETTINGS_CONFIG
permanences = []
home_info = EMPTY_STRING
for permanence in Permanence.objects.filter(
status=PERMANENCE_OPENED) \
.only("id", "permanence_date", "with_delivery_point") \
.order_by('permanence_date'):
result.append(
.order_by('-permanence_date', '-id'):
permanences.append(
format_html(
'<div class="panel-heading"><h4 class="panel-title"><a href="{}">{}</a></h4></div>',
reverse('order_view', args=(permanence.id,)),
......@@ -32,7 +34,7 @@ def home_info_ajax(request):
)
if permanence.offer_description_on_home_page and permanence.offer_description:
if permanence.picture:
result.append(
permanences.append(
format_html(
'<div class="panel-body"><div class="col-xs-12"><img class="img-rounded" style="float: left; margin: 5px;" alt="{}" title="{}" src="{}{}"/>{}</div></div>',
permanence.get_permanence_customer_display(),
......@@ -43,12 +45,51 @@ def home_info_ajax(request):
)
)
else:
result.append(
permanences.append(
format_html(
'<div class="panel-body"><div class="col-xs-12">{}</div></div>',
mark_safe(permanence.offer_description)
)
)
if len(result) > 0:
return HttpResponse("".join(result))
if len(permanences) > 0:
home_info = """
<div class="container">
<div class="row">
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-body">
<div class="col-md-12">
{permanences}
</div>
</div>
</div>
</div>
</div>
</div>
""".format(
permanences="".join(permanences)
)
if REPANIER_SETTINGS_CONFIG.notification:
if REPANIER_SETTINGS_CONFIG.notification_is_public or request.user.is_authenticated:
home_info = """
<div class="container">
<div class="row">
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-body">
<div class="col-md-12">
{notification}
</div>
</div>
</div>
</div>
</div>
</div>
{home_info}
""".format(
notification=REPANIER_SETTINGS_CONFIG.notification,
home_info=home_info
)
return HttpResponse(home_info)
raise Http404
# -*- coding: utf-8
from __future__ import unicode_literals
from django.conf import settings
from django.http import Http404
from django.http import HttpResponse
from django.urls import reverse
from django.utils.html import format_html
from django.utils.safestring import mark_safe
from django.views.decorators.cache import never_cache
from django.views.decorators.http import require_GET
from repanier.const import PERMANENCE_OPENED, EMPTY_STRING
from repanier.models import Permanence
@never_cache
@require_GET
def order_info_ajax(request):
if request.is_ajax():
from repanier.apps import REPANIER_SETTINGS_CONFIG
order_info = EMPTY_STRING
if REPANIER_SETTINGS_CONFIG.notification:
if REPANIER_SETTINGS_CONFIG.notification_is_public or request.user.is_authenticated:
order_info = """
<div class="row">
<div class="panel-group">
<div class="panel panel-default">
<div class="panel-body">
<div class="col-md-12">
{notification}
</div>
</div>
</div>
</div>
</div>
""".format(
notification=REPANIER_SETTINGS_CONFIG.notification
)
return HttpResponse(order_info)
raise Http404
# -*- coding: utf-8
from __future__ import unicode_literals
from django.conf import settings
from django.db import transaction
from django.utils import translation, timezone
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from openpyxl import load_workbook
from openpyxl.style import Border
......@@ -19,7 +18,7 @@ from repanier.models import CustomerInvoice
from repanier.models import Producer
from repanier.models import ProducerInvoice
from repanier.tools import get_invoice_unit, get_reverse_invoice_unit, get_or_create_offer_item, \
create_or_update_one_purchase
create_or_update_one_purchase, reorder_offer_items, reorder_purchases
from repanier.xlsx.import_tools import get_customer_email_2_id_dict, \
get_header, get_row
......@@ -266,6 +265,7 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
(_("invoice_status"), 10, purchase.get_status_display(), NumberFormat.FORMAT_TEXT, False),
(_("customer"), 10, purchase.customer.user.email, NumberFormat.FORMAT_TEXT, False),
(_("reference"), 10, purchase.offer_item.reference, NumberFormat.FORMAT_TEXT, False),
(_("wrapped"), 10, purchase.offer_item.wrapped, NumberFormat.FORMAT_TEXT, False),
]
if row_num == 0:
......@@ -303,6 +303,7 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
ws.column_dimensions[get_column_letter(15)].visible = False
ws.column_dimensions[get_column_letter(18)].visible = False
ws.column_dimensions[get_column_letter(19)].visible = False
ws.column_dimensions[get_column_letter(20)].visible = False
for col_num in range(len(row)):
c = ws.cell(row=row_num, column=col_num)
c.style.borders.top.border_style = Border.BORDER_THIN
......@@ -397,20 +398,28 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
product.unit_deposit = row[_("deposit")]
product.order_unit = order_unit
product.vat_level = vat_level
product.wrapped = row[_("wrapped")]
product.save()
qty_and_price_display = product.get_qty_and_price_display()
qty_and_price_display = product.get_qty_and_price_display(customer_price=False)
if product.long_name.endswith(qty_and_price_display):
product.long_name = product.long_name[:-len(qty_and_price_display)]
product.save()
offer_item = get_or_create_offer_item(permanence, product.id, producer.id)
create_or_update_one_purchase(customer_id, offer_item, q_order=1,
status=PERMANENCE_SEND,
permanence_date=permanence.permanence_date,
batch_job=True, is_box_content=False)
create_or_update_one_purchase(
customer_id,
offer_item,
q_order=Decimal(row[_("Quantity")]),
status=PERMANENCE_SEND,
permanence_date=permanence.permanence_date,
batch_job=True, is_box_content=False,
comment=row[_("comment")]
)
import_counter += 1
row_num += 1
row = get_row(worksheet, header, row_num)
reorder_offer_items(permanence.id)
reorder_purchases(permanence.id)
except KeyError as e:
# Missing field
......@@ -431,17 +440,13 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
def handle_uploaded_invoice(request, permanences, file_to_import, producer, invoice_reference):
error = False
error_msg = None
if producer is None:
error = True
error_msg = _("A producer must be given.")
wb = load_workbook(file_to_import)
# dict for performance optimisation purpose : read the DB only once
customer_2_id_dict = get_customer_email_2_id_dict()
if not error:
else:
wb = load_workbook(file_to_import)
# dict for performance optimisation purpose : read the DB only once
customer_2_id_dict = get_customer_email_2_id_dict()
ws = wb.worksheets[0]
error, error_msg = import_invoice_sheet(
ws, invoice_reference=invoice_reference,
......
......@@ -234,24 +234,24 @@ def export_purchase(permanence=None, year=None, producer=None, customer=None, wb
delta = 5