Credit/debit support

This commit is contained in:
Yohann D'ANELLO 2020-03-14 15:13:58 +01:00 committed by Bombar Maxime
parent 321927ba1e
commit 040bb27528
5 changed files with 186 additions and 67 deletions

View File

@ -6,7 +6,7 @@ from rest_polymorphic.serializers import PolymorphicSerializer
from ..models.notes import Note, NoteClub, NoteSpecial, NoteUser, Alias
from ..models.transactions import TransactionTemplate, Transaction, MembershipTransaction, TemplateCategory, \
TemplateTransaction
TemplateTransaction, SpecialTransaction
class NoteSerializer(serializers.ModelSerializer):
@ -144,9 +144,21 @@ class MembershipTransactionSerializer(serializers.ModelSerializer):
fields = '__all__'
class SpecialTransactionSerializer(serializers.ModelSerializer):
"""
REST API Serializer for Special transactions.
The djangorestframework plugin will analyse the model `SpecialTransaction` and parse all fields in the API.
"""
class Meta:
model = SpecialTransaction
fields = '__all__'
class TransactionPolymorphicSerializer(PolymorphicSerializer):
model_serializer_mapping = {
Transaction: TransactionSerializer,
TemplateTransaction: TemplateTransactionSerializer,
MembershipTransaction: MembershipTransactionSerializer,
SpecialTransaction: SpecialTransactionSerializer,
}

View File

@ -165,7 +165,6 @@ class Transaction(PolymorphicModel):
class TemplateTransaction(Transaction):
"""
Special type of :model:`note.Transaction` associated to a :model:`note.TransactionTemplate`.
"""
template = models.ForeignKey(
@ -183,6 +182,27 @@ class TemplateTransaction(Transaction):
return _('template')
class SpecialTransaction(Transaction):
"""
Special type of :model:`note.Transaction` associated to transactions with special notes
"""
last_name = models.CharField(
max_length=255,
verbose_name=_("name"),
)
first_name = models.CharField(
max_length=255,
verbose_name=_("first_name"),
)
bank = models.CharField(
max_length=255,
verbose_name=_("bank")
)
class MembershipTransaction(Transaction):
"""
Special type of :model:`note.Transaction` associated to a :model:`member.Membership`.

View File

@ -37,20 +37,16 @@ class HistoryTable(tables.Table):
.order_by(('-' if is_descending else '') + 'total')
return queryset, True
def render_amount(self, value):
return pretty_money(value)
def render_total(self, value):
return pretty_money(value)
# Django-tables escape strings. That's a wrong thing.
def render_reason(self, value):
return html.unescape(value)
def render_valid(self, value):
return "" if value else ""

View File

@ -10,7 +10,8 @@ from django.views.generic import CreateView, ListView, UpdateView, TemplateView
from django_tables2 import SingleTableView
from .forms import TransactionTemplateForm
from .models import Transaction, TransactionTemplate, Alias, TemplateTransaction
from .models import Transaction, TransactionTemplate, Alias, TemplateTransaction, NoteSpecial
from .models.transactions import SpecialTransaction
from .tables import HistoryTable
@ -30,6 +31,8 @@ class TransactionCreate(LoginRequiredMixin, TemplateView):
context['title'] = _('Transfer money from your account '
'to one or others')
context['polymorphic_ctype'] = ContentType.objects.get_for_model(Transaction).pk
context['special_polymorphic_ctype'] = ContentType.objects.get_for_model(SpecialTransaction).pk
context['special_types'] = NoteSpecial.objects.order_by("special_type").all()
return context

View File

@ -9,7 +9,24 @@ SPDX-License-Identifier: GPL-2.0-or-later
<div class="row">
<div class="col-xl-12">
<button id="switch_mode" class="form-control btn btn-secondary">Passer en mode transfert</button>
<div class="btn-group btn-group-toggle" style="width: 100%" data-toggle="buttons">
<label class="btn btn-sm btn-outline-primary active">
<input type="radio" name="transaction_type" id="type_gift" checked>
Virement
</label>
<label class="btn btn-sm btn-outline-primary">
<input type="radio" name="transaction_type" id="type_transfer">
Transfert
</label>
<label class="btn btn-sm btn-outline-primary">
<input type="radio" name="transaction_type" id="type_credit">
Crédit
</label>
<label class="btn btn-sm btn-outline-primary">
<input type="radio" name="transaction_type" id="type_debit">
Retrait
</label>
</div>
</div>
</div>
@ -31,6 +48,48 @@ SPDX-License-Identifier: GPL-2.0-or-later
</div>
</div>
<div class="col-md-6" id="external_div" style="display: none;">
<div class="card border-success shadow mb-4">
<div class="card-header">
<p class="card-text font-weight-bold">
Paiement externe
</p>
</div>
<ul class="list-group list-group-flush" id="source_note_list">
</ul>
<div class="card-body">
<div class="form-row">
<div class="col-md-12">
<label for="credit_type">Type de transfert :</label>
<select id="credit_type" class="custom-select">
{% for special_type in special_types %}
<option value="{{ special_type.id }}">{{ special_type.special_type }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="form-row">
<div class="col-md-12">
<label for="last_name">Nom :</label>
<input type="text" id="last_name" class="form-control" />
</div>
</div>
<div class="form-row">
<div class="col-md-12">
<label for="first_name">Prénom :</label>
<input type="text" id="first_name" class="form-control" />
</div>
</div>
<div class="form-row">
<div class="col-md-12">
<label for="bank">Banque :</label>
<input type="text" id="bank" class="form-control" />
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12" id="dests_div">
<div class="card border-info shadow mb-4">
<div class="card-header">
@ -75,7 +134,23 @@ SPDX-License-Identifier: GPL-2.0-or-later
sources_notes_display = [];
dests = [];
dests_notes_display = [];
transfer_mode = false;
function reset() {
sources_notes_display.length = 0;
sources.length = 0;
dests_notes_display.length = 0;
dests.length = 0;
$("#source_note_list").html("");
$("#dest_note_list").html("");
$("#source_alias_matched").html("");
$("#dest_alias_matched").html("");
$("#amount").val("");
$("#reason").val("");
$("#last_name").val("");
$("#first_name").val("");
$("#bank").val("");
refreshBalance();
}
$(document).ready(function() {
autoCompleteNote("source_note", "source_alias_matched", "source_note_list", sources, sources_notes_display,
@ -84,22 +159,32 @@ SPDX-License-Identifier: GPL-2.0-or-later
"dest_alias", "dest_note");
});
$("#switch_mode").click(function () {
transfer_mode ^= true;
if (transfer_mode) {
$("#switch_mode").text("Passer en mode virement");
$("#emitters_div").show();
$("#dests_div").attr('class', 'col-md-6');
}
else {
$("#switch_mode").text("Passer en mode transfert");
$("#type_gift").click(function() {
$("#emitters_div").hide();
$("#external_div").hide();
$("#dests_div").attr('class', 'col-md-12');
}
});
$("#type_transfer").click(function() {
$("#emitters_div").show();
$("#external_div").hide();
$("#dests_div").attr('class', 'col-md-6');
});
$("#type_credit").click(function() {
$("#emitters_div").hide();
$("#external_div").show();
$("#dests_div").attr('class', 'col-md-6');
});
$("#type_debit").click(function() {
$("#emitters_div").hide();
$("#external_div").show();
$("#dests_div").attr('class', 'col-md-6');
});
$("#transfer").click(function() {
if (sources_notes_display.length === 0) {
if ($("#type_gift").is(':checked')) {
dests_notes_display.forEach(function (dest) {
$.post("/api/note/transaction/transaction/",
{
@ -120,17 +205,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
+ " vers la note " + dest[0] + " a été fait avec succès !</div>\n";
msgDiv.html(html);
sources_notes_display.length = 0;
sources.length = 0;
dests_notes_display.length = 0;
dests.length = 0;
$("#source_note_list").html("");
$("#dest_note_list").html("");
$("#source_alias_matched").html("");
$("#dest_alias_matched").html("");
$("#amount").val("");
$("#reason").val("");
refreshBalance();
reset();
}).fail(function (err) {
let msgDiv = $("#messages");
let html = msgDiv.html();
@ -139,21 +214,11 @@ SPDX-License-Identifier: GPL-2.0-or-later
+ " vers la note " + dest[0] + " a échoué : " + err.responseText + "</div>\n";
msgDiv.html(html);
sources_notes_display.length = 0;
sources.length = 0;
dests_notes_display.length = 0;
dests.length = 0;
$("#source_note_list").html("");
$("#dest_note_list").html("");
$("#source_alias_matched").html("");
$("#dest_alias_matched").html("");
$("#amount").val("");
$("#reason").val("");
refreshBalance();
reset();
});
});
}
else {
else if ($("#type_transfer").is(':checked')) {
sources_notes_display.forEach(function (source) {
dests_notes_display.forEach(function (dest) {
$.post("/api/note/transaction/transaction/",
@ -175,17 +240,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
+ " vers la note " + dest[0] + " a été fait avec succès !</div>\n";
msgDiv.html(html);
sources_notes_display.length = 0;
sources.length = 0;
dests_notes_display.length = 0;
dests.length = 0;
$("#source_note_list").html("");
$("#dest_note_list").html("");
$("#source_alias_matched").html("");
$("#dest_alias_matched").html("");
$("#amount").val("");
$("#reason").val("");
refreshBalance();
reset();
}).fail(function (err) {
let msgDiv = $("#messages");
let html = msgDiv.html();
@ -194,20 +249,53 @@ SPDX-License-Identifier: GPL-2.0-or-later
+ " vers la note " + dest[0] + " a échoué : " + err.responseText + "</div>\n";
msgDiv.html(html);
sources_notes_display.length = 0;
sources.length = 0;
dests_notes_display.length = 0;
dests.length = 0;
$("#source_note_list").html("");
$("#dest_note_list").html("");
$("#source_alias_matched").html("");
$("#dest_alias_matched").html("");
$("#amount").val("");
$("#reason").val("");
refreshBalance();
reset();
});
});
});
} else if ($("#type_credit").is(':checked') || $("#type_debit").is(':checked')) {
let special_note = $("#credit_type").val();
let user_note = dests_notes_display[0][1];
let source, dest, reason;
if ($("#type_credit").is(':checked')) {
source = special_note;
dest = user_note;
reason = $("#reason").val() + " (Crédit " + $("#credit_type option:selected").text().toLowerCase() + ")";
}
else {
source = user_note;
dest = special_note;
reason = $("#reason").val() + " (Retrait " + $("#credit_type option:selected").text().toLowerCase() + ")";
}
$.post("/api/note/transaction/transaction/",
{
"csrfmiddlewaretoken": CSRF_TOKEN,
"quantity": dest[3],
"amount": $("#amount").val(),
"reason": reason,
"valid": true,
"polymorphic_ctype": {{ special_polymorphic_ctype }},
"resourcetype": "SpecialTransaction",
"source": source,
"destination": dest,
"last_name": $("#last_name").val(),
"first_name": $("#first_name").val(),
"bank": $("#bank").val()
}, function () {
let msgDiv = $("#messages");
let html = msgDiv.html();
html += "<div class=\"alert alert-success\">Le crédit/retrait a bien été effectué !</div>\n";
msgDiv.html(html);
reset();
}).fail(function (err) {
let msgDiv = $("#messages");
let html = msgDiv.html();
html += "<div class=\"alert alert-danger\">Le crédit/transfert a échoué : " + err.responseText + "</div>\n";
msgDiv.html(html);
reset();
});
}
});
</script>