Commit 8ba5667f authored by Patrick's avatar Patrick

New version in progress

parent 02f2536b
from django import forms
from django.contrib.admin.widgets import AdminDateWidget
from django.forms.formsets import formset_factory
from django.utils.translation import ugettext_lazy as _
from djangocms_text_ckeditor.widgets import TextEditorWidget
from repanier.models import Producer
from repanier.const import REPANIER_MONEY_ZERO
from repanier.fields.RepanierMoneyField import FormMoneyField
......@@ -66,6 +66,21 @@ class PermanenceInvoicedForm(forms.Form):
self.fields['payment_date'].initial = self.payment_date
class ImportXlsxForm(forms.Form):
template = 'repanier/import_xlsx.html'
file_to_import = forms.FileField(label=_('File to import'), allow_empty_file=False)
class ImportInvoiceForm(ImportXlsxForm):
template = 'repanier/import_invoice_xlsx.html'
# Important : The length of invoice_reference must be the same as of permanence.short_name
invoice_reference = forms.CharField(label=_("invoice reference"), max_length=50, required=False)
producer = forms.ModelChoiceField(label=_('producer'), queryset=Producer.objects.filter(is_active=True).all(), required=False)
def __init__(self, *args, **kwargs):
super(ImportInvoiceForm, self).__init__(*args, **kwargs)
self.fields["invoice_reference"].widget.attrs['style'] = "width:450px !important"
class ProducerInvoicedForm(forms.Form):
selected = forms.BooleanField(required=False)
......
This diff is collapsed.
......@@ -18,6 +18,7 @@ from import_export.formats.base_formats import XLS
from import_export.widgets import CharWidget
import repanier.apps
from repanier.admin.forms import ImportXlsxForm
from repanier.models import BoxContent
from repanier.const import *
from repanier.models import Permanence, Product, \
......@@ -297,8 +298,9 @@ class ProducerAdmin(ImportExportMixin, admin.ModelAdmin):
export_xlsx_stock.short_description = _("Export stock to a xlsx file")
def import_xlsx_stock(self, request):
return import_xslx_view(self, admin, request, Producer.objects.all(), _("Import stock"), handle_uploaded_stock, action='import_xlsx_stock')
# return xlsx_stock.admin_import(self, admin, request, Producer.objects.all(), action='import_xlsx_stock')
return import_xslx_view(
self, admin, request, Producer.objects.all(), _("Import stock"), handle_uploaded_stock,
action='import_xlsx_stock', form_klass=ImportXlsxForm)
import_xlsx_stock.short_description = _("Import stock from a xlsx file")
......
......@@ -268,7 +268,8 @@ class ProductDataForm(TranslatableModelForm):
model = Product
fields = "__all__"
widgets = {
'order_unit' : SelectAdminOrderUnitWidget(),
'long_name' : forms.TextInput(attrs={'style': "width:450px !important"}),
'order_unit' : SelectAdminOrderUnitWidget(attrs={'style': "width:450px !important"}),
'department_for_customer': apply_select2(forms.Select),
}
......
......@@ -13,7 +13,7 @@ from django.http import HttpResponseRedirect
from django.utils import translation
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
from django.views.i18n import JavaScriptCatalog
# from django.views.i18n import JavaScriptCatalog
from easy_select2 import Select2
from import_export import resources, fields
from import_export.admin import ExportMixin
......
......@@ -61,6 +61,7 @@ PERMANENCE_WAIT_FOR_INVOICED = '600'
PERMANENCE_INVOICES_VALIDATION_FAILED = '700'
PERMANENCE_INVOICED = '800'
PERMANENCE_ARCHIVED = '900'
PERMANENCE_CANCELLED = '950'
LUT_PERMANENCE_STATUS = (
(PERMANENCE_DISABLED, _('disabled')),
......@@ -76,7 +77,8 @@ LUT_PERMANENCE_STATUS = (
(PERMANENCE_WAIT_FOR_INVOICED, _('wait for done')),
(PERMANENCE_INVOICES_VALIDATION_FAILED, _('invoices validation test failed')),
(PERMANENCE_INVOICED, _('invoiced')),
(PERMANENCE_ARCHIVED, _('archived'))
(PERMANENCE_ARCHIVED, _('archived')),
(PERMANENCE_CANCELLED, _('cancelled'))
)
PRODUCT_PLACEMENT_FREEZER = '100'
......
This diff is collapsed.
......@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: repanier\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2017-03-09 11:31+0100\n"
"PO-Revision-Date: 2017-03-09 17:48+0100\n"
"POT-Creation-Date: 2017-04-14 13:41+0200\n"
"PO-Revision-Date: 2017-04-15 08:56+0100\n"
"Last-Translator: Patrick Colmant <pcolmant@gmail.com>\n"
"Language-Team: Patrick Colmant <pcolmant@gmail.com>\n"
"Language: fr\n"
......@@ -26,6 +26,10 @@ msgstr "Exporter le stock"
msgid "Import stock"
msgstr "Importer le stock"
#: static/js/import_invoice.js:4
msgid "Import an invoice"
msgstr "Importer une facture"
#: static/js/is_order_confirm_send.js:4
msgid "✗🔓"
msgstr "✗🔓 - déverrouiller"
......
......@@ -29,6 +29,9 @@ class CustomerInvoice(models.Model):
customer = models.ForeignKey(
'Customer', verbose_name=_("customer"),
on_delete=models.PROTECT)
customer_charged = models.ForeignKey(
'Customer', verbose_name=_("customer"), related_name='invoices_paid', blank=True, null=True,
on_delete=models.PROTECT, db_index=True)
permanence = models.ForeignKey(
'Permanence', verbose_name=permanence_verbose_name(),
on_delete=models.PROTECT, db_index=True)
......@@ -109,10 +112,10 @@ class CustomerInvoice(models.Model):
help_text=_("This is the minimum order amount to avoid shipping cost."),
default=DECIMAL_ZERO, max_digits=5, decimal_places=2,
validators=[MinValueValidator(0)])
customer_charged = models.ForeignKey(
'Customer', verbose_name=_("customer"),
related_name='invoices_paid',
on_delete=models.PROTECT, db_index=True)
# customer_charged = models.ForeignKey(
# 'Customer', verbose_name=_("customer"),
# related_name='invoices_paid',
# on_delete=models.PROTECT, db_index=True)
master_permanence = models.ForeignKey(
'Permanence', verbose_name=_("master permanence"),
related_name='child_customer_invoice',
......
......@@ -46,8 +46,9 @@ class OfferItem(TranslatableModel):
'Permanence', verbose_name=REPANIER_SETTINGS_PERMANENCE_NAME, on_delete=models.PROTECT,
db_index=True
)
# Important : Check select_related
product = models.ForeignKey(
'Product', verbose_name=_("product"), on_delete=models.PROTECT)
'Product', verbose_name=_("product"), null=True, blank=True, default=None, on_delete=models.PROTECT)
picture2 = AjaxPictureField(
verbose_name=_("picture"),
null=True, blank=True,
......
......@@ -408,8 +408,6 @@ class Permanence(TranslatableModel):
update_fields=['status', 'is_updated_on', 'highest_status', 'payment_date'])
else:
self.save(update_fields=['status', 'is_updated_on', 'highest_status'])
menu_pool.clear()
cache.clear()
if new_status == PERMANENCE_WAIT_FOR_OPEN:
for a_producer in producer.Producer.objects.filter(
permanence=self.id
......
......@@ -4,6 +4,5 @@
$(".object-tools").prepend('<li><a href="./export_stock/' + location.search + '">' + gettext('Export stock')+ '</a></li>');
$(".object-tools").prepend('<li><a href="./import_stock/' + location.search + '">' + gettext('Import stock')+ '</a></li>');
}
// $(".object-tools").append('<li><a href="./is_order_confirm_send/' + location.search + '" class="addlink">&nbsp;&nbsp;🔐&nbsp;&nbsp;</a></li>');
});
})(django.jQuery);
(function($) {
$(document).ready(function($) {
if(location.pathname.indexOf('change') <= -1) {
$(".object-tools").append('<li><a href="./import_invoice/' + location.search + '">' + gettext('Import an invoice')+ '</a></li>');
}
});
})(django.jQuery);
......@@ -523,7 +523,16 @@ def generate_invoice(permanence, payment_date):
@transaction.atomic
def cancel(permanence):
def generate_archive(permanence):
permanence.set_status(PERMANENCE_ARCHIVED)
@transaction.atomic
def cancel_delivery(permanence):
permanence.set_status(PERMANENCE_CANCELLED)
@transaction.atomic
def cancel_invoice(permanence):
if permanence.status in [PERMANENCE_INVOICED, PERMANENCE_ARCHIVED]:
last_bank_account_total = BankAccount.objects.filter(
operation_status=BANK_LATEST_TOTAL, permanence_id=permanence.id
......@@ -649,16 +658,15 @@ def cancel(permanence):
permanence.set_status(PERMANENCE_SEND)
def admin_send(permanence_id):
if repanier.apps.REPANIER_SETTINGS_INVOICE:
thread.start_new_thread(email_invoice.send_invoice, (permanence_id,))
user_message = _("Emails containing the invoices will be send to the customers and the producers.")
user_message_level = messages.INFO
@transaction.atomic
def cancel_archive(permanence):
if BankAccount.objects.filter(
operation_status=BANK_LATEST_TOTAL, permanence_id=permanence.id
).order_by('?').exists():
# old archive
cancel_invoice(permanence)
else:
user_message = _("This action is not activated for your group.")
user_message_level = messages.ERROR
return user_message, user_message_level
permanence.set_status(PERMANENCE_SEND, allow_downgrade=True)
def admin_cancel(permanence):
......@@ -672,7 +680,7 @@ def admin_cancel(permanence):
if last_permanence_invoiced_id is not None:
if last_permanence_invoiced_id == permanence.id:
# This is well the latest closed permanence. The invoices can be cancelled without damages.
cancel(permanence)
cancel_invoice(permanence)
user_message = _("The selected invoice has been canceled.")
user_message_level = messages.INFO
else:
......@@ -685,8 +693,8 @@ def admin_cancel(permanence):
user_message = _("The selected invoice has been canceled.")
user_message_level = messages.INFO
permanence.set_status(PERMANENCE_SEND)
elif permanence.status == PERMANENCE_ARCHIVED:
cancel(permanence)
elif permanence.status in [PERMANENCE_ARCHIVED, PERMANENCE_CANCELLED]:
cancel_archive(permanence)
user_message = _("The selected invoice has been restored.")
user_message_level = messages.INFO
else:
......@@ -695,3 +703,16 @@ def admin_cancel(permanence):
user_message_level = messages.ERROR
return user_message, user_message_level
def admin_send(permanence):
if permanence.status == PERMANENCE_INVOICED:
thread.start_new_thread(email_invoice.send_invoice, (permanence.id,))
user_message = _("Emails containing the invoices will be send to the customers and the producers.")
user_message_level = messages.INFO
else:
user_message = _("The status of %(permanence)s prohibit you to send invoices.") % {
'permanence': permanence}
user_message_level = messages.ERROR
return user_message, user_message_level
\ No newline at end of file
......@@ -58,6 +58,7 @@ abbr, address, article, aside, audio, b, blockquote, body, canvas, caption, cite
{# ^^^^^^^^^^^ django cms admin style 1.2.6 #}
</style>
{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE" />{% endblock %}
<script type="text/javascript" src="{% url 'javascript-catalog' %}"></script>
</head>
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}"
data-admin-utc-offset="{% now "Z" %}">
......@@ -87,7 +88,7 @@ abbr, address, article, aside, audio, b, blockquote, body, canvas, caption, cite
{# {% block content_title %}{% if title %}<h1>{{ title }}</h1>{% endif %}{% endblock %}#}
{% block content %}
{% block object-tools %}<li><a href="https://repanier.be/fr/documentation/">' + gettext('Help')+ '</a></li>{% endblock %}
{% block object-tools %}{% endblock %}
{{ content }}
{% endblock %}
......
{% extends "admin/base_site.html" %}
{% load cms_tags menu_tags compress i18n l10n static %}
{% block content %}
<link rel="stylesheet" href="{% static "bootstrap/css/bootstrap.css" %}">
<link rel="stylesheet" href="{% static "css/custom.css" %}">
<style type="text/css">
.form-group input[type="checkbox"] {
display: none;
}
.form-group input[type="checkbox"] + .btn-group > label span {
width: 20px;
}
.form-group input[type="checkbox"] + .btn-group > label span:first-child {
display: none;
}
.form-group input[type="checkbox"] + .btn-group > label span:last-child {
display: inline-block;
}
.form-group input[type="checkbox"]:checked + .btn-group > label span:first-child {
display: inline-block;
}
.form-group input[type="checkbox"]:checked + .btn-group > label span:last-child {
display: none;
}
.colorgraph {
height: 5px;
border-top: 0;
background: #c4e17f;
border-radius: 5px;
background-image: -webkit-linear-gradient(left, #c4e17f, #62c2e4);
background-image: -moz-linear-gradient(left, #c4e17f, #62c2e4);
background-image: -o-linear-gradient(left, #c4e17f, #62c2e4);
background-image: linear-gradient(to right, #c4e17f, #62c2e4);
}
</style>
<h4>{{ sub_title }}</h4>
<p></p>
<form enctype="multipart/form-data" action="" method="post">{% csrf_token %}
<fieldset class="module aligned ">
<div class="form-group">
<b>{% trans "The importation concern :" %}</b> {% for object in queryset.all %}{{ object }}<input type="hidden" name="{{ action_checkbox_name }}" value="{{ object.id|unlocalize }}"/>{% if not forloop.last %}, {% endif %}{% endfor %}
<br/>
<label for="id_file_to_import"><b>{% trans "File to import :"%}</b></label><input id="id_file_to_import" name="file_to_import" type="file" />
</div>
<div class="form-group">
<div class="fieldWrapper">
{{ form.invoice_reference.errors }}
{{ form.invoice_reference.label_tag }}
{{ form.invoice_reference }}
</div>
</div>
<div class="form-group">
<div class="fieldWrapper">
{{ form.producer.errors }}
{{ form.producer.label_tag }}
{{ form.producer }}
</div>
</div>
</fieldset>
<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 "Execute the import" %}</h6></button>
</div>
<input type="hidden" name="action" value="{{ action }}"/>
</form>
{% endblock %}
......@@ -892,7 +892,7 @@ def update_or_create_purchase(customer=None, offer_item_id=None, q_order=None, v
if offer_item_id is not None and (q_order is not None or value_id is not None) and customer is not None:
offer_item = models.OfferItem.objects.select_for_update(nowait=False) \
.filter(id=offer_item_id, is_active=True, may_order=True) \
.order_by('?').select_related("product", "producer").first()
.order_by('?').select_related("producer").first()
if offer_item is not None:
if q_order is None:
# Transform value_id into a q_order.
......@@ -1391,7 +1391,7 @@ def clean_offer_item(permanence, queryset, reset_add_2_stock=False):
# The offer item may not be modified any more
return
getcontext().rounding = ROUND_HALF_UP
for offer_item in queryset.select_related("product", "producer"):
for offer_item in queryset.select_related("producer"):
product = offer_item.product
producer = offer_item.producer
if product.order_unit < PRODUCT_ORDER_UNIT_DEPOSIT:
......@@ -1445,7 +1445,7 @@ def clean_offer_item(permanence, queryset, reset_add_2_stock=False):
cur_language = translation.get_language()
for language in settings.PARLER_LANGUAGES[settings.SITE_ID]:
translation.activate(language["code"])
for offer_item in queryset.select_related("product", "producer", "department_for_customer"):
for offer_item in queryset.select_related("producer", "department_for_customer"):
offer_item.long_name = offer_item.product.long_name
offer_item.cache_part_a = render_to_string('repanier/cache_part_a.html',
{'offer': offer_item, 'MEDIA_URL': settings.MEDIA_URL})
......
......@@ -3,6 +3,7 @@ from django.conf import settings
from django.contrib.auth import views as auth_views
from django.contrib.auth.decorators import login_required
from django.views.decorators.cache import never_cache
# from django.views.i18n import JavaScriptCatalog
from picture.views import ajax_picture
from repanier.rest.lut import departments_for_customers_rest, department_for_customer_rest
......@@ -40,6 +41,7 @@ from repanier.views.send_mail_to_coordinators_view import send_mail_to_coordinat
from repanier.views.who_is_who_view import who_is_who_view
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
urlpatterns = [
url(r'^go_repanier/$', login_view, name='login_form'),
......@@ -127,6 +129,7 @@ urlpatterns = [
url(r'^members/$', send_mail_to_all_members_view, name='send_mail_to_all_members_view'),
url(r'^who/$', who_is_who_view, name='who_is_who_view'),
url(r'^me/$', me_view, name='me_view'),
# url(r'^jsi18n/$', JavaScriptCatalog.as_view(), name='javascript-catalog'),
url(r'^rest/permanences/$', permanences_rest, name='permanences_rest'),
url(r'^rest/permanence/(?P<permanence_id>\d+)/(?P<producer_name>.*)/(?P<reference>.*)/$',
permanence_producer_product_rest,
......@@ -143,4 +146,5 @@ urlpatterns = [
url(r'^rest/product/(?P<producer_short_profile_name>.*)/(?P<reference>.*)/$', product_rest,
name='product_rest'),
url(r'^rest/version/$', version_rest, name='version_rest'),
url(r'^ajax/dowload-customer-invoice/(?P<customer_invoice_id>\d+)/$', download_customer_invoice, name='download_customer_invoice'),
]
# -*- coding: utf-8
from __future__ import unicode_literals
from django.http import Http404
from django.http import HttpResponse
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.cache import never_cache
from django.views.decorators.http import require_GET
from repanier.apps import REPANIER_SETTINGS_GROUP_NAME
from repanier.models import CustomerInvoice
# from repanier.xlsx.xlsx_purchase import export_purchase
from repanier.xlsx.xlsx_invoice import export_invoice
@never_cache
@require_GET
def download_customer_invoice(request, customer_invoice_id):
user = request.user
if user.is_authenticated:
if user.is_staff or user.is_superuser:
customer_invoice = CustomerInvoice.objects.filter(
id=customer_invoice_id,
invoice_sort_order__isnull=False
).order_by('?').first()
else:
customer_invoice = CustomerInvoice.objects.filter(
customer__user_id=request.user.id,
id=customer_invoice_id,
invoice_sort_order__isnull=False
).order_by('?').first()
if customer_invoice is not None:
# wb = export_purchase(permanence=customer_invoice.permanence, customer=customer_invoice.customer, wb=None)
wb = export_invoice(
permanence=customer_invoice.permanence,
customer=customer_invoice.customer,
sheet_name=slugify(customer_invoice.permanence),
wb=None)
response = HttpResponse(
content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
response['Content-Disposition'] = "attachment; filename={0}-{1}.xlsx".format(
slugify(_("Accounting report")),
REPANIER_SETTINGS_GROUP_NAME
)
wb.save(response)
return response
raise Http404
......@@ -24,5 +24,4 @@ def is_into_offer(request, product_id):
'is_into_offer').first().is_into_offer)
Product.objects.filter(id=product_id).update(is_into_offer=is_into_offer)
return HttpResponse(mark_safe(_boolean_icon(is_into_offer)))
# return HttpResponse("Patrick")
raise Http404
......@@ -21,7 +21,7 @@ def like_ajax(request):
user = request.user
if user.is_authenticated:
offer_item_id = sint(request.GET.get('offer_item', 0))
offer_item = OfferItem.objects.filter(id=offer_item_id).order_by('?').select_related("product").first()
offer_item = OfferItem.objects.filter(id=offer_item_id).order_by('?').first()
if offer_item is not None and offer_item.product_id is not None:
product = offer_item.product
to_json = []
......
......@@ -67,8 +67,8 @@ def order_ajax(request):
else:
offer_item = OfferItem.objects.filter(
id=offer_item_id
).select_related(
"product"
# ).select_related(
# "product"
).order_by('?').first()
option_dict = display_selected_value(
offer_item,
......
......@@ -50,6 +50,14 @@ def get_customer_2_id_dict():
return represent_this_buyinggroup, customer_2_id_dict
def get_customer_email_2_id_dict():
customer_2_id_dict = {}
customer_set = Customer.objects.filter(is_active=True).order_by('?')
for customer in customer_set:
customer_2_id_dict[customer.user.email] = customer.id
return customer_2_id_dict
def get_producer_2_id_dict():
producer_2_id_dict = {}
represent_this_buyinggroup = None
......
......@@ -8,20 +8,15 @@ from django.shortcuts import render
from django.utils.translation import ugettext_lazy as _
class ImportXlsxForm(forms.Form):
file_to_import = forms.FileField(
label=_('File to import'),
allow_empty_file=False
)
def import_xslx_view(admin_ui, admin, request, queryset, sub_title, handle_uploaded_file, action):
def import_xslx_view(admin_ui, admin, request, queryset, sub_title, handle_uploaded_file, action, form_klass):
if 'apply' in request.POST:
form = ImportXlsxForm(request.POST, request.FILES)
form = form_klass(request.POST, request.FILES)
if form.is_valid():
file_to_import = request.FILES['file_to_import']
if ('.xlsx' in file_to_import.name) and (file_to_import.size <= 1000000):
error, error_msg = handle_uploaded_file(request, queryset, file_to_import)
producer = form.cleaned_data.get('producer')
invoice_reference = form.cleaned_data.get('invoice_reference')
error, error_msg = handle_uploaded_file(request, queryset, file_to_import, producer, invoice_reference)
if error:
if error_msg is None:
admin_ui.message_user(request,
......@@ -37,8 +32,8 @@ def import_xslx_view(admin_ui, admin, request, queryset, sub_title, handle_uploa
else:
admin_ui.message_user(request, _("Successfully imported %s.") % (file_to_import.name))
split_path = request.get_full_path().split('/')
if split_path[-2] == "import_stock":
return HttpResponseRedirect("/".join(request.get_full_path().split('/')[:-2]))
if len(split_path) == 7:
return HttpResponseRedirect("/".join(split_path[:-2]))
else:
admin_ui.message_user(request,
_(
......@@ -51,14 +46,17 @@ def import_xslx_view(admin_ui, admin, request, queryset, sub_title, handle_uploa
return HttpResponseRedirect(request.get_full_path())
elif 'cancel' in request.POST:
admin_ui.message_user(request, _("Action canceled by the user."), level=messages.INFO)
split_path = request.get_full_path().split('/')
if len(split_path) == 7:
return HttpResponseRedirect("/".join(split_path[:-2]))
return HttpResponseRedirect(request.get_full_path())
form = ImportXlsxForm(
form = form_klass(
initial={'_selected_action': request.POST.getlist(admin.ACTION_CHECKBOX_NAME)}
)
return render(request, 'repanier/import_xlsx.html', {
return render(request, form.template, {
'sub_title' : sub_title,
'queryset' : queryset,
'import_xlsx_form' : form,
'form' : form,
'action' : action,
'action_checkbox_name': admin.ACTION_CHECKBOX_NAME,
})
# -*- coding: utf-8
from __future__ import unicode_literals
from django.db import transaction
from django.http import HttpResponse
from django.utils import translation
from django.utils import translation, timezone
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
from openpyxl import load_workbook
from openpyxl.style import Border
from openpyxl.style import NumberFormat
......@@ -12,13 +14,15 @@ import repanier.apps
from export_tools import *
from repanier.models import Configuration
from repanier.const import *
from repanier.models import BankAccount, Purchase
from repanier.models import BankAccount, Permanence, Purchase
from repanier.models import Customer
from repanier.models import CustomerInvoice
from repanier.models import Producer
from repanier.models import ProducerInvoice
from repanier.tools import get_invoice_unit
from repanier.xlsx.xlsx_stock import export_permanence_stock
from repanier.xlsx.import_tools import get_customer_2_id_dict, get_producer_2_id_dict, get_customer_email_2_id_dict, \
get_header, get_row
def export_bank(permanence, wb=None, sheet_name=EMPTY_STRING):
......@@ -178,7 +182,7 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
hide_customer_prices = False
purchase_set = Purchase.objects.all().distinct()
if customer is not None:
purchase_set = purchase_set.filter(customer=customer)
purchase_set = purchase_set.filter(customer_charged=customer)
hide_producer_prices = True
if producer is not None:
purchase_set = purchase_set.filter(producer=producer)
......@@ -191,7 +195,7 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
if purchase_set.exists():
wb, ws = new_landscape_a4_sheet(wb, sheet_name, permanence)
row = []
row_num = 0
hide_column_deposit = True
......@@ -218,9 +222,9 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
False)]
if hide_producer_prices:
row += [
(EMPTY_STRING, 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False),
(EMPTY_STRING, 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False),
(EMPTY_STRING, 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False)
(_("Empty"), 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False),
(_("Empty"), 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False),
(_("Empty"), 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False)
]
else:
row += [
......@@ -235,9 +239,9 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
if hide_customer_prices:
row += [
(EMPTY_STRING, 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False),
(EMPTY_STRING, 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False),
(EMPTY_STRING, 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False)
(_("Empty"), 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False),
(_("Empty"), 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False),
(_("Empty"), 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False)
]
else:
row += [
......@@ -251,15 +255,17 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
]
if hide_producer_prices and hide_customer_prices:
row += [
(EMPTY_STRING, 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False)
(_("Empty"), 10, EMPTY_STRING, NumberFormat.FORMAT_TEXT, False)
]
else:
row += [
(EMPTY_STRING, 10, purchase.get_vat_level_display(), NumberFormat.FORMAT_TEXT, False)
(_("Vat"), 10, purchase.get_vat_level_display(), NumberFormat.FORMAT_TEXT, False)
]
row += [
(_("comment"), 30, EMPTY_STRING if purchase.comment is None else purchase.comment, NumberFormat.FORMAT_TEXT,
False),
(_("invoice_status"), 10, purchase.get_status_display(), NumberFormat.FORMAT_TEXT, False),
(_("CustId_02"), 10, purchase.customer.user.email, NumberFormat.FORMAT_TEXT, False),
]
if row_num == 0:
......@@ -282,7 +288,7 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
row_num += 1
if wb is not None and ws is not None:
if ws is not None:
if hide_column_deposit:
ws.column_dimensions[get_column_letter(8)].visible = False
if hide_producer_prices:
......@@ -295,7 +301,8 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
ws.column_dimensions[get_column_letter(14)].visible = False
if hide_producer_prices and hide_customer_prices:
ws.column_dimensions[get_column_letter(15)].visible = False
for col_num in range(15):
ws.column_dimensions[get_column_letter(18)].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
c.style.borders.bottom.border_style = Border.BORDER_THIN
......@@ -327,7 +334,7 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
group_label = config.group_label
if group_label:
row_num += 1
for col_num in range(15):
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
c.style.borders.bottom.border_style = Border.BORDER_THIN
......@@ -335,3 +342,74 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
c.value = group_label
c.style.font.bold = True
return wb
@transaction.atomic
def import_invoice_sheet(worksheet, invoice_reference=None,
customer_2_id_dict=None,
producer=None
):
error = False
error_msg = None
header = get_header(worksheet)
if header:
now = timezone.now().date()
import_counter = 0
row_num = 1
sid = transaction.savepoint()
try:
permanence = Permanence.objects.create(
permanence_date=now,
short_name=invoice_reference
)
permanence.producers.add(producer)
row = get_row(worksheet, header, row_num)
while row and not error:
customer_name = row[_("CustId_02")]
if customer_name:
if customer_name in customer_2_id_dict: