Commit 05bd177a authored by Skia's avatar Skia

Migrate invoices and lot of eboutic improvements

parent 50c452c2
Pipeline #120 failed with stage
in 3 minutes and 9 seconds
...@@ -14,48 +14,56 @@ ...@@ -14,48 +14,56 @@
<thead> <thead>
<tr> <tr>
<td>{% trans %}Date{% endtrans %}</td> <td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Counter{% endtrans %}</td>
<td>{% trans %}Barman{% endtrans %}</td> <td>{% trans %}Barman{% endtrans %}</td>
<td>{% trans %}Amount{% endtrans %}</td> <td>{% trans %}Amount{% endtrans %}</td>
<td>{% trans %}Payment method{% endtrans %}</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for i in customer.refillings.all() %} {% for i in customer.refillings.order_by('-date').all() %}
<tr> <tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td> <td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td>{{ i.counter }}</td>
<td><a href="{{ i.operator.get_absolute_url() }}">{{ i.operator.get_display_name() }}</a></td> <td><a href="{{ i.operator.get_absolute_url() }}">{{ i.operator.get_display_name() }}</a></td>
<td>{{ i.amount }}</td> <td>{{ i.amount }}</td>
<td>{{ i.get_payment_method_display() }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endif %} {% endif %}
{% if customer.buyings.exists() %} {% if customer.buyings.exists() %}
<h4>{% trans %}Buyings{% endtrans %}</h4> <h4>{% trans %}Account buyings{% endtrans %}</h4>
<table> <table>
<thead> <thead>
<tr> <tr>
<td>{% trans %}Date{% endtrans %}</td> <td>{% trans %}Date{% endtrans %}</td>
<td>{% trans %}Counter{% endtrans %}</td>
<td>{% trans %}Barman{% endtrans %}</td> <td>{% trans %}Barman{% endtrans %}</td>
<td>{% trans %}Label{% endtrans %}</td> <td>{% trans %}Label{% endtrans %}</td>
<td>{% trans %}Quantity{% endtrans %}</td> <td>{% trans %}Quantity{% endtrans %}</td>
<td>{% trans %}Total{% endtrans %}</td> <td>{% trans %}Total{% endtrans %}</td>
<td>{% trans %}Payment method{% endtrans %}</td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for i in customer.buyings.all() %} {% for i in customer.buyings.order_by('-date').all() %}
<tr> <tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td> <td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td>{{ i.seller }}</td> <td>{{ i.counter }}</td>
<td><a href="{{ i.seller.get_absolute_url() }}">{{ i.seller.get_display_name() }}</a></td>
<td>{{ i.label }}</td> <td>{{ i.label }}</td>
<td>{{ i.quantity }}</td> <td>{{ i.quantity }}</td>
<td>{{ i.quantity * i.unit_price }}</td> <td>{{ i.quantity * i.unit_price }}</td>
<td>{{ i.get_payment_method_display() }}</td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody> </tbody>
</table> </table>
{% endif %} {% endif %}
{% if customer.user.invoices.exists() %} {% if customer.user.invoices.exists() %}
<h4>{% trans %}Invoices{% endtrans %}</h4> <h4>{% trans %}Eboutic invoices{% endtrans %}</h4>
<table> <table>
<thead> <thead>
<tr> <tr>
...@@ -65,7 +73,7 @@ ...@@ -65,7 +73,7 @@
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
{% for i in customer.user.invoices.all() %} {% for i in customer.user.invoices.order_by('-date').all() %}
<tr> <tr>
<td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td> <td>{{ i.date|localtime|date(DATETIME_FORMAT) }} - {{ i.date|localtime|time(DATETIME_FORMAT) }}</td>
<td> <td>
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0008_auto_20160818_0231'),
]
operations = [
migrations.AlterField(
model_name='refilling',
name='payment_method',
field=models.CharField(verbose_name='payment method', default='CASH', choices=[('CHECK', 'Check'), ('CASH', 'Cash'), ('EBOUTIC', 'Eboutic')], max_length=255),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0009_auto_20160818_1709'),
]
operations = [
migrations.AlterField(
model_name='refilling',
name='payment_method',
field=models.CharField(default='CASH', max_length=255, verbose_name='payment method', choices=[('CHECK', 'Check'), ('CASH', 'Cash'), ('CARD', 'Credit card')]),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
from django.conf import settings
class Migration(migrations.Migration):
dependencies = [
('counter', '0010_auto_20160818_1716'),
]
operations = [
migrations.AlterField(
model_name='selling',
name='club',
field=models.ForeignKey(related_name='sellings', null=True, on_delete=django.db.models.deletion.SET_NULL, to='club.Club'),
),
migrations.AlterField(
model_name='selling',
name='counter',
field=models.ForeignKey(related_name='sellings', null=True, on_delete=django.db.models.deletion.SET_NULL, to='counter.Counter'),
),
migrations.AlterField(
model_name='selling',
name='customer',
field=models.ForeignKey(related_name='buyings', null=True, on_delete=django.db.models.deletion.SET_NULL, to='counter.Customer'),
),
migrations.AlterField(
model_name='selling',
name='product',
field=models.ForeignKey(related_name='sellings', null=True, on_delete=django.db.models.deletion.SET_NULL, blank=True, to='counter.Product'),
),
migrations.AlterField(
model_name='selling',
name='seller',
field=models.ForeignKey(related_name='sellings_as_operator', null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0011_auto_20160818_1722'),
]
operations = [
migrations.AddField(
model_name='selling',
name='payment_method',
field=models.CharField(default='SITH_ACCOUNT', max_length=255, verbose_name='payment method', choices=[('SITH_ACCOUNT', 'Compte AE'), ('CARD', 'Credit card')]),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('counter', '0012_selling_payment_method'),
]
operations = [
migrations.AlterField(
model_name='selling',
name='payment_method',
field=models.CharField(max_length=255, default='SITH_ACCOUNT', verbose_name='payment method', choices=[('SITH_ACCOUNT', 'Sith account'), ('CARD', 'Credit card')]),
),
]
...@@ -5,7 +5,8 @@ from django.conf import settings ...@@ -5,7 +5,8 @@ from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.forms import ValidationError from django.forms import ValidationError
from datetime import timedelta from datetime import timedelta, datetime
from pytz import timezone
import random import random
import string import string
...@@ -206,7 +207,7 @@ class Refilling(models.Model): ...@@ -206,7 +207,7 @@ class Refilling(models.Model):
amount = CurrencyField(_('amount')) amount = CurrencyField(_('amount'))
operator = models.ForeignKey(User, related_name="refillings_as_operator", blank=False) operator = models.ForeignKey(User, related_name="refillings_as_operator", blank=False)
customer = models.ForeignKey(Customer, related_name="refillings", blank=False) customer = models.ForeignKey(Customer, related_name="refillings", blank=False)
date = models.DateTimeField(_('date'), auto_now=True) date = models.DateTimeField(_('date'))
payment_method = models.CharField(_('payment method'), max_length=255, payment_method = models.CharField(_('payment method'), max_length=255,
choices=settings.SITH_COUNTER_PAYMENT_METHOD, default='CASH') choices=settings.SITH_COUNTER_PAYMENT_METHOD, default='CASH')
bank = models.CharField(_('bank'), max_length=255, bank = models.CharField(_('bank'), max_length=255,
...@@ -223,6 +224,8 @@ class Refilling(models.Model): ...@@ -223,6 +224,8 @@ class Refilling(models.Model):
# return reverse('counter:details', kwargs={'counter_id': self.id}) # return reverse('counter:details', kwargs={'counter_id': self.id})
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.date:
self.date = datetime.now().replace(tzinfo=timezone(settings.TIME_ZONE))
self.full_clean() self.full_clean()
if not self.is_validated: if not self.is_validated:
self.customer.amount += self.amount self.customer.amount += self.amount
...@@ -235,14 +238,16 @@ class Selling(models.Model): ...@@ -235,14 +238,16 @@ class Selling(models.Model):
Handle the sellings Handle the sellings
""" """
label = models.CharField(_("label"), max_length=64) label = models.CharField(_("label"), max_length=64)
product = models.ForeignKey(Product, related_name="sellings", null=True, blank=True) product = models.ForeignKey(Product, related_name="sellings", null=True, blank=True, on_delete=models.SET_NULL)
counter = models.ForeignKey(Counter, related_name="sellings", blank=False) counter = models.ForeignKey(Counter, related_name="sellings", null=True, blank=False, on_delete=models.SET_NULL)
club = models.ForeignKey(Club, related_name="sellings", blank=False) club = models.ForeignKey(Club, related_name="sellings", null=True, blank=False, on_delete=models.SET_NULL)
unit_price = CurrencyField(_('unit price')) unit_price = CurrencyField(_('unit price'))
quantity = models.IntegerField(_('quantity')) quantity = models.IntegerField(_('quantity'))
seller = models.ForeignKey(User, related_name="sellings_as_operator", blank=False) seller = models.ForeignKey(User, related_name="sellings_as_operator", null=True, blank=False, on_delete=models.SET_NULL)
customer = models.ForeignKey(Customer, related_name="buyings", blank=False) customer = models.ForeignKey(Customer, related_name="buyings", null=True, blank=False, on_delete=models.SET_NULL)
date = models.DateTimeField(_('date'), auto_now=True) date = models.DateTimeField(_('date'))
payment_method = models.CharField(_('payment method'), max_length=255,
choices=[('SITH_ACCOUNT', _('Sith account')), ('CARD', _('Credit card'))], default='SITH_ACCOUNT')
is_validated = models.BooleanField(_('is validated'), default=False) is_validated = models.BooleanField(_('is validated'), default=False)
class Meta: class Meta:
...@@ -253,6 +258,8 @@ class Selling(models.Model): ...@@ -253,6 +258,8 @@ class Selling(models.Model):
self.quantity*self.unit_price, self.customer.user.get_display_name()) self.quantity*self.unit_price, self.customer.user.get_display_name())
def save(self, *args, **kwargs): def save(self, *args, **kwargs):
if not self.date:
self.date = datetime.now().replace(tzinfo=timezone(settings.TIME_ZONE))
self.full_clean() self.full_clean()
if not self.is_validated: if not self.is_validated:
self.customer.amount -= self.quantity * self.unit_price self.customer.amount -= self.quantity * self.unit_price
......
...@@ -44,7 +44,8 @@ class GetUserForm(forms.Form): ...@@ -44,7 +44,8 @@ class GetUserForm(forms.Form):
elif cleaned_data['id'] is not None: elif cleaned_data['id'] is not None:
cus = Customer.objects.filter(user=cleaned_data['id']).first() cus = Customer.objects.filter(user=cleaned_data['id']).first()
sub = get_subscriber(cus.user) if cus is not None else None sub = get_subscriber(cus.user) if cus is not None else None
if cus is None or sub is None or (date.today() - sub.subscriptions.last().subscription_end) > timedelta(days=90): if (cus is None or sub is None or not sub.subscriptions.last() or
(date.today() - sub.subscriptions.last().subscription_end) > timedelta(days=90)):
raise forms.ValidationError(_("User not found")) raise forms.ValidationError(_("User not found"))
cleaned_data['user_id'] = cus.user.id cleaned_data['user_id'] = cus.user.id
cleaned_data['user'] = cus.user cleaned_data['user'] = cus.user
......
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('eboutic', '0001_initial'),
]
operations = [
migrations.RemoveField(
model_name='basketitem',
name='type',
),
migrations.RemoveField(
model_name='invoiceitem',
name='type',
),
migrations.AddField(
model_name='basketitem',
name='type_id',
field=models.IntegerField(default=1, verbose_name='product type id'),
preserve_default=False,
),
migrations.AddField(
model_name='invoiceitem',
name='type_id',
field=models.IntegerField(default=1, verbose_name='product type id'),
preserve_default=False,
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('eboutic', '0002_auto_20160818_1635'),
]
operations = [
migrations.AlterField(
model_name='invoice',
name='payment_method',
field=models.CharField(verbose_name='payment method', max_length=20, choices=[('CARD', 'Credit card'), ('SITH_ACCOUNT', 'Sith account')]),
),
]
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('eboutic', '0003_auto_20160818_1738'),
]
operations = [
migrations.RemoveField(
model_name='invoice',
name='payment_method',
),
]
from django.db import models, DataError from django.db import models, DataError
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.conf import settings
from accounting.models import CurrencyField from accounting.models import CurrencyField
from counter.models import Counter, Product, Customer from counter.models import Counter, Product, Customer, Selling, Refilling
from core.models import User from core.models import User
class Basket(models.Model): class Basket(models.Model):
...@@ -15,7 +16,7 @@ class Basket(models.Model): ...@@ -15,7 +16,7 @@ class Basket(models.Model):
def add_product(self, p, q = 1): def add_product(self, p, q = 1):
item = self.items.filter(product_id=p.id).first() item = self.items.filter(product_id=p.id).first()
if item is None: if item is None:
BasketItem(basket=self, product_id=p.id, product_name=p.name, type=p.product_type.name, BasketItem(basket=self, product_id=p.id, product_name=p.name, type_id=p.product_type.id,
quantity=q, product_unit_price=p.selling_price).save() quantity=q, product_unit_price=p.selling_price).save()
else: else:
item.quantity += q item.quantity += q
...@@ -44,10 +45,11 @@ class Invoice(models.Model): ...@@ -44,10 +45,11 @@ class Invoice(models.Model):
""" """
user = models.ForeignKey(User, related_name='invoices', verbose_name=_('user'), blank=False) user = models.ForeignKey(User, related_name='invoices', verbose_name=_('user'), blank=False)
date = models.DateTimeField(_('date'), auto_now=True) date = models.DateTimeField(_('date'), auto_now=True)
payment_method = models.CharField(choices=[('CREDIT_CARD', _('Credit card')), ('SITH_ACCOUNT', _('Sith account'))],
max_length=20, verbose_name=_('payment method'))
validated = models.BooleanField(_("validated"), default=False) validated = models.BooleanField(_("validated"), default=False)
def __str__(self):
return "%s - %s - %s" % (self.user, self.get_total(), self.date)
def get_total(self): def get_total(self):
total = 0 total = 0
for i in self.items.all(): for i in self.items.all():
...@@ -59,23 +61,44 @@ class Invoice(models.Model): ...@@ -59,23 +61,44 @@ class Invoice(models.Model):
raise DataError(_("Invoice already validated")) raise DataError(_("Invoice already validated"))
from counter.models import Customer from counter.models import Customer
if not Customer.objects.filter(user=self.user).exists(): if not Customer.objects.filter(user=self.user).exists():
number = Customer.objects.last().account_id[:-1] number = Customer.objects.count() + 1
Customer(user=self.user, account_id=Customer.generate_account_id(number), amount=0).save() Customer(user=self.user, account_id=Customer.generate_account_id(number), amount=0).save()
if self.payment_method == "SITH_ACCOUNT": eboutic = Counter.objects.filter(type="EBOUTIC").first()
self.user.customer.amount -= self.get_total() for i in self.items.all():
self.user.customer.save() if i.type_id == settings.SITH_COUNTER_PRODUCTTYPE_REFILLING:
else: new = Refilling(
for i in self.items.filter(type="REFILLING").all(): counter=eboutic,
self.user.customer.amount += i.product_unit_price * i.quantity customer=self.user.customer,
self.user.customer.save() operator=self.user,
amount=i.product_unit_price * i.quantity,
payment_method="CARD",
bank="OTHER",
date=self.date,
)
new.save()
else:
product = Product.objects.filter(id=i.product_id).first()
new = Selling(
label=i.product_name,
counter=eboutic,
club=product.club,
product=product,
seller=self.user,
customer=self.user.customer,
unit_price=i.product_unit_price,
quantity=i.quantity,
payment_method="CARD",
is_validated=True,
date=self.date,
)
new.save()
self.validated = True self.validated = True
self.save() self.save()
class AbstractBaseItem(models.Model): class AbstractBaseItem(models.Model):
product_id = models.IntegerField(_('product id')) product_id = models.IntegerField(_('product id'))
product_name = models.CharField(_('product name'), max_length=255) product_name = models.CharField(_('product name'), max_length=255)
type = models.CharField(_('product type'), max_length=255) type_id = models.IntegerField(_('product type id'))
product_unit_price = CurrencyField(_('unit price')) product_unit_price = CurrencyField(_('unit price'))
quantity = models.IntegerField(_('quantity')) quantity = models.IntegerField(_('quantity'))
......
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% block title %}
{% trans %}Eboutic{% endtrans %}
{% endblock %}
{% macro add_product(id, content) %} {% macro add_product(id, content) %}
<form method="post" action="{{ url('eboutic:main') }}" class="inline" style="display:inline"> <form method="post" action="{{ url('eboutic:main') }}" class="inline" style="display:inline">
{% csrf_token %} {% csrf_token %}
...@@ -34,11 +38,14 @@ ...@@ -34,11 +38,14 @@
</form> </form>
</div> </div>
<div> <div>
<p><strong>{% trans %}Products: {% endtrans %}</strong> {% for t in categories %}
{% for p in eboutic.products.all() %} {% if eboutic.products.filter(product_type=t).exists() %}
{{ add_product(p.id, p.name) }} <h5>{{ t }}</h5>
{% for p in eboutic.products.filter(product_type=t).all() %}
{{ add_product(p.id, p.name) }}
{% endfor %}
{% endif %}
{% endfor %} {% endfor %}
</p>
</div> </div>
{% endblock %} {% endblock %}
......
{% extends "core/base.jinja" %} {% extends "core/base.jinja" %}
{% block title %}
{% trans %}Basket state{% endtrans %}
{% endblock %}
{% block content %} {% block content %}
<h3>{% trans %}Eboutic{% endtrans %}</h3> <h3>{% trans %}Eboutic{% endtrans %}</h3>
...@@ -30,7 +34,7 @@ ...@@ -30,7 +34,7 @@
{% endfor %} {% endfor %}
<input type="submit" value="{% trans %}Pay with credit card{% endtrans %}" /> <input type="submit" value="{% trans %}Pay with credit card{% endtrans %}" />
</form> </form>
{% if basket.items.filter(type="REFILLING").exists() %} {% if basket.items.filter(type_id=settings.SITH_COUNTER_PRODUCTTYPE_REFILLING).exists() %}
<p>{% trans %}AE account payment disabled because your basket contains refilling items.{% endtrans %}</p> <p>{% trans %}AE account payment disabled because your basket contains refilling items.{% endtrans %}</p>
{% else %} {% else %}
<form method="post" action="{{ url('eboutic:pay_with_sith') }}"> <form method="post" action="{{ url('eboutic:pay_with_sith') }}">
......