Merge branch 'qwann/k-fet/category_addcost' into 'master'
K-Fêt - Majorations - Seulement les catégories préalablement sélectionnées sont majorées le le cas échéant. - Pour modifier cette sélection, suivre le lien "Catégories" depuis la liste des articles. Fixes #149 See merge request !189
This commit is contained in:
commit
ebf948d042
10 changed files with 265 additions and 85 deletions
|
@ -233,6 +233,16 @@ class CheckoutStatementUpdateForm(forms.ModelForm):
|
|||
model = CheckoutStatement
|
||||
exclude = ['by', 'at', 'checkout', 'amount_error', 'amount_taken']
|
||||
|
||||
|
||||
# -----
|
||||
# Category
|
||||
# -----
|
||||
|
||||
class CategoryForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = ArticleCategory
|
||||
fields = ['name', 'has_addcost']
|
||||
|
||||
# -----
|
||||
# Article forms
|
||||
# -----
|
||||
|
|
24
kfet/migrations/0052_category_addcost.py
Normal file
24
kfet/migrations/0052_category_addcost.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('kfet', '0051_verbose_names'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='articlecategory',
|
||||
name='has_addcost',
|
||||
field=models.BooleanField(default=True, help_text="Si oui et qu'une majoration est active, celle-ci sera appliquée aux articles de cette catégorie.", verbose_name='majorée'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='articlecategory',
|
||||
name='name',
|
||||
field=models.CharField(max_length=45, verbose_name='nom'),
|
||||
),
|
||||
]
|
|
@ -338,13 +338,20 @@ class CheckoutStatement(models.Model):
|
|||
balance=F('balance') - last_statement.balance_new + self.balance_new)
|
||||
super(CheckoutStatement, self).save(*args, **kwargs)
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class ArticleCategory(models.Model):
|
||||
name = models.CharField(max_length = 45)
|
||||
name = models.CharField("nom", max_length=45)
|
||||
has_addcost = models.BooleanField("majorée", default=True,
|
||||
help_text="Si oui et qu'une majoration "
|
||||
"est active, celle-ci sera "
|
||||
"appliquée aux articles de "
|
||||
"cette catégorie.")
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Article(models.Model):
|
||||
name = models.CharField("nom", max_length = 45)
|
||||
|
|
|
@ -16,6 +16,9 @@
|
|||
<a class="btn btn-primary btn-lg" href="{% url 'kfet.article.create' %}">
|
||||
Nouvel article
|
||||
</a>
|
||||
<a class="btn btn-primary btn-lg" href="{% url 'kfet.category' %}">
|
||||
Catégories
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<div class="row form-only">
|
||||
<div class="col-sm-12 col-md-8 col-md-offset-2">
|
||||
<div class="content-form">
|
||||
<form submit="" method="post" class="form-horizontal">
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% include 'kfet/form_snippet.html' with form=form %}
|
||||
{% if not perms.kfet.change_article %}
|
||||
|
|
53
kfet/templates/kfet/category.html
Normal file
53
kfet/templates/kfet/category.html
Normal file
|
@ -0,0 +1,53 @@
|
|||
{% extends 'kfet/base.html' %}
|
||||
|
||||
{% block title %}Categories d'articles{% endblock %}
|
||||
{% block content-header-title %}Categories d'articles{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
<div class="row">
|
||||
<div class="col-sm-4 col-md-3 col-content-left">
|
||||
<div class="content-left">
|
||||
<div class="content-left-top">
|
||||
<div class="line line-big">{{ categories|length }}</div>
|
||||
<div class="line line-bigsub">catégorie{{ categories|length|pluralize }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-8 col-md-9 col-content-right">
|
||||
{% include 'kfet/base_messages.html' %}
|
||||
<div class="content-right">
|
||||
<div class="content-right-block">
|
||||
<h2>Liste des catégories</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-condensed">
|
||||
<thead>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>Nom</td>
|
||||
<td class="text-right">Nombre d'articles</td>
|
||||
<td class="text-right">Peut être majorée</td>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for category in categories %}
|
||||
<tr>
|
||||
<td class="text-center">
|
||||
<a href="{% url 'kfet.category.update' category.pk %}">
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ category.name }}</td>
|
||||
<td class="text-right">{{ category.articles.all|length }}</td>
|
||||
<td class="text-right">{{ category.has_addcost | yesno:"Oui,Non"}}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
25
kfet/templates/kfet/category_update.html
Normal file
25
kfet/templates/kfet/category_update.html
Normal file
|
@ -0,0 +1,25 @@
|
|||
{% extends 'kfet/base.html' %}
|
||||
|
||||
{% block title %}Édition de la catégorie {{ category.name }}{% endblock %}
|
||||
{% block content-header-title %}Catégorie {{ category.name }} - Édition{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
|
||||
{% include "kfet/base_messages.html" %}
|
||||
|
||||
<div class="row form-only">
|
||||
<div class="col-sm-12 col-md-8 col-md-offset-2">
|
||||
<div class="content-form">
|
||||
<form action="" method="post" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
{% include 'kfet/form_snippet.html' with form=form %}
|
||||
{% if not perms.kfet.edit_articlecategory %}
|
||||
{% include 'kfet/form_authentication_snippet.html' %}
|
||||
{% endif %}
|
||||
{% include 'kfet/form_submit_snippet.html' with value="Enregistrer"%}
|
||||
<form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
|
@ -647,7 +647,7 @@ $(document).ready(function() {
|
|||
});
|
||||
$after.after(article_html);
|
||||
// Pour l'autocomplétion
|
||||
articlesList.push([article['name'],article['id'],article['category_id'],article['price'], article['stock']]);
|
||||
articlesList.push([article['name'],article['id'],article['category_id'],article['price'], article['stock'],article['category__has_addcost']]);
|
||||
}
|
||||
|
||||
function getArticles() {
|
||||
|
@ -831,8 +831,11 @@ $(document).ready(function() {
|
|||
while (i<articlesList.length && id != articlesList[i][1]) i++;
|
||||
article_data = articlesList[i];
|
||||
var amount_euro = - article_data[3] * nb ;
|
||||
if (settings['addcost_for'] && settings['addcost_amount'] && account_data['trigramme'] != settings['addcost_for'])
|
||||
amount_euro -= settings['addcost_amount'] * nb;
|
||||
if (settings['addcost_for']
|
||||
&& settings['addcost_amount']
|
||||
&& account_data['trigramme'] != settings['addcost_for']
|
||||
&& article_data[5])
|
||||
amount_euro -= settings['addcost_amount'] * nb;
|
||||
var reduc_divisor = 1;
|
||||
if (account_data['is_cof'])
|
||||
reduc_divisor = 1 + settings['subvention_cof'] / 100;
|
||||
|
|
14
kfet/urls.py
14
kfet/urls.py
|
@ -8,7 +8,7 @@ from kfet.decorators import teamkfet_required
|
|||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.Home.as_view(),
|
||||
name = 'kfet.home'),
|
||||
name='kfet.home'),
|
||||
url(r'^login/genericteam$', views.login_genericteam,
|
||||
name='kfet.login.genericteam'),
|
||||
url(r'^history$', views.history,
|
||||
|
@ -69,10 +69,10 @@ urlpatterns = [
|
|||
name='kfet.account.negative'),
|
||||
|
||||
# Account - Statistics
|
||||
url('^accounts/(?P<trigramme>.{3})/stat/operations/list$',
|
||||
url(r'^accounts/(?P<trigramme>.{3})/stat/operations/list$',
|
||||
views.AccountStatOperationList.as_view(),
|
||||
name='kfet.account.stat.operation.list'),
|
||||
url('^accounts/(?P<trigramme>.{3})/stat/operations$',
|
||||
url(r'^accounts/(?P<trigramme>.{3})/stat/operations$',
|
||||
views.AccountStatOperation.as_view(),
|
||||
name='kfet.account.stat.operation'),
|
||||
|
||||
|
@ -125,6 +125,14 @@ urlpatterns = [
|
|||
# Article urls
|
||||
# -----
|
||||
|
||||
# Category - General
|
||||
url('^categories/$',
|
||||
teamkfet_required(views.CategoryList.as_view()),
|
||||
name='kfet.category'),
|
||||
# Category - Update
|
||||
url('^categories/(?P<pk>\d+)/edit$',
|
||||
teamkfet_required(views.CategoryUpdate.as_view()),
|
||||
name='kfet.category.update'),
|
||||
# Article - General
|
||||
url('^articles/$',
|
||||
teamkfet_required(views.ArticleList.as_view()),
|
||||
|
|
201
kfet/views.py
201
kfet/views.py
|
@ -29,7 +29,7 @@ from kfet.models import (
|
|||
Account, Checkout, Article, Settings, AccountNegative,
|
||||
CheckoutStatement, GenericTeamToken, Supplier, SupplierArticle, Inventory,
|
||||
InventoryArticle, Order, OrderArticle, Operation, OperationGroup,
|
||||
TransferGroup, Transfer)
|
||||
TransferGroup, Transfer, ArticleCategory)
|
||||
from kfet.forms import (
|
||||
AccountTriForm, AccountBalanceForm, AccountNoTriForm, UserForm, CofForm,
|
||||
UserRestrictTeamForm, UserGroupForm, AccountForm, CofRestrictForm,
|
||||
|
@ -39,7 +39,7 @@ from kfet.forms import (
|
|||
KPsulOperationGroupForm, KPsulAccountForm, KPsulCheckoutForm,
|
||||
KPsulOperationFormSet, AddcostForm, FilterHistoryForm, SettingsForm,
|
||||
TransferFormSet, InventoryArticleForm, OrderArticleForm,
|
||||
OrderArticleToInventoryForm
|
||||
OrderArticleToInventoryForm, CategoryForm
|
||||
)
|
||||
from collections import defaultdict
|
||||
from kfet import consumers
|
||||
|
@ -52,7 +52,7 @@ from kfet.statistic import ScaleMixin, last_stats_manifest, tot_ventes
|
|||
|
||||
|
||||
class Home(TemplateView):
|
||||
template_name = "kfet/home.html"
|
||||
template_name = "kfet/home.html"
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(TemplateView, self).get_context_data(**kwargs)
|
||||
|
@ -723,28 +723,60 @@ class CheckoutStatementUpdate(SuccessMessageMixin, UpdateView):
|
|||
form.instance.amount_taken = getAmountTaken(form.instance)
|
||||
return super(CheckoutStatementUpdate, self).form_valid(form)
|
||||
|
||||
# -----
|
||||
# Category views
|
||||
# -----
|
||||
|
||||
|
||||
# Category - General
|
||||
class CategoryList(ListView):
|
||||
queryset = (ArticleCategory.objects
|
||||
.prefetch_related('articles')
|
||||
.order_by('name'))
|
||||
template_name = 'kfet/category.html'
|
||||
context_object_name = 'categories'
|
||||
|
||||
|
||||
# Category - Update
|
||||
class CategoryUpdate(SuccessMessageMixin, UpdateView):
|
||||
model = ArticleCategory
|
||||
template_name = 'kfet/category_update.html'
|
||||
form_class = CategoryForm
|
||||
success_url = reverse_lazy('kfet.category')
|
||||
success_message = "Informations mises à jour pour la catégorie : %(name)s"
|
||||
|
||||
# Surcharge de la validation
|
||||
def form_valid(self, form):
|
||||
# Checking permission
|
||||
if not self.request.user.has_perm('kfet.change_articlecategory'):
|
||||
form.add_error(None, 'Permission refusée')
|
||||
return self.form_invalid(form)
|
||||
|
||||
# Updating
|
||||
return super(CategoryUpdate, self).form_valid(form)
|
||||
|
||||
# -----
|
||||
# Article views
|
||||
# -----
|
||||
|
||||
# Article - General
|
||||
|
||||
# Article - General
|
||||
class ArticleList(ListView):
|
||||
queryset = (Article.objects
|
||||
.select_related('category')
|
||||
.prefetch_related(Prefetch('inventories',
|
||||
queryset = Inventory.objects.order_by('-at'),
|
||||
to_attr = 'inventory'))
|
||||
.order_by('category', '-is_sold', 'name'))
|
||||
.select_related('category')
|
||||
.prefetch_related(Prefetch('inventories',
|
||||
queryset=Inventory.objects.order_by('-at'),
|
||||
to_attr='inventory'))
|
||||
.order_by('category', '-is_sold', 'name'))
|
||||
template_name = 'kfet/article.html'
|
||||
context_object_name = 'articles'
|
||||
|
||||
# Article - Create
|
||||
|
||||
# Article - Create
|
||||
class ArticleCreate(SuccessMessageMixin, CreateView):
|
||||
model = Article
|
||||
template_name = 'kfet/article_create.html'
|
||||
form_class = ArticleForm
|
||||
model = Article
|
||||
template_name = 'kfet/article_create.html'
|
||||
form_class = ArticleForm
|
||||
success_message = 'Nouvel item : %(category)s - %(name)s'
|
||||
|
||||
# Surcharge de la validation
|
||||
|
@ -759,7 +791,7 @@ class ArticleCreate(SuccessMessageMixin, CreateView):
|
|||
# Save des suppliers déjà existant
|
||||
for supplier in form.cleaned_data['suppliers']:
|
||||
SupplierArticle.objects.create(
|
||||
article = article, supplier = supplier)
|
||||
article=article, supplier=supplier)
|
||||
|
||||
# Nouveau supplier
|
||||
supplier_new = form.cleaned_data['supplier_new'].strip()
|
||||
|
@ -768,49 +800,49 @@ class ArticleCreate(SuccessMessageMixin, CreateView):
|
|||
name=supplier_new)
|
||||
if created:
|
||||
SupplierArticle.objects.create(
|
||||
article = article, supplier = supplier)
|
||||
article=article, supplier=supplier)
|
||||
|
||||
# Inventaire avec stock initial
|
||||
inventory = Inventory()
|
||||
inventory.by = self.request.user.profile.account_kfet
|
||||
inventory.save()
|
||||
InventoryArticle.objects.create(
|
||||
inventory = inventory,
|
||||
article = article,
|
||||
stock_old = article.stock,
|
||||
stock_new = article.stock,
|
||||
inventory=inventory,
|
||||
article=article,
|
||||
stock_old=article.stock,
|
||||
stock_new=article.stock,
|
||||
)
|
||||
|
||||
# Creating
|
||||
return super(ArticleCreate, self).form_valid(form)
|
||||
|
||||
# Article - Read
|
||||
|
||||
# Article - Read
|
||||
class ArticleRead(DetailView):
|
||||
model = Article
|
||||
model = Article
|
||||
template_name = 'kfet/article_read.html'
|
||||
context_object_name = 'article'
|
||||
|
||||
def get_context_data(self, **kwargs):
|
||||
context = super(ArticleRead, self).get_context_data(**kwargs)
|
||||
inventoryarts = (InventoryArticle.objects
|
||||
.filter(article = self.object)
|
||||
.select_related('inventory')
|
||||
.order_by('-inventory__at'))
|
||||
.filter(article=self.object)
|
||||
.select_related('inventory')
|
||||
.order_by('-inventory__at'))
|
||||
context['inventoryarts'] = inventoryarts
|
||||
supplierarts = (SupplierArticle.objects
|
||||
.filter(article = self.object)
|
||||
.select_related('supplier')
|
||||
.order_by('-at'))
|
||||
.filter(article=self.object)
|
||||
.select_related('supplier')
|
||||
.order_by('-at'))
|
||||
context['supplierarts'] = supplierarts
|
||||
return context
|
||||
|
||||
# Article - Update
|
||||
|
||||
# Article - Update
|
||||
class ArticleUpdate(SuccessMessageMixin, UpdateView):
|
||||
model = Article
|
||||
template_name = 'kfet/article_update.html'
|
||||
form_class = ArticleRestrictForm
|
||||
model = Article
|
||||
template_name = 'kfet/article_update.html'
|
||||
form_class = ArticleRestrictForm
|
||||
success_message = "Informations mises à jour pour l'article : %(name)s"
|
||||
|
||||
# Surcharge de la validation
|
||||
|
@ -826,13 +858,13 @@ class ArticleUpdate(SuccessMessageMixin, UpdateView):
|
|||
for supplier in form.cleaned_data['suppliers']:
|
||||
if supplier not in article.suppliers.all():
|
||||
SupplierArticle.objects.create(
|
||||
article = article, supplier = supplier)
|
||||
article=article, supplier=supplier)
|
||||
|
||||
# On vire les suppliers désélectionnés
|
||||
for supplier in article.suppliers.all():
|
||||
if supplier not in form.cleaned_data['suppliers']:
|
||||
SupplierArticle.objects.filter(
|
||||
article = article, supplier = supplier).delete()
|
||||
article=article, supplier=supplier).delete()
|
||||
|
||||
# Nouveau supplier
|
||||
supplier_new = form.cleaned_data['supplier_new'].strip()
|
||||
|
@ -841,7 +873,7 @@ class ArticleUpdate(SuccessMessageMixin, UpdateView):
|
|||
name=supplier_new)
|
||||
if created:
|
||||
SupplierArticle.objects.create(
|
||||
article = article, supplier = supplier)
|
||||
article=article, supplier=supplier)
|
||||
|
||||
# Updating
|
||||
return super(ArticleUpdate, self).form_valid(form)
|
||||
|
@ -924,13 +956,14 @@ def kpsul_update_addcost(request):
|
|||
addcost_form = AddcostForm(request.POST)
|
||||
|
||||
if not addcost_form.is_valid():
|
||||
data = { 'errors': { 'addcost': list(addcost_form.errors) } }
|
||||
data = {'errors': {'addcost': list(addcost_form.errors)}}
|
||||
return JsonResponse(data, status=400)
|
||||
required_perms = ['kfet.manage_addcosts']
|
||||
if not request.user.has_perms(required_perms):
|
||||
data = {
|
||||
'errors': {
|
||||
'missing_perms': get_missing_perms(required_perms, request.user)
|
||||
'missing_perms': get_missing_perms(required_perms,
|
||||
request.user)
|
||||
}
|
||||
}
|
||||
return JsonResponse(data, status=403)
|
||||
|
@ -938,7 +971,8 @@ def kpsul_update_addcost(request):
|
|||
trigramme = addcost_form.cleaned_data['trigramme']
|
||||
account = trigramme and Account.objects.get(trigramme=trigramme) or None
|
||||
Settings.objects.filter(name='ADDCOST_FOR').update(value_account=account)
|
||||
Settings.objects.filter(name='ADDCOST_AMOUNT').update(value_decimal=addcost_form.cleaned_data['amount'])
|
||||
(Settings.objects.filter(name='ADDCOST_AMOUNT')
|
||||
.update(value_decimal=addcost_form.cleaned_data['amount']))
|
||||
cache.delete('ADDCOST_FOR')
|
||||
cache.delete('ADDCOST_AMOUNT')
|
||||
data = {
|
||||
|
@ -950,20 +984,24 @@ def kpsul_update_addcost(request):
|
|||
consumers.KPsul.group_send('kfet.kpsul', data)
|
||||
return JsonResponse(data)
|
||||
|
||||
|
||||
def get_missing_perms(required_perms, user):
|
||||
missing_perms_codenames = [ (perm.split('.'))[1]
|
||||
for perm in required_perms if not user.has_perm(perm)]
|
||||
missing_perms_codenames = [(perm.split('.'))[1]
|
||||
for perm in required_perms
|
||||
if not user.has_perm(perm)]
|
||||
missing_perms = list(
|
||||
Permission.objects
|
||||
.filter(codename__in=missing_perms_codenames)
|
||||
.values_list('name', flat=True))
|
||||
.filter(codename__in=missing_perms_codenames)
|
||||
.values_list('name', flat=True)
|
||||
)
|
||||
return missing_perms
|
||||
|
||||
|
||||
@teamkfet_required
|
||||
def kpsul_perform_operations(request):
|
||||
# Initializing response data
|
||||
data = { 'operationgroup': 0, 'operations': [],
|
||||
'warnings': {}, 'errors': {} }
|
||||
data = {'operationgroup': 0, 'operations': [],
|
||||
'warnings': {}, 'errors': {}}
|
||||
|
||||
# Checking operationgroup
|
||||
operationgroup_form = KPsulOperationGroupForm(request.POST)
|
||||
|
@ -971,7 +1009,7 @@ def kpsul_perform_operations(request):
|
|||
data['errors']['operation_group'] = list(operationgroup_form.errors)
|
||||
|
||||
# Checking operation_formset
|
||||
operation_formset = KPsulOperationFormSet(request.POST)
|
||||
operation_formset = KPsulOperationFormSet(request.POST)
|
||||
if not operation_formset.is_valid():
|
||||
data['errors']['operations'] = list(operation_formset.errors)
|
||||
|
||||
|
@ -980,39 +1018,41 @@ def kpsul_perform_operations(request):
|
|||
return JsonResponse(data, status=400)
|
||||
|
||||
# Pre-saving (no commit)
|
||||
operationgroup = operationgroup_form.save(commit = False)
|
||||
operations = operation_formset.save(commit = False)
|
||||
operationgroup = operationgroup_form.save(commit=False)
|
||||
operations = operation_formset.save(commit=False)
|
||||
|
||||
# Retrieving COF grant
|
||||
cof_grant = Settings.SUBVENTION_COF()
|
||||
# Retrieving addcosts data
|
||||
addcost_amount = Settings.ADDCOST_AMOUNT()
|
||||
addcost_for = Settings.ADDCOST_FOR()
|
||||
addcost_for = Settings.ADDCOST_FOR()
|
||||
|
||||
# Initializing vars
|
||||
required_perms = set() # Required perms to perform all operations
|
||||
required_perms = set() # Required perms to perform all operations
|
||||
cof_grant_divisor = 1 + cof_grant / 100
|
||||
to_addcost_for_balance = 0 # For balance of addcost_for
|
||||
to_checkout_balance = 0 # For balance of selected checkout
|
||||
to_articles_stocks = defaultdict(lambda:0) # For stocks articles
|
||||
is_addcost = (addcost_for and addcost_amount
|
||||
and addcost_for != operationgroup.on_acc)
|
||||
to_addcost_for_balance = 0 # For balance of addcost_for
|
||||
to_checkout_balance = 0 # For balance of selected checkout
|
||||
to_articles_stocks = defaultdict(lambda: 0) # For stocks articles
|
||||
is_addcost = all((addcost_for, addcost_amount,
|
||||
addcost_for != operationgroup.on_acc))
|
||||
need_comment = operationgroup.on_acc.need_comment
|
||||
|
||||
# Filling data of each operations + operationgroup + calculating other stuffs
|
||||
# Filling data of each operations
|
||||
# + operationgroup + calculating other stuffs
|
||||
for operation in operations:
|
||||
if operation.type == Operation.PURCHASE:
|
||||
operation.amount = - operation.article.price * operation.article_nb
|
||||
if is_addcost:
|
||||
operation.addcost_for = addcost_for
|
||||
operation.addcost_amount = addcost_amount * operation.article_nb
|
||||
operation.amount -= operation.addcost_amount
|
||||
to_addcost_for_balance += operation.addcost_amount
|
||||
if is_addcost & operation.article.category.has_addcost:
|
||||
operation.addcost_for = addcost_for
|
||||
operation.addcost_amount = addcost_amount \
|
||||
* operation.article_nb
|
||||
operation.amount -= operation.addcost_amount
|
||||
to_addcost_for_balance += operation.addcost_amount
|
||||
if operationgroup.on_acc.is_cash:
|
||||
to_checkout_balance += -operation.amount
|
||||
if operationgroup.on_acc.is_cof:
|
||||
if is_addcost:
|
||||
operation.addcost_amount = operation.addcost_amount / cof_grant_divisor
|
||||
if is_addcost and operation.article.category.has_addcost:
|
||||
operation.addcost_amount /= cof_grant_divisor
|
||||
operation.amount = operation.amount / cof_grant_divisor
|
||||
to_articles_stocks[operation.article] -= operation.article_nb
|
||||
else:
|
||||
|
@ -1029,8 +1069,10 @@ def kpsul_perform_operations(request):
|
|||
if operationgroup.on_acc.is_cof:
|
||||
to_addcost_for_balance = to_addcost_for_balance / cof_grant_divisor
|
||||
|
||||
(perms, stop) = operationgroup.on_acc.perms_to_perform_operation(
|
||||
amount = operationgroup.amount)
|
||||
(perms, stop) = (operationgroup.on_acc
|
||||
.perms_to_perform_operation(
|
||||
amount=operationgroup.amount)
|
||||
)
|
||||
required_perms |= perms
|
||||
|
||||
if need_comment:
|
||||
|
@ -1061,7 +1103,7 @@ def kpsul_perform_operations(request):
|
|||
# saving account's balance and adding to Negative if not in
|
||||
if not operationgroup.on_acc.is_cash:
|
||||
Account.objects.filter(pk=operationgroup.on_acc.pk).update(
|
||||
balance = F('balance') + operationgroup.amount)
|
||||
balance=F('balance') + operationgroup.amount)
|
||||
operationgroup.on_acc.refresh_from_db()
|
||||
if operationgroup.on_acc.balance < 0:
|
||||
if hasattr(operationgroup.on_acc, 'negative'):
|
||||
|
@ -1070,21 +1112,21 @@ def kpsul_perform_operations(request):
|
|||
operationgroup.on_acc.negative.save()
|
||||
else:
|
||||
negative = AccountNegative(
|
||||
account = operationgroup.on_acc, start = timezone.now())
|
||||
account=operationgroup.on_acc, start=timezone.now())
|
||||
negative.save()
|
||||
elif (hasattr(operationgroup.on_acc, 'negative')
|
||||
and not operationgroup.on_acc.negative.balance_offset):
|
||||
elif (hasattr(operationgroup.on_acc, 'negative') and
|
||||
not operationgroup.on_acc.negative.balance_offset):
|
||||
operationgroup.on_acc.negative.delete()
|
||||
|
||||
# Updating checkout's balance
|
||||
if to_checkout_balance:
|
||||
Checkout.objects.filter(pk=operationgroup.checkout.pk).update(
|
||||
balance = F('balance') + to_checkout_balance)
|
||||
balance=F('balance') + to_checkout_balance)
|
||||
|
||||
# Saving addcost_for with new balance if there is one
|
||||
if is_addcost and to_addcost_for_balance:
|
||||
Account.objects.filter(pk=addcost_for.pk).update(
|
||||
balance = F('balance') + to_addcost_for_balance)
|
||||
balance=F('balance') + to_addcost_for_balance)
|
||||
|
||||
# Saving operation group
|
||||
operationgroup.save()
|
||||
|
@ -1099,7 +1141,7 @@ def kpsul_perform_operations(request):
|
|||
# Updating articles stock
|
||||
for article in to_articles_stocks:
|
||||
Article.objects.filter(pk=article.pk).update(
|
||||
stock = F('stock') + to_articles_stocks[article])
|
||||
stock=F('stock') + to_articles_stocks[article])
|
||||
|
||||
# Websocket data
|
||||
websocket_data = {}
|
||||
|
@ -1111,17 +1153,20 @@ def kpsul_perform_operations(request):
|
|||
'at': operationgroup.at,
|
||||
'is_cof': operationgroup.is_cof,
|
||||
'comment': operationgroup.comment,
|
||||
'valid_by__trigramme': ( operationgroup.valid_by and
|
||||
operationgroup.valid_by.trigramme or None),
|
||||
'valid_by__trigramme': (operationgroup.valid_by and
|
||||
operationgroup.valid_by.trigramme or None),
|
||||
'on_acc__trigramme': operationgroup.on_acc.trigramme,
|
||||
'opes': [],
|
||||
}]
|
||||
for operation in operations:
|
||||
ope_data = {
|
||||
'id': operation.pk, 'type': operation.type, 'amount': operation.amount,
|
||||
'id': operation.pk, 'type': operation.type,
|
||||
'amount': operation.amount,
|
||||
'addcost_amount': operation.addcost_amount,
|
||||
'addcost_for__trigramme': operation.addcost_for and addcost_for.trigramme or None,
|
||||
'article__name': operation.article and operation.article.name or None,
|
||||
'addcost_for__trigramme': (
|
||||
operation.addcost_for and addcost_for.trigramme or None),
|
||||
'article__name': (
|
||||
operation.article and operation.article.name or None),
|
||||
'article_nb': operation.article_nb,
|
||||
'group_id': operationgroup.pk,
|
||||
'canceled_by__trigramme': None, 'canceled_at': None,
|
||||
|
@ -1135,7 +1180,7 @@ def kpsul_perform_operations(request):
|
|||
}]
|
||||
websocket_data['articles'] = []
|
||||
# Need refresh from db cause we used update on querysets
|
||||
articles_pk = [ article.pk for article in to_articles_stocks]
|
||||
articles_pk = [article.pk for article in to_articles_stocks]
|
||||
articles = Article.objects.values('id', 'stock').filter(pk__in=articles_pk)
|
||||
for article in articles:
|
||||
websocket_data['articles'].append({
|
||||
|
@ -1145,6 +1190,7 @@ def kpsul_perform_operations(request):
|
|||
consumers.KPsul.group_send('kfet.kpsul', websocket_data)
|
||||
return JsonResponse(data)
|
||||
|
||||
|
||||
@teamkfet_required
|
||||
def kpsul_cancel_operations(request):
|
||||
# Pour la réponse
|
||||
|
@ -1393,7 +1439,8 @@ def history_json(request):
|
|||
def kpsul_articles_data(request):
|
||||
articles = (
|
||||
Article.objects
|
||||
.values('id', 'name', 'price', 'stock', 'category_id', 'category__name')
|
||||
.values('id', 'name', 'price', 'stock', 'category_id',
|
||||
'category__name', 'category__has_addcost')
|
||||
.filter(is_sold=True))
|
||||
return JsonResponse({ 'articles': list(articles) })
|
||||
|
||||
|
|
Loading…
Reference in a new issue