Commit 0157185d authored by Patrick's avatar Patrick

Work in progress

parent 8ba5667f
......@@ -119,7 +119,7 @@ class ProductFilterByVatLevel(SimpleListFilter):
def lookups(self, request, model_admin):
return [(p[0], p[1]) for p in
settings.LUT_VAT
LUT_ALL_VAT # settings.LUT_VAT
]
def queryset(self, request, queryset):
......
......@@ -51,7 +51,7 @@ class ProductResource(resources.ModelResource):
producer_unit_price = fields.Field(attribute='producer_unit_price', widget=TwoMoneysWidget())
customer_unit_price = fields.Field(attribute='customer_unit_price', widget=TwoMoneysWidget())
unit_deposit = fields.Field(attribute='unit_deposit', widget=TwoMoneysWidget())
vat_level = fields.Field(attribute='vat_level', widget=ChoiceWidget(settings.LUT_VAT, settings.LUT_VAT_REVERSE))
vat_level = fields.Field(attribute='vat_level', widget=ChoiceWidget(LUT_ALL_VAT, LUT_ALL_VAT_REVERSE))
customer_minimum_order_quantity = fields.Field(attribute='customer_minimum_order_quantity',
widget=ThreeDecimalsWidget())
customer_increment_order_quantity = fields.Field(attribute='customer_increment_order_quantity',
......@@ -507,10 +507,13 @@ class ProductAdmin(ImportExportMixin, TranslatableAdmin):
production_mode_field = form.base_fields["production_mode"]
picture_field = form.base_fields["picture2"]
order_unit_field = form.base_fields["order_unit"]
vat_level_field = form.base_fields["vat_level"]
producer_field.widget.can_add_related = False
producer_field.widget.can_delete_related = False
producer_field.widget.attrs['readonly'] = True
department_for_customer_field.widget.can_delete_related = False
# TODO : Make it dependent of the producer country
vat_level_field.widget.choices = settings.LUT_VAT
order_unit_choices = LUT_PRODUCT_ORDER_UNIT_WO_SUBSCRIPTION
if producer is not None:
......
......@@ -60,7 +60,7 @@ class PurchaseResource(resources.ModelResource):
producer_row_price = fields.Field(attribute='purchase_price', widget=TwoMoneysWidget(), readonly=True)
customer_row_price = fields.Field(attribute='selling_price', widget=TwoMoneysWidget(), readonly=True)
vat_level = fields.Field(attribute='offer_item__vat_level',
widget=ChoiceWidget(settings.LUT_VAT, settings.LUT_VAT_REVERSE), readonly=True)
widget=ChoiceWidget(LUT_ALL_VAT, LUT_ALL_VAT_REVERSE), readonly=True)
class Meta:
model = Purchase
......
......@@ -186,8 +186,6 @@ DICT_VAT_RATE = 1
DICT_VAT = {
VAT_100: (_('none'), DECIMAL_ZERO),
VAT_200: (_('compensation 2%'), DECIMAL_0_02),
VAT_300: (_('compensation 6%'), DECIMAL_0_06),
VAT_315: (_('vat 2.1%'), DECIMAL_0_021),
VAT_325: (_('vat 2.5%'), DECIMAL_0_025),
VAT_350: (_('vat 3.8%'), DECIMAL_0_038),
......@@ -201,6 +199,36 @@ DICT_VAT = {
VAT_600: (_('vat 21%'), DECIMAL_0_21),
}
LUT_ALL_VAT = (
(VAT_100, _('none')),
(VAT_315, _('vat 2.1%')),
(VAT_325, _('vat 2.5%')),
(VAT_350, _('vat 3.8%')),
(VAT_360, _('vat 4%')),
(VAT_375, _('vat 5.5%')),
(VAT_400, _('vat 6%')),
(VAT_430, _('vat 8%')),
(VAT_460, _('vat 10%')),
(VAT_500, _('vat 12%')),
(VAT_590, _('vat 20%')),
(VAT_600, _('vat 21%')),
)
LUT_ALL_VAT_REVERSE = (
(_('none'), VAT_100),
(_('vat 2.1%'), VAT_315),
(_('vat 2.5%'), VAT_325),
(_('vat 3.8%'), VAT_350),
(_('vat 4%'), VAT_360),
(_('vat 5.5%'), VAT_375),
(_('vat 6%'), VAT_400),
(_('vat 8%'), VAT_430),
(_('vat 10%'), VAT_460),
(_('vat 12%'), VAT_500),
(_('vat 20%'), VAT_590),
(_('vat 21%'), VAT_600),
)
BANK_NOT_LATEST_TOTAL = '100'
BANK_SUBSCRIPTION = '150'
BANK_COMPENSATION = '200' # BANK_COMPENSATION may occurs in previous release of Repanier
......
......@@ -48,7 +48,7 @@ class OfferItem(TranslatableModel):
)
# Important : Check select_related
product = models.ForeignKey(
'Product', verbose_name=_("product"), null=True, blank=True, default=None, on_delete=models.PROTECT)
'Product', verbose_name=_("product"), on_delete=models.PROTECT)
picture2 = AjaxPictureField(
verbose_name=_("picture"),
null=True, blank=True,
......@@ -102,7 +102,7 @@ class OfferItem(TranslatableModel):
default=DECIMAL_ZERO, max_digits=8, decimal_places=2)
vat_level = models.CharField(
max_length=3,
choices=settings.LUT_VAT,
choices=LUT_ALL_VAT, # settings.LUT_VAT,
default=settings.DICT_VAT_DEFAULT,
verbose_name=_("tax"))
......@@ -322,7 +322,7 @@ class OfferItem(TranslatableModel):
return '<span class="glyphicon glyphicon-heart%s" onclick="like_ajax(%d);return false;"></span>' % (
EMPTY_STRING if self.product.likes.filter(id=user.id).only("id").exists() else "-empty", self.id)
def get_order_name(self, is_quantity_invoiced=False, box_unicode=BOX_UNICODE):
def get_qty_display(self, is_quantity_invoiced=False, box_unicode=BOX_UNICODE):
if self.is_box:
# To avoid unicode error in email_offer.send_open_order
qty_display = box_unicode
......@@ -343,7 +343,27 @@ class OfferItem(TranslatableModel):
for_customer=False,
without_price_display=True
)
return '%s %s' % (self.long_name, qty_display)
return qty_display
def get_qty_and_price_display(self, is_quantity_invoiced=False, customer_price=True, box_unicode=BOX_UNICODE):
qty_display = self.get_qty_display(is_quantity_invoiced, box_unicode)
unit_price = self.get_unit_price(customer_price=customer_price)
if len(qty_display) > 0:
if self.unit_deposit.amount > DECIMAL_ZERO:
return '%s, %s + ♻ %s' % (
qty_display, unit_price, self.unit_deposit)
else:
return '%s, %s' % (qty_display, unit_price)
else:
if self.unit_deposit.amount > DECIMAL_ZERO:
return '%s + ♻ %s' % (
unit_price, self.unit_deposit)
else:
return '%s' % unit_price
def get_order_name(self, is_quantity_invoiced=False, box_unicode=BOX_UNICODE):
return '%s %s' % (self.long_name, self.get_qty_display(is_quantity_invoiced, box_unicode))
def get_long_name_with_producer_price(self):
return self.get_long_name(customer_price=False)
......@@ -352,31 +372,7 @@ class OfferItem(TranslatableModel):
get_long_name_with_producer_price.admin_order_field = 'translations__long_name'
def get_long_name(self, is_quantity_invoiced=False, customer_price=True, box_unicode=BOX_UNICODE):
if self.is_box:
# To avoid unicode error in email_offer.send_open_order
qty_display = box_unicode
else:
if is_quantity_invoiced and self.order_unit == PRODUCT_ORDER_UNIT_PC_KG:
qty_display = get_display(
qty=1,
order_average_weight=self.order_average_weight,
order_unit=PRODUCT_ORDER_UNIT_KG,
for_customer=False,
without_price_display=True
)
else:
qty_display = get_display(
qty=1,
order_average_weight=self.order_average_weight,
order_unit=self.order_unit,
for_customer=False,
without_price_display=True
)
unit_price = self.get_unit_price(customer_price=customer_price)
if self.unit_deposit.amount > DECIMAL_ZERO:
return '%s %s, %s + ♻ %s' % (self.long_name, qty_display, unit_price, self.unit_deposit)
else:
return '%s %s, %s' % (self.long_name, qty_display, unit_price)
return '%s %s' % (self.long_name, self.get_qty_and_price_display(is_quantity_invoiced, customer_price, box_unicode))
get_long_name.short_description = (_("long_name"))
get_long_name.allow_tags = False
......@@ -390,7 +386,6 @@ class OfferItem(TranslatableModel):
verbose_name_plural = _("offer's items")
unique_together = ("permanence", "product",)
index_together = [
# ["permanence", "product"],
["id", "order_unit"]
]
......
......@@ -80,7 +80,7 @@ class Product(TranslatableModel):
vat_level = models.CharField(
max_length=3,
choices=settings.LUT_VAT,
choices=LUT_ALL_VAT, # settings.LUT_VAT,
default=settings.DICT_VAT_DEFAULT,
verbose_name=_("tax"))
stock = models.DecimalField(
......@@ -132,8 +132,8 @@ class Product(TranslatableModel):
is_active = models.BooleanField(_("is_active"), default=True)
is_updated_on = models.DateTimeField(
_("is_updated_on"), auto_now=True, blank=True)
external_id_producer = models.BigIntegerField(null=True, blank=True, default=None)
external_id_product = models.BigIntegerField(null=True, blank=True, default=None)
# external_id_producer = models.BigIntegerField(null=True, blank=True, default=None)
# external_id_product = models.BigIntegerField(null=True, blank=True, default=None)
@property
def total_likes(self):
......@@ -233,11 +233,19 @@ class Product(TranslatableModel):
offer_price = self.get_unit_price()
return offer_price
def get_long_name(self, box_unicode=BOX_UNICODE, customer_price=True):
if self.id:
if self.is_box:
# To avoid unicode error when print
qty_display = box_unicode
def get_qty_display(self, is_quantity_invoiced=False, box_unicode=BOX_UNICODE):
if self.is_box:
# To avoid unicode error in email_offer.send_open_order
qty_display = box_unicode
else:
if is_quantity_invoiced and self.order_unit == PRODUCT_ORDER_UNIT_PC_KG:
qty_display = get_display(
qty=1,
order_average_weight=self.order_average_weight,
order_unit=PRODUCT_ORDER_UNIT_KG,
for_customer=False,
without_price_display=True
)
else:
qty_display = get_display(
qty=1,
......@@ -246,20 +254,27 @@ class Product(TranslatableModel):
for_customer=False,
without_price_display=True
)
unit_price = self.get_unit_price(customer_price=customer_price)
unit_deposit = self.unit_deposit
if len(qty_display) > 0:
if unit_deposit.amount > DECIMAL_ZERO:
return '%s %s, %s ♻ %s' % (self.long_name, qty_display, unit_price, unit_deposit)
else:
return '%s %s, %s' % (self.long_name, qty_display, unit_price)
return qty_display
def get_qty_and_price_display(self, is_quantity_invoiced=False, customer_price=True, box_unicode=BOX_UNICODE):
qty_display = self.get_qty_display(is_quantity_invoiced, box_unicode)
unit_price = self.get_unit_price(customer_price=customer_price)
if len(qty_display) > 0:
if self.unit_deposit.amount > DECIMAL_ZERO:
return '%s, %s + ♻ %s' % (
qty_display, unit_price, self.unit_deposit)
else:
if unit_deposit.amount > DECIMAL_ZERO:
return '%s, %s ♻ %s' % (self.long_name, unit_price, unit_deposit)
else:
return '%s, %s' % (self.long_name, unit_price)
return '%s, %s' % (qty_display, unit_price)
else:
raise AttributeError
if self.unit_deposit.amount > DECIMAL_ZERO:
return '%s + ♻ %s' % (
unit_price, self.unit_deposit)
else:
return '%s' % unit_price
def get_long_name(self, is_quantity_invoiced=False, customer_price=True, box_unicode=BOX_UNICODE):
return '%s %s' % (
self.long_name, self.get_qty_and_price_display(is_quantity_invoiced, customer_price, box_unicode))
get_long_name.short_description = (_("long_name"))
get_long_name.allow_tags = True
......
......@@ -96,7 +96,7 @@ class Purchase(models.Model):
vat_level = models.CharField(
max_length=3,
choices=settings.LUT_VAT,
choices=LUT_ALL_VAT, # settings.LUT_VAT,
default=settings.DICT_VAT_DEFAULT,
verbose_name=_("tax"))
......
......@@ -379,14 +379,16 @@ def close_order_delivery(permanence, delivery, all_producers, producers_id=None)
for offer_item in OfferItem.objects.filter(permanence_id=permanence.id, # is_active=False,
order_unit=PRODUCT_ORDER_UNIT_DEPOSIT).order_by('?'):
permanence.producers.add(offer_item.producer_id)
create_or_update_one_purchase(customer, offer_item, q_order=1, batch_job=True, is_box_content=False)
create_or_update_one_purchase(customer, offer_item, q_order=0, batch_job=True, is_box_content=False)
create_or_update_one_purchase(customer.id, offer_item, q_order=1, permanence_date=permanence.permanence_date, batch_job=True, is_box_content=False)
create_or_update_one_purchase(customer.id, offer_item, q_order=0, permanence_date=permanence.permanence_date, batch_job=True, is_box_content=False)
# 4 - Add Membership fee Subscription
if repanier.apps.REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION > 0:
# There is a membership fee
if customer.membership_fee_valid_until < today:
permanence.producers.add(membership_fee_offer_item.producer_id)
create_or_update_one_purchase(customer, membership_fee_offer_item, q_order=1, batch_job=True,
create_or_update_one_purchase(customer.id, membership_fee_offer_item, q_order=1,
permanence_date=permanence.permanence_date,
batch_job=True,
is_box_content=False)
customer.membership_fee_valid_until = add_months(
customer.membership_fee_valid_until,
......@@ -400,7 +402,9 @@ def close_order_delivery(permanence, delivery, all_producers, producers_id=None)
for customer in Customer.objects.filter(is_active=True, may_order=True,
represent_this_buyinggroup=False).order_by('?'):
permanence.producers.add(offer_item.producer_id)
create_or_update_one_purchase(customer, offer_item, q_order=1, batch_job=True, is_box_content=False)
create_or_update_one_purchase(customer.id, offer_item, q_order=1,
permanence_date=permanence.permanence_date,
batch_job=True, is_box_content=False)
delivery.set_status(PERMANENCE_CLOSED, all_producers, producers_id)
......@@ -471,7 +475,9 @@ def close_order(permanence, all_producers, producers_id=None):
offer_item_qs = offer_item_qs.filter(producer_id__in=producers_id)
for offer_item in offer_item_qs:
buying_group = Customer.objects.filter(is_active=True, represent_this_buyinggroup=True).order_by('?').first()
create_or_update_one_purchase(buying_group, offer_item, q_order=1, batch_job=True, is_box_content=False)
create_or_update_one_purchase(buying_group.id, offer_item, q_order=1,
permanence_date=permanence.permanence_date,
batch_job=True, is_box_content=False)
membership_fee_product = Product.objects.filter(is_membership_fee=True, is_active=True).order_by('?').first()
membership_fee_product.producer_unit_price = repanier.apps.REPANIER_SETTINGS_MEMBERSHIP_FEE
# Update the prices
......@@ -495,14 +501,14 @@ def close_order(permanence, all_producers, producers_id=None):
if not all_producers:
offer_item_qs = offer_item_qs.filter(producer_id__in=producers_id)
for offer_item in offer_item_qs:
create_or_update_one_purchase(customer, offer_item, q_order=1, batch_job=True, is_box_content=False)
create_or_update_one_purchase(customer, offer_item, q_order=0, batch_job=True, is_box_content=False)
create_or_update_one_purchase(customer.id, offer_item, q_order=1, permanence_date=permanence.permanence_date, batch_job=True, is_box_content=False)
create_or_update_one_purchase(customer.id, offer_item, q_order=0, permanence_date=permanence.permanence_date, batch_job=True, is_box_content=False)
# 4 - Add Add Membership fee Subscription
if repanier.apps.REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION > 0:
# There is a membership fee
if customer.membership_fee_valid_until < today:
permanence.producers.add(membership_fee_offer_item.producer_id)
create_or_update_one_purchase(customer, membership_fee_offer_item, q_order=1, batch_job=True, is_box_content=False)
create_or_update_one_purchase(customer.id, membership_fee_offer_item, q_order=1, permanence_date=permanence.permanence_date, batch_job=True, is_box_content=False)
while customer.membership_fee_valid_until < today:
# Do not pay the membership fee if no order passed during a certain amount of time
customer.membership_fee_valid_until = add_months(
......@@ -522,7 +528,7 @@ def close_order(permanence, all_producers, producers_id=None):
represent_this_buyinggroup=False
).order_by('?'):
permanence.producers.add(offer_item.producer_id)
create_or_update_one_purchase(customer, offer_item, q_order=1, batch_job=True, is_box_content=False)
create_or_update_one_purchase(customer.id, offer_item, q_order=1, permanence_date=permanence.permanence_date, batch_job=True, is_box_content=False)
# Disable subscription for next permanence
Product.objects.filter(
order_unit=PRODUCT_ORDER_UNIT_SUBSCRIPTION, is_into_offer=True, is_membership_fee=False
......
......@@ -346,6 +346,17 @@ def get_invoice_unit(order_unit=PRODUCT_ORDER_UNIT_PC, qty=0):
return unit
def get_reverse_invoice_unit(unit):
# reverse of tools get_invoice_unit
if unit == _("/ kg"):
order_unit = PRODUCT_ORDER_UNIT_KG
elif unit == _("/ l"):
order_unit = PRODUCT_ORDER_UNIT_LT
else:
order_unit = PRODUCT_ORDER_UNIT_PC
return order_unit
def get_preparator_unit(order_unit=PRODUCT_ORDER_UNIT_PC):
# Used when producing the preparation list.
if order_unit in [PRODUCT_ORDER_UNIT_PC, PRODUCT_ORDER_UNIT_PC_PRICE_KG, PRODUCT_ORDER_UNIT_PC_PRICE_LT,
......@@ -956,7 +967,7 @@ 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, 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
......@@ -993,7 +1004,7 @@ def update_or_create_purchase(customer=None, offer_item_id=None, q_order=None, v
transaction.savepoint_rollback(sid)
if not offer_item.is_box or updated:
purchase, updated = create_or_update_one_purchase(
customer, offer_item, q_order=q_order, batch_job=batch_job,
customer.id, offer_item, q_order=q_order, batch_job=batch_job,
is_box_content=False
)
if not batch_job and apps.REPANIER_SETTINGS_DISPLAY_PRODUCER_ON_ORDER_FORM:
......@@ -1292,42 +1303,45 @@ def my_order_confirmation_email_send_to(customer):
return msg_confirmation
def create_or_update_one_purchase(customer, offer_item, 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):
# 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
# when the status is PERMANENCE_WAIT_FOR_SEND
purchase = models.Purchase.objects.filter(
customer_id=customer.id,
customer_id=customer_id,
offer_item_id=offer_item.id,
is_box_content=is_box_content
).order_by('?').first()
if batch_job:
if purchase is None:
permanence = models.Permanence.objects.filter(id=offer_item.permanence_id) \
.only("permanence_date") \
.order_by('?').first()
permanence_date = permanence_date or models.Permanence.objects.filter(
id=offer_item.permanence_id).only("permanence_date").order_by('?').first().permanence_date
purchase = models.Purchase.objects.create(
permanence_id=offer_item.permanence_id,
permanence_date=permanence.permanence_date,
permanence_date=permanence_date,
offer_item_id=offer_item.id,
producer_id=offer_item.producer_id,
customer_id=customer.id,
quantity_ordered=q_order,
quantity_invoiced=DECIMAL_ZERO,
customer_id=customer_id,
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=PERMANENCE_OPENED
status=status
)
if q_order == DECIMAL_ZERO:
purchase.comment = _("Cancelled qty : %s") % number_format(purchase.quantity_ordered, 4)
purchase.quantity_ordered = q_order
purchase.save()
else:
if status < PERMANENCE_SEND:
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
purchase.save()
return purchase, True
else:
permanence_is_opened = models.CustomerInvoice.objects.filter(
permanence_id=offer_item.permanence_id,
customer_id=customer.id,
status=PERMANENCE_OPENED
customer_id=customer_id,
status=status
).order_by('?').exists()
if permanence_is_opened:
if offer_item.limit_order_quantity_to_stock:
......@@ -1339,7 +1353,7 @@ def create_or_update_one_purchase(customer, offer_item, q_order=None, batch_job=
if is_box_content and q_alert < q_order:
# Select one purchase
non_box_purchase = models.Purchase.objects.filter(
customer_id=customer.id,
customer_id=customer_id,
offer_item_id=offer_item.id,
is_box_content=False
).order_by('?').first()
......@@ -1373,11 +1387,11 @@ def create_or_update_one_purchase(customer, offer_item, q_order=None, batch_job=
permanence_date=permanence.permanence_date,
offer_item_id=offer_item.id,
producer_id=offer_item.producer_id,
customer_id=customer.id,
customer_id=customer_id,
quantity_ordered=q_order,
quantity_invoiced=DECIMAL_ZERO,
is_box_content=is_box_content,
status=PERMANENCE_OPENED
status=status
)
return purchase, True
else:
......@@ -1574,6 +1588,7 @@ def update_offer_item(product_id=None, producer_id=None):
cache.clear()
@transaction.atomic()
def get_or_create_offer_item(permanence, product_id, producer_id=None):
offer_item_qs = models.OfferItem.objects.filter(
permanence_id=permanence.id,
......
# -*- coding: utf-8
from __future__ import unicode_literals
from django.conf import settings
from django.db import transaction
from django.http import HttpResponse
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
......@@ -14,14 +13,14 @@ import repanier.apps
from export_tools import *
from repanier.models import Configuration
from repanier.const import *
from repanier.models import BankAccount, Permanence, Purchase
from repanier.models import BankAccount, Permanence, Product, 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, \
from repanier.tools import get_invoice_unit, get_reverse_invoice_unit, get_or_create_offer_item, \
create_or_update_one_purchase
from repanier.xlsx.import_tools import get_customer_email_2_id_dict, \
get_header, get_row
......@@ -259,13 +258,14 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
]
else:
row += [
(_("Vat"), 10, purchase.get_vat_level_display(), NumberFormat.FORMAT_TEXT, False)
(_("Vat level"), 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),
(_("customer"), 10, purchase.customer.user.email, NumberFormat.FORMAT_TEXT, False),
(_("reference"), 10, purchase.offer_item.reference, NumberFormat.FORMAT_TEXT, False),
]
if row_num == 0:
......@@ -302,6 +302,7 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
if hide_producer_prices and hide_customer_prices:
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
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
......@@ -354,6 +355,7 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
header = get_header(worksheet)
if header:
now = timezone.now().date()
lut_reverse_vat = dict(LUT_ALL_VAT_REVERSE)
import_counter = 0
row_num = 1
sid = transaction.savepoint()
......@@ -361,12 +363,14 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
permanence = Permanence.objects.create(
permanence_date=now,
short_name=invoice_reference
short_name=invoice_reference,
status=PERMANENCE_SEND,
highest_status=PERMANENCE_SEND
)
permanence.producers.add(producer)
row = get_row(worksheet, header, row_num)
while row and not error:
customer_name = row[_("CustId_02")]
customer_name = row[_("customer")]
if customer_name:
if customer_name in customer_2_id_dict:
customer_id = customer_2_id_dict[customer_name]
......@@ -374,7 +378,32 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
error = True
error_msg = _("Row %(row_num)d : No valid customer") % {'row_num': row_num + 1}
break
product_reference = row[_("reference")]
unit = row[_("Unit")]
order_unit = get_reverse_invoice_unit(unit)
vat = row[_("Vat level")]
vat_level = lut_reverse_vat[vat]
product = Product.objects.filter(producer_id=producer.id, reference=product_reference).order_by('?').first()
if product is None:
product = Product.objects.create(
producer=producer,
reference=product_reference,
)
product.long_name = row[_("Product")]
product.order_unit = order_unit
product.vat_level = vat_level
product.save()
qty_and_price_display = product.get_qty_and_price_display()
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)
import_counter += 1
row_num += 1
row = get_row(worksheet, header, row_num)
......@@ -391,6 +420,8 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
error_msg = "%s" % _("Nothing to import.")
if error:
transaction.savepoint_rollback(sid)
else:
transaction.savepoint_commit(sid)
return error, error_msg
......
......@@ -2,9 +2,7 @@
from __future__ import unicode_literals
from django.db import transaction
from django.http import HttpResponse
from django.utils import translation
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
from openpyxl import load_workbook
from openpyxl.style import Fill
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment