Commit 3d4f0b37 authored by Patrick's avatar Patrick

Two pass to calculate invoice price

parent 6b888178
...@@ -227,7 +227,6 @@ class CustomerInvoice(models.Model): ...@@ -227,7 +227,6 @@ class CustomerInvoice(models.Model):
self.calculate_delta_price() self.calculate_delta_price()
self.calculate_delta_transport() self.calculate_delta_transport()
self.save()
producer_invoice_buyinggroup.delta_price_with_tax.amount += self.delta_price_with_tax.amount producer_invoice_buyinggroup.delta_price_with_tax.amount += self.delta_price_with_tax.amount
producer_invoice_buyinggroup.delta_vat.amount += self.delta_vat.amount producer_invoice_buyinggroup.delta_vat.amount += self.delta_vat.amount
...@@ -238,14 +237,24 @@ class CustomerInvoice(models.Model): ...@@ -238,14 +237,24 @@ class CustomerInvoice(models.Model):
def calculate_delta_price(self): def calculate_delta_price(self):
getcontext().rounding = ROUND_HALF_UP getcontext().rounding = ROUND_HALF_UP
result_set = purchase.Purchase.objects.filter( if self.customer_charged is None:
permanence_id=self.permanence_id, result_set = purchase.Purchase.objects.filter(
customer_id=self.customer_id, permanence_id=self.permanence_id,
).order_by('?').aggregate( customer_id=self.customer_id,
Sum('customer_vat'), ).order_by('?').aggregate(
Sum('deposit'), Sum('customer_vat'),
Sum('selling_price') Sum('deposit'),
) Sum('selling_price')
)
else:
result_set = purchase.Purchase.objects.filter(
permanence_id=self.permanence_id,
customer_charged_id=self.customer_id,
).order_by('?').aggregate(
Sum('customer_vat'),
Sum('deposit'),
Sum('selling_price')
)
if result_set["customer_vat__sum"] is not None: if result_set["customer_vat__sum"] is not None:
self.total_vat.amount = result_set["customer_vat__sum"] self.total_vat.amount = result_set["customer_vat__sum"]
else: else:
...@@ -298,6 +307,7 @@ class CustomerInvoice(models.Model): ...@@ -298,6 +307,7 @@ class CustomerInvoice(models.Model):
self.delta_price_with_tax.amount = DECIMAL_ZERO self.delta_price_with_tax.amount = DECIMAL_ZERO
self.delta_vat.amount = DECIMAL_ZERO self.delta_vat.amount = DECIMAL_ZERO
def calculate_delta_transport(self): def calculate_delta_transport(self):
self.delta_transport.amount = DECIMAL_ZERO self.delta_transport.amount = DECIMAL_ZERO
......
...@@ -23,6 +23,7 @@ from repanier.tools import * ...@@ -23,6 +23,7 @@ from repanier.tools import *
@transaction.atomic @transaction.atomic
def generate_invoice(permanence, payment_date): def generate_invoice(permanence, payment_date):
getcontext().rounding = ROUND_HALF_UP
from repanier.apps import REPANIER_SETTINGS_MEMBERSHIP_FEE, REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION from repanier.apps import REPANIER_SETTINGS_MEMBERSHIP_FEE, REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION
today = timezone.now().date() today = timezone.now().date()
bank_account = BankAccount.objects.filter(operation_status=BANK_LATEST_TOTAL).order_by('?').first() bank_account = BankAccount.objects.filter(operation_status=BANK_LATEST_TOTAL).order_by('?').first()
...@@ -30,7 +31,23 @@ def generate_invoice(permanence, payment_date): ...@@ -30,7 +31,23 @@ def generate_invoice(permanence, payment_date):
customer_buyinggroup = Customer.objects.filter(represent_this_buyinggroup=True).order_by('?').first() customer_buyinggroup = Customer.objects.filter(represent_this_buyinggroup=True).order_by('?').first()
if bank_account is None or producer_buyinggroup is None or customer_buyinggroup is None: if bank_account is None or producer_buyinggroup is None or customer_buyinggroup is None:
return return
getcontext().rounding = ROUND_HALF_UP customer_invoice_buyinggroup = CustomerInvoice.objects.filter(
customer_id=customer_buyinggroup.id,
permanence_id=permanence.id,
).order_by('?').first()
if customer_invoice_buyinggroup is None:
customer_invoice_buyinggroup = CustomerInvoice.objects.create(
customer_id=customer_buyinggroup.id,
permanence_id=permanence.id,
date_previous_balance=customer_buyinggroup.date_balance,
previous_balance=customer_buyinggroup.balance,
date_balance=payment_date,
balance=customer_buyinggroup.balance,
customer_charged_id=customer_buyinggroup.id,
transport=repanier.apps.REPANIER_SETTINGS_TRANSPORT,
min_transport=repanier.apps.REPANIER_SETTINGS_MIN_TRANSPORT,
price_list_multiplier=DECIMAL_ONE
)
old_bank_latest_total = bank_account.bank_amount_in.amount - bank_account.bank_amount_out.amount old_bank_latest_total = bank_account.bank_amount_in.amount - bank_account.bank_amount_out.amount
permanence_partially_invoiced = ProducerInvoice.objects.filter( permanence_partially_invoiced = ProducerInvoice.objects.filter(
permanence_id=permanence.id, permanence_id=permanence.id,
...@@ -74,7 +91,10 @@ def generate_invoice(permanence, payment_date): ...@@ -74,7 +91,10 @@ def generate_invoice(permanence, payment_date):
id=purchase.customer_invoice_id id=purchase.customer_invoice_id
).order_by('?').first() ).order_by('?').first()
new_customer_invoice = customer_invoice.create_child(new_permanence=new_permanence) new_customer_invoice = customer_invoice.create_child(new_permanence=new_permanence)
# Important : The customer_charged is null. This is required for calculate_and_save_delta_buyinggroup
new_customer_invoice.calculate_and_save_delta_buyinggroup()
new_customer_invoice.set_delivery(customer_invoice.delivery) new_customer_invoice.set_delivery(customer_invoice.delivery)
new_customer_invoice.save()
Purchase.objects.filter( Purchase.objects.filter(
customer_invoice_id=customer_invoice.id, customer_invoice_id=customer_invoice.id,
producer_id__in=producers_to_move producer_id__in=producers_to_move
...@@ -83,121 +103,67 @@ def generate_invoice(permanence, payment_date): ...@@ -83,121 +103,67 @@ def generate_invoice(permanence, payment_date):
customer_invoice_id=new_customer_invoice.id, customer_invoice_id=new_customer_invoice.id,
customer_charged_id=new_customer_invoice.customer_charged_id customer_charged_id=new_customer_invoice.customer_charged_id
) )
new_customer_invoice.calculate_and_save_delta_buyinggroup()
membership_fee_product = Product.objects.filter(
order_unit=PRODUCT_ORDER_UNIT_MEMBERSHIP_FEE,
is_active=True
).order_by('?').first()
membership_fee_product.producer_unit_price = REPANIER_SETTINGS_MEMBERSHIP_FEE
# Update the prices
membership_fee_product.save()
# Important : linked to task_invoice.cancel
# First pass, set customer_charged
for customer_invoice in CustomerInvoice.objects.filter( for customer_invoice in CustomerInvoice.objects.filter(
permanence_id=permanence.id, permanence_id=permanence.id
customer_charged_id=F('customer_id') ).order_by('?'):
).select_related("customer").order_by('?'):
# In case of changed delivery conditions # In case of changed delivery conditions
customer_invoice.set_delivery(customer_invoice.delivery) customer_invoice.set_delivery(customer_invoice.delivery)
# Need to calculate delta_price_with_tax, delta_vat and delta_transport customer_invoice.save()
customer_invoice.calculate_and_save_delta_buyinggroup()
Purchase.objects.filter( Purchase.objects.filter(
customer_invoice_id=customer_invoice.id customer_invoice_id=customer_invoice.id
).order_by('?').update( ).order_by('?').update(
customer_charged_id=customer_invoice.customer_charged_id customer_charged_id=customer_invoice.customer_charged_id
) )
# 4 - Add Membership fee Subscription # Second pass, calculate invoices of charged customers
customer = customer_invoice.customer for customer_invoice in CustomerInvoice.objects.filter(
if REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION > 0 and REPANIER_SETTINGS_MEMBERSHIP_FEE > 0 and not customer.represent_this_buyinggroup: permanence_id=permanence.id
# There is a membership fee ).order_by('?'):
if customer.membership_fee_valid_until < today: # Need to calculate delta_price_with_tax, delta_vat and delta_transport
membership_fee_offer_item = get_or_create_offer_item( customer_invoice.calculate_and_save_delta_buyinggroup()
permanence, customer_invoice.save()
membership_fee_product.id,
membership_fee_product.producer_id
)
permanence.producers.add(membership_fee_offer_item.producer_id)
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,
REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION
)
customer.save(update_fields=['membership_fee_valid_until', ])
# Important : linked to task_invoice.cancel
for delivery in DeliveryBoard.objects.filter(
permanence_id=permanence.id,
delivery_point__customer_responsible__isnull=False
):
result_set = CustomerInvoice.objects.filter(
permanence_id=permanence.id,
customer_charged_id=delivery.delivery_point.customer_responsible_id
).exclude(
customer_id=delivery.delivery_point.customer_responsible_id
).order_by('?').aggregate(
Sum('total_price_with_tax'),
Sum('total_vat'),
Sum('delta_price_with_tax'),
Sum('delta_vat'),
)
if result_set["total_price_with_tax__sum"] is not None:
sum_total_price_with_tax = result_set["total_price_with_tax__sum"]
else:
sum_total_price_with_tax = DECIMAL_ZERO
if result_set["total_vat__sum"] is not None:
sum_total_vat = result_set["total_vat__sum"]
else:
sum_total_vat = DECIMAL_ZERO
if result_set["delta_price_with_tax__sum"] is not None:
sum_delta_price_with_tax = result_set["delta_price_with_tax__sum"]
else:
sum_delta_price_with_tax = DECIMAL_ZERO
if result_set["delta_vat__sum"] is not None:
sum_delta_vat = result_set["delta_vat__sum"]
else:
sum_delta_vat = DECIMAL_ZERO
CustomerInvoice.objects.filter( if REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION > 0 and REPANIER_SETTINGS_MEMBERSHIP_FEE > 0:
permanence_id=permanence.id, membership_fee_product = Product.objects.filter(
customer_id=delivery.delivery_point.customer_responsible_id order_unit=PRODUCT_ORDER_UNIT_MEMBERSHIP_FEE,
).update( is_active=True
is_order_confirm_send=True,
total_price_with_tax=sum_total_price_with_tax,
total_vat=sum_total_vat,
delta_price_with_tax=sum_delta_price_with_tax,
delta_vat=sum_delta_vat,
delta_transport=DECIMAL_ZERO,
)
customer_invoice_charged = CustomerInvoice.objects.filter(
permanence_id=permanence.id,
customer_id=delivery.delivery_point.customer_responsible_id
).order_by('?').first() ).order_by('?').first()
customer_invoice_charged.calculate_and_save_delta_buyinggroup() membership_fee_product.producer_unit_price = REPANIER_SETTINGS_MEMBERSHIP_FEE
# Update the prices
membership_fee_product.save()
customer_invoice_buyinggroup = CustomerInvoice.objects.filter( for customer_invoice in CustomerInvoice.objects.filter(
customer_id=customer_buyinggroup.id,
permanence_id=permanence.id,
).order_by('?').first()
if customer_invoice_buyinggroup is None:
customer_invoice_buyinggroup = CustomerInvoice.objects.create(
customer_id=customer_buyinggroup.id,
permanence_id=permanence.id, permanence_id=permanence.id,
date_previous_balance=customer_buyinggroup.date_balance, customer_charged_id=F('customer_id')
previous_balance=customer_buyinggroup.balance, ).select_related("customer").order_by('?'):
date_balance=payment_date, # 4 - Add Membership fee Subscription
balance=customer_buyinggroup.balance, customer = customer_invoice.customer
customer_charged_id=customer_buyinggroup.id, if not customer.represent_this_buyinggroup:
transport=repanier.apps.REPANIER_SETTINGS_TRANSPORT, # There is a membership fee
min_transport=repanier.apps.REPANIER_SETTINGS_MIN_TRANSPORT, if customer.membership_fee_valid_until < today:
price_list_multiplier=DECIMAL_ONE membership_fee_offer_item = get_or_create_offer_item(
) permanence,
membership_fee_product.id,
membership_fee_product.producer_id
)
permanence.producers.add(membership_fee_offer_item.producer_id)
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,
REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION
)
customer.save(update_fields=['membership_fee_valid_until', ])
for customer_invoice in CustomerInvoice.objects.filter( for customer_invoice in CustomerInvoice.objects.filter(
permanence_id=permanence.id permanence_id=permanence.id
...@@ -559,21 +525,18 @@ def cancel_invoice(permanence): ...@@ -559,21 +525,18 @@ def cancel_invoice(permanence):
date_balance=F('date_previous_balance'), date_balance=F('date_previous_balance'),
invoice_sort_order=None invoice_sort_order=None
) )
# Important : linked to task_invoice.generate # # Important : linked to task_invoice.generate
for delivery in DeliveryBoard.objects.filter( # First pass, set customer_charged
permanence_id=permanence.id, CustomerInvoice.objects.filter(
delivery_point__customer_responsible__isnull=False permanence_id=permanence.id
): ).order_by('?').update(customer_charged=None)
CustomerInvoice.objects.filter( # Second pass, calculate invoices of charged customers
permanence_id=permanence.id, for customer_invoice in CustomerInvoice.objects.filter(
customer_id=delivery.delivery_point.customer_responsible_id permanence_id=permanence.id
).update( ).order_by('?'):
total_price_with_tax=DECIMAL_ZERO, # Need to calculate delta_price_with_tax, delta_vat and delta_transport
total_vat=DECIMAL_ZERO, customer_invoice.calculate_and_save_delta_buyinggroup()
delta_price_with_tax=DECIMAL_ZERO, customer_invoice.save()
delta_vat=DECIMAL_ZERO,
delta_transport=DECIMAL_ZERO
)
for customer_invoice in CustomerInvoice.objects.filter( for customer_invoice in CustomerInvoice.objects.filter(
permanence_id=permanence.id).order_by(): permanence_id=permanence.id).order_by():
......
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