Commit 39d8ee76 authored by Patrick's avatar Patrick

Code refactoring

parent e6d746f4
......@@ -18,7 +18,6 @@ from repanier.admin.fkey_choice_cache_mixin import ForeignKeyCacheMixin
from repanier.const import *
from repanier.fields.RepanierMoneyField import FormMoneyField, RepanierMoney
from repanier.models import Customer, Permanence, Product, LUT_DepartmentForCustomer, Purchase, OfferItem
from repanier.tools import recalculate_order_amount
class OfferItemPurchaseSendInlineFormSet(BaseInlineFormSet):
......@@ -408,9 +407,7 @@ class OfferItemSendAdmin(admin.ModelAdmin):
purchase_form.instance.save_box()
# Important : linked with ^^^^^
recalculate_order_amount(
permanence_id=offer_item.permanence_id,
offer_item.permanence.recalculate_order_amount(
offer_item_qs=OfferItem.objects.filter(id=offer_item.id).order_by('?')
)
......
......@@ -98,7 +98,7 @@ def send_invoice(permanence_id):
'invoice_customer_mail', any_language=True, default=EMPTY_STRING
)
invoice_customer_mail_subject = "%s - %s" % (REPANIER_SETTINGS_GROUP_NAME, permanence)
customer_last_balance, customer_on_hold_movement, customer_payment_needed, customer_order_amount = payment_message(
customer_last_balance, _, customer_payment_needed, customer_order_amount = payment_message(
customer, permanence)
template = Template(invoice_customer_mail)
context = TemplateContext({
......
......@@ -317,7 +317,7 @@ def export_order_2_1_customer(customer, filename, permanence, sender_email, send
settings.ALLOWED_HOSTS[0], reverse('customer_invoice_view', args=(0,)), customer_last_balance)),
'last_balance' : mark_safe(customer_last_balance),
'order_amount' : mark_safe(customer_order_amount),
'on_hold_movement' : mark_safe(customer_on_hold_movement),
'on_hold_movement' : customer_on_hold_movement,
'payment_needed' : mark_safe(customer_payment_needed),
'delivery_point' : delivery_point,
'signature' : mark_safe(
......
......@@ -2,18 +2,13 @@
from django.utils import timezone
import datetime
from django.core.management.base import BaseCommand, CommandError
from django.utils.text import slugify
from django.utils.translation import ugettext_lazy as _
from django.core.management.base import BaseCommand
from repanier.const import PERMANENCE_OPENED, DECIMAL_ZERO
from repanier.email.email_order import export_order_2_1_customer
from repanier.models import Permanence, CustomerInvoice, Purchase
from repanier.models import Permanence, CustomerInvoice
from django.conf import settings
from django.utils import translation
from repanier.tools import update_or_create_purchase, get_signature
class Command(BaseCommand):
args = '<none>'
......
# -*- coding: utf-8 -*-
from django.core.management.base import BaseCommand
from repanier.models import BankAccount
from repanier.models import LUT_DeliveryPoint, DeliveryBoard
from repanier.models import CustomerInvoice, ProducerInvoice
from repanier.const import PERMANENCE_CLOSED, \
PERMANENCE_INVOICED, PERMANENCE_ARCHIVED, PERMANENCE_SEND
from repanier.models import Permanence
from repanier.tools import reorder_offer_items, recalculate_order_amount
from repanier.task import task_invoice
class Command(BaseCommand):
......@@ -17,10 +11,11 @@ class Command(BaseCommand):
help = 'Recalculate order amount'
def handle(self, *args, **options):
recalculate_order_amount(
permanence_id=229,
re_init=True
)
for permanence in Permanence.objects.filter(
id=229
).order_by('permanence_date'):
print ("Cancel %s %s" % (permanence.permanence_date, permanence.get_status_display()))
permanence.recalculate_order_amount(re_init=True)
# latest_total = BankAccount.objects.filter(
# producer__isnull=True,
......
......@@ -2,7 +2,6 @@
from django.core.management.base import BaseCommand
from repanier.const import PERMANENCE_CLOSED
from repanier.models import Permanence
from repanier.tools import recalculate_order_amount
class Command(BaseCommand):
......
......@@ -12,6 +12,7 @@ from django.db.models.signals import post_delete, pre_save
from django.dispatch import receiver
from django.utils import timezone
from django.utils.encoding import python_2_unicode_compatible
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
import bankaccount
......@@ -129,6 +130,8 @@ class Customer(models.Model):
get_admin_balance.allow_tags = False
def get_order_not_invoiced(self):
from repanier.apps import REPANIER_SETTINGS_INVOICE
if REPANIER_SETTINGS_INVOICE:
result_set = invoice.CustomerInvoice.objects.filter(
customer_id=self.id,
status__gte=PERMANENCE_OPENED,
......@@ -143,9 +146,13 @@ class Customer(models.Model):
order_not_invoiced += RepanierMoney(result_set["delta_price_with_tax__sum"])
if result_set["delta_transport__sum"] is not None:
order_not_invoiced += RepanierMoney(result_set["delta_transport__sum"])
else:
order_not_invoiced = REPANIER_MONEY_ZERO
return order_not_invoiced
def get_bank_not_invoiced(self):
from repanier.apps import REPANIER_SETTINGS_INVOICE
if REPANIER_SETTINGS_INVOICE:
result_set = bankaccount.BankAccount.objects.filter(
customer_id=self.id, customer_invoice__isnull=True
).order_by('?').aggregate(Sum('bank_amount_in'), Sum('bank_amount_out'))
......@@ -158,6 +165,8 @@ class Customer(models.Model):
else:
bank_out = REPANIER_MONEY_ZERO
bank_not_invoiced = bank_in - bank_out
else:
bank_not_invoiced = REPANIER_MONEY_ZERO
return bank_not_invoiced
def get_balance(self):
......@@ -190,6 +199,43 @@ class Customer(models.Model):
get_balance.allow_tags = True
get_balance.admin_order_field = 'balance'
def get_on_hold_movement_html(self, bank_not_invoiced=None, order_not_invoiced=None, total_price_with_tax=REPANIER_MONEY_ZERO):
from repanier.apps import REPANIER_SETTINGS_INVOICE
if REPANIER_SETTINGS_INVOICE:
bank_not_invoiced = bank_not_invoiced if bank_not_invoiced is not None else self.get_bank_not_invoiced()
order_not_invoiced = order_not_invoiced if order_not_invoiced is not None else self.get_order_not_invoiced()
other_order_not_invoiced = order_not_invoiced - total_price_with_tax
else:
bank_not_invoiced = REPANIER_MONEY_ZERO
other_order_not_invoiced = REPANIER_MONEY_ZERO
if other_order_not_invoiced.amount != DECIMAL_ZERO or bank_not_invoiced.amount != DECIMAL_ZERO:
if other_order_not_invoiced.amount != DECIMAL_ZERO:
if bank_not_invoiced.amount == DECIMAL_ZERO:
customer_on_hold_movement = \
_('This balance does not take account of any unbilled sales %(other_order)s.') % {
'other_order': other_order_not_invoiced
}
else:
customer_on_hold_movement = \
_(
'This balance does not take account of any unrecognized payments %(bank)s and any unbilled order %(other_order)s.') \
% {
'bank' : bank_not_invoiced,
'other_order': other_order_not_invoiced
}
else:
customer_on_hold_movement = \
_(
'This balance does not take account of any unrecognized payments %(bank)s.') % {
'bank': bank_not_invoiced
}
customer_on_hold_movement = mark_safe(customer_on_hold_movement)
else:
customer_on_hold_movement = EMPTY_STRING
return customer_on_hold_movement
def get_last_membership_fee(self):
last_membership_fee = purchase.Purchase.objects.filter(
customer_id=self.id,
......
......@@ -17,7 +17,7 @@ import purchase
from repanier.apps import DJANGO_IS_MIGRATION_RUNNING
from repanier.const import *
from repanier.fields.RepanierMoneyField import ModelMoneyField
from repanier.tools import update_or_create_purchase, get_signature
from repanier.tools import create_or_update_one_cart_item, get_signature
def permanence_verbose_name():
......@@ -416,7 +416,7 @@ class CustomerInvoice(Invoice):
is_box_content=False,
).order_by('?')
for a_purchase in purchase_qs.select_related("customer"):
update_or_create_purchase(
create_or_update_one_cart_item(
customer=a_purchase.customer,
offer_item_id=a_purchase.offer_item_id,
q_order=DECIMAL_ZERO,
......@@ -484,6 +484,23 @@ class ProducerInvoice(Invoice):
def get_total_deposit(self):
return self.total_deposit + self.delta_stock_deposit
def get_order_json(self, to_json):
producer = self.producer
if producer.minimum_order_value.amount > DECIMAL_ZERO:
ratio = self.total_price_with_tax.amount / producer.minimum_order_value.amount
if ratio >= DECIMAL_ONE:
ratio = 100
else:
ratio *= 100
option_dict = {'id' : "#order_procent%d" % producer.id,
'html': "%s%%" % number_format(ratio, 0)}
to_json.append(option_dict)
if self.status != PERMANENCE_OPENED:
option_dict = {'id' : "#order_closed%d" % producer.id,
'html': '&nbsp;<span class="glyphicon glyphicon-ban-circle" aria-hidden="true"></span>'}
to_json.append(option_dict)
return
def __str__(self):
return '%s, %s' % (self.producer, self.permanence)
......
......@@ -18,6 +18,7 @@ from parler.models import TranslatableModel, TranslatedFields, TranslationDoesNo
import customer
import deliveryboard
import invoice
import offeritem
import permanenceboard
import producer
import purchase
......@@ -599,6 +600,88 @@ class Permanence(TranslatableModel):
cur_language=translation.get_language(),
)
def recalculate_order_amount(self,
offer_item_qs=None,
re_init=False,
send_to_producer=False):
getcontext().rounding = ROUND_HALF_UP
if send_to_producer or re_init:
assert offer_item_qs is None, 'offer_item_qs must be set to None when send_to_producer or re_init'
invoice.ProducerInvoice.objects.filter(
permanence_id=self.id
).update(
total_price_with_tax=DECIMAL_ZERO,
total_vat=DECIMAL_ZERO,
total_deposit=DECIMAL_ZERO,
)
invoice.CustomerInvoice.objects.filter(
permanence_id=self.id
).update(
total_price_with_tax=DECIMAL_ZERO,
total_vat=DECIMAL_ZERO,
total_deposit=DECIMAL_ZERO
)
invoice.CustomerProducerInvoice.objects.filter(
permanence_id=self.id
).update(
total_purchase_with_tax=DECIMAL_ZERO,
total_selling_with_tax=DECIMAL_ZERO
)
offeritem.OfferItem.objects.filter(
permanence_id=self.id
).update(
quantity_invoiced=DECIMAL_ZERO,
total_purchase_with_tax=DECIMAL_ZERO,
total_selling_with_tax=DECIMAL_ZERO
)
self.total_purchase_with_tax=DECIMAL_ZERO
self.total_selling_with_tax=DECIMAL_ZERO
self.total_purchase_vat=DECIMAL_ZERO
self.total_selling_vat=DECIMAL_ZERO
for offer_item in offeritem.OfferItem.objects.filter(
permanence_id=self.id,
is_active=True,
manage_replenishment=True
).exclude(add_2_stock=DECIMAL_ZERO).order_by('?'):
# Recalculate the total_price_with_tax of ProducerInvoice and
# the total_purchase_with_tax of OfferItem
# taking into account "add_2_stock"
offer_item.previous_add_2_stock = DECIMAL_ZERO
offer_item.save()
if offer_item_qs is not None:
purchase_set = purchase.Purchase.objects \
.filter(permanence_id=self.id, offer_item__in=offer_item_qs) \
.order_by('?')
else:
purchase_set = purchase.Purchase.objects \
.filter(permanence_id=self.id) \
.order_by('?')
for a_purchase in purchase_set.select_related("offer_item"):
# Recalculate the total_price_with_tax of ProducerInvoice,
# the total_price_with_tax of CustomerInvoice,
# the total_purchase_with_tax + total_selling_with_tax of CustomerProducerInvoice,
# and quantity_invoiced + total_purchase_with_tax + total_selling_with_tax of OfferItem
if send_to_producer or re_init:
a_purchase.previous_quantity_ordered = DECIMAL_ZERO
a_purchase.previous_quantity_invoiced = DECIMAL_ZERO
a_purchase.previous_purchase_price = DECIMAL_ZERO
a_purchase.previous_selling_price = DECIMAL_ZERO
a_purchase.previous_producer_vat = DECIMAL_ZERO
a_purchase.previous_customer_vat = DECIMAL_ZERO
a_purchase.previous_deposit = DECIMAL_ZERO
if send_to_producer:
offer_item = a_purchase.offer_item
if offer_item.order_unit == PRODUCT_ORDER_UNIT_PC_KG:
a_purchase.quantity_invoiced = (a_purchase.quantity_ordered * offer_item.order_average_weight) \
.quantize(FOUR_DECIMALS)
else:
a_purchase.quantity_invoiced = a_purchase.quantity_ordered
a_purchase.save()
self.save()
def recalculate_profit(self):
getcontext().rounding = ROUND_HALF_UP
......
......@@ -16,6 +16,7 @@ from django.db.models.signals import pre_save
from django.dispatch import receiver
from django.utils.encoding import python_2_unicode_compatible
from django.utils.formats import number_format
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
import bankaccount
......@@ -141,6 +142,8 @@ class Producer(models.Model):
get_admin_balance.allow_tags = False
def get_order_not_invoiced(self):
from repanier.apps import REPANIER_SETTINGS_INVOICE
if REPANIER_SETTINGS_INVOICE:
result_set = invoice.ProducerInvoice.objects.filter(
producer_id=self.id,
status__gte=PERMANENCE_OPENED,
......@@ -154,9 +157,13 @@ class Producer(models.Model):
order_not_invoiced += RepanierMoney(result_set["delta_price_with_tax__sum"])
if result_set["delta_transport__sum"] is not None:
order_not_invoiced += RepanierMoney(result_set["delta_transport__sum"])
else:
order_not_invoiced = REPANIER_MONEY_ZERO
return order_not_invoiced
def get_bank_not_invoiced(self):
from repanier.apps import REPANIER_SETTINGS_INVOICE
if REPANIER_SETTINGS_INVOICE:
result_set = bankaccount.BankAccount.objects.filter(
producer_id=self.id, producer_invoice__isnull=True
).order_by('?').aggregate(Sum('bank_amount_in'), Sum('bank_amount_out'))
......@@ -169,6 +176,9 @@ class Producer(models.Model):
else:
bank_out = REPANIER_MONEY_ZERO
bank_not_invoiced = bank_in - bank_out
else:
bank_not_invoiced = REPANIER_MONEY_ZERO
return bank_not_invoiced
def get_calculated_invoiced_balance(self, permanence_id):
......@@ -265,8 +275,10 @@ class Producer(models.Model):
get_balance.admin_order_field = 'balance'
def get_last_invoice(self):
producer_last_invoice = invoice.ProducerInvoice.objects.filter(producer_id=self.id).order_by("-id").first()
if producer_last_invoice:
producer_last_invoice = invoice.ProducerInvoice.objects.filter(
producer_id=self.id, invoice_sort_order__isnull=False
).order_by("-id").first()
if producer_last_invoice is not None:
if producer_last_invoice.total_price_with_tax < DECIMAL_ZERO:
return '<span style="color:#298A08">%s</span>' % (
number_format(producer_last_invoice.total_price_with_tax, 2))
......@@ -285,6 +297,36 @@ class Producer(models.Model):
get_last_invoice.short_description = _("last invoice")
get_last_invoice.allow_tags = True
def get_on_hold_movement_json(self, to_json):
bank_not_invoiced = self.get_bank_not_invoiced()
order_not_invoiced = self.get_order_not_invoiced()
if order_not_invoiced.amount != DECIMAL_ZERO or bank_not_invoiced.amount != DECIMAL_ZERO:
if order_not_invoiced.amount != DECIMAL_ZERO:
if bank_not_invoiced.amount == DECIMAL_ZERO:
producer_on_hold_movement = \
_('This balance does not take account of any unbilled sales %(other_order)s.') % {
'other_order': order_not_invoiced
}
else:
producer_on_hold_movement = \
_(
'This balance does not take account of any unrecognized payments %(bank)s and any unbilled order %(other_order)s.') \
% {
'bank' : bank_not_invoiced,
'other_order': order_not_invoiced
}
else:
producer_on_hold_movement = \
_(
'This balance does not take account of any unrecognized payments %(bank)s.') % {
'bank': bank_not_invoiced
}
option_dict = {'id': "#basket_message", 'html': mark_safe(producer_on_hold_movement)}
to_json.append(option_dict)
return
def __str__(self):
if self.producer_price_are_wo_vat:
return "%s %s" % (self.short_profile_name, _("wo tax"))
......
......@@ -109,10 +109,7 @@ def generate_invoice(permanence, payment_date):
new_customer_invoice.calculate_and_save_delta_buyinggroup()
new_customer_invoice.save()
recalculate_order_amount(
permanence_id=new_permanence.id,
re_init=True
)
new_permanence.recalculate_order_amount(re_init=True)
for customer_invoice in CustomerInvoice.objects.filter(
permanence_id=permanence.id,
......
......@@ -20,7 +20,7 @@ from repanier.models import Permanence
from repanier.models import Producer
from repanier.models import Product
from repanier.tools import clean_offer_item, reorder_purchases
from repanier.tools import recalculate_order_amount, create_or_update_one_purchase, reorder_offer_items
from repanier.tools import create_or_update_one_purchase, reorder_offer_items
@transaction.atomic
......@@ -151,7 +151,7 @@ def common_to_pre_open_and_open(permanence_id):
# Calculate the sort order of the order display screen
reorder_offer_items(permanence_id)
# Calculate the Purchase 'sum' for each customer
recalculate_order_amount(permanence_id=permanence_id)
permanence.recalculate_order_amount()
return permanence
......@@ -420,10 +420,7 @@ def close_order(permanence, all_producers, producers_id=None):
@transaction.atomic
def send_order(permanence, all_producers=True, producers_id=None, deliveries_id=None):
recalculate_order_amount(
permanence_id=permanence.id,
send_to_producer=True
)
permanence.recalculate_order_amount(send_to_producer=True)
reorder_purchases(permanence.id)
try:
email_order.email_order(permanence.id, all_producers, producers_id=producers_id, closed_deliveries_id=deliveries_id)
......
This diff is collapsed.
......@@ -6,13 +6,11 @@ import json
from django.core.serializers.json import DjangoJSONEncoder
from django.http import Http404
from django.http import HttpResponse
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.models import Producer
from repanier.models import Customer
from repanier.tools import customer_on_hold_movement_message, producer_on_hold_movement_message
@never_cache
......@@ -27,9 +25,7 @@ def customer_basket_message_form_ajax(request, pk):
customer = Customer.objects.filter(id=pk).order_by('?').first()
else:
customer = request.user.customer
customer_on_hold_movement = customer_on_hold_movement_message(customer)
basket_message = mark_safe(customer_on_hold_movement)
option_dict = {'id': "#basket_message", 'html': basket_message}
option_dict = {'id': "#basket_message", 'html': customer.get_on_hold_movement_html()}
to_json.append(option_dict)
return HttpResponse(json.dumps(to_json, cls=DjangoJSONEncoder), content_type="application/json")
raise Http404
......@@ -46,9 +42,6 @@ def producer_basket_message_form_ajax(request, pk, uuid):
if producer is None:
raise Http404
to_json = []
producer_on_hold_movement = producer_on_hold_movement_message(producer)
basket_message = mark_safe(producer_on_hold_movement)
option_dict = {'id': "#basket_message", 'html': basket_message}
to_json.append(option_dict)
producer.on_hold_movement_json(to_json)
return HttpResponse(json.dumps(to_json, cls=DjangoJSONEncoder), content_type="application/json")
raise Http404
......@@ -11,7 +11,7 @@ from django.views.decorators.http import require_GET
from repanier.const import PERMANENCE_OPENED, DECIMAL_ZERO
from repanier.models import Customer, ProducerInvoice, CustomerInvoice, Purchase, OfferItem
from repanier.tools import update_or_create_purchase, sint, sboolean, display_selected_value
from repanier.tools import create_or_update_one_cart_item, sint, sboolean, display_selected_value
@never_cache
......@@ -42,13 +42,14 @@ def order_ajax(request):
status=PERMANENCE_OPENED
).order_by('?')
if qs.exists():
result = update_or_create_purchase(
result = create_or_update_one_cart_item(
customer=customer,
offer_item_id=offer_item_id,
value_id=value_id,
basket=basket,
batch_job=False
)
if result is None:
# Select one purchase
purchase = Purchase.objects.filter(
......@@ -67,8 +68,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,
......
......@@ -87,34 +87,12 @@ def order_init_ajax(request):
)
if customer.may_order:
if REPANIER_SETTINGS_DISPLAY_PRODUCER_ON_ORDER_FORM:
for producer in permanence.producers.all():
producer_invoice = ProducerInvoice.objects.filter(
producer_id=producer.id, permanence_id=permanence.id
for producer_invoice in ProducerInvoice.objects.filter(
permanence_id=permanence.id
).only(
"total_price_with_tax", "status"
).order_by('?').first()
if producer_invoice is None:
producer_invoice = ProducerInvoice.objects.create(
permanence_id=permanence.id,
producer_id=producer.id,
status=permanence.status
)
if producer.minimum_order_value.amount > DECIMAL_ZERO:
if producer_invoice is None:
ratio = 0
else:
ratio = producer_invoice.total_price_with_tax.amount / producer.minimum_order_value.amount
if ratio >= DECIMAL_ONE:
ratio = 100
else:
ratio *= 100
option_dict = {'id' : "#order_procent%d" % producer.id,
'html': "%s%%" % number_format(ratio, 0)}
to_json.append(option_dict)
if producer_invoice.status != PERMANENCE_OPENED:
option_dict = {'id' : "#order_closed%d" % producer.id,
'html': '&nbsp;<span class="glyphicon glyphicon-ban-circle" aria-hidden="true"></span>'}
to_json.append(option_dict)
).order_by('?'):
producer_invoice.get_order_json(to_json)
communication = sboolean(request.GET.get('co', False))
if communication \
and customer_invoice.total_price_with_tax == DECIMAL_ZERO \
......@@ -185,7 +163,7 @@ def order_init_ajax(request):
if box_purchase is not None:
offer_item = box_purchase.offer_item
if offer_item is not None:
option_dict = display_selected_box_value(customer, offer_item, box_purchase)
option_dict = display_selected_box_value(offer_item, box_purchase)
to_json.append(option_dict)
option_dict = {'id': ".btn_like%s" % offer_item_id, 'html': offer_item.get_like(user)}
to_json.append(option_dict)
......
......@@ -15,7 +15,7 @@ from repanier.const import *
from repanier.models import OfferItem
from repanier.models import Producer
from repanier.models import Purchase
from repanier.tools import cap, next_row, recalculate_order_amount
from repanier.tools import cap, next_row
def next_purchase(purchases):
......
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