mirror of
https://gitlab.crans.org/bde/nk20
synced 2024-11-26 18:37:12 +00:00
Migration fixes
This commit is contained in:
parent
e9f4795d13
commit
7051294d76
@ -1,422 +0,0 @@
|
|||||||
var LOCK = false
|
|
||||||
|
|
||||||
sources = []
|
|
||||||
sources_notes_display = []
|
|
||||||
dests = []
|
|
||||||
dests_notes_display = []
|
|
||||||
|
|
||||||
function refreshHistory () {
|
|
||||||
$('#history').load('/note/transfer/ #history')
|
|
||||||
}
|
|
||||||
|
|
||||||
function reset (refresh = true) {
|
|
||||||
sources_notes_display.length = 0
|
|
||||||
sources.length = 0
|
|
||||||
dests_notes_display.length = 0
|
|
||||||
dests.length = 0
|
|
||||||
$('#source_note_list').html('')
|
|
||||||
$('#dest_note_list').html('')
|
|
||||||
const source_field = $('#source_note')
|
|
||||||
source_field.val('')
|
|
||||||
const event = jQuery.Event('keyup')
|
|
||||||
event.originalEvent = { charCode: 97 }
|
|
||||||
source_field.trigger(event)
|
|
||||||
source_field.removeClass('is-invalid')
|
|
||||||
source_field.attr('data-original-title', '').tooltip('hide')
|
|
||||||
const dest_field = $('#dest_note')
|
|
||||||
dest_field.val('')
|
|
||||||
dest_field.trigger(event)
|
|
||||||
dest_field.removeClass('is-invalid')
|
|
||||||
dest_field.attr('data-original-title', '').tooltip('hide')
|
|
||||||
const amount_field = $('#amount')
|
|
||||||
amount_field.val('')
|
|
||||||
amount_field.removeClass('is-invalid')
|
|
||||||
$('#amount-required').html('')
|
|
||||||
const reason_field = $('#reason')
|
|
||||||
reason_field.val('')
|
|
||||||
reason_field.removeClass('is-invalid')
|
|
||||||
$('#reason-required').html('')
|
|
||||||
$('#last_name').val('')
|
|
||||||
$('#first_name').val('')
|
|
||||||
$('#bank').val('')
|
|
||||||
$('#user_note').val('')
|
|
||||||
$('#profile_pic').attr('src', '/static/member/img/default_picture.png')
|
|
||||||
$('#profile_pic_link').attr('href', '#')
|
|
||||||
if (refresh) {
|
|
||||||
refreshBalance()
|
|
||||||
refreshHistory()
|
|
||||||
}
|
|
||||||
|
|
||||||
LOCK = false
|
|
||||||
}
|
|
||||||
|
|
||||||
$(document).ready(function () {
|
|
||||||
/**
|
|
||||||
* If we are in credit/debit mode, check that only one note is entered.
|
|
||||||
* More over, get first name and last name to autocomplete fields.
|
|
||||||
*/
|
|
||||||
function checkUniqueNote () {
|
|
||||||
if ($('#type_credit').is(':checked') || $('#type_debit').is(':checked')) {
|
|
||||||
const arr = $('#type_credit').is(':checked') ? dests_notes_display : sources_notes_display
|
|
||||||
|
|
||||||
if (arr.length === 0) { return }
|
|
||||||
|
|
||||||
const last = arr[arr.length - 1]
|
|
||||||
arr.length = 0
|
|
||||||
arr.push(last)
|
|
||||||
|
|
||||||
last.quantity = 1
|
|
||||||
|
|
||||||
if (last.note.club) {
|
|
||||||
$('#last_name').val(last.note.name)
|
|
||||||
$('#first_name').val(last.note.name)
|
|
||||||
}
|
|
||||||
else if (!last.note.user) {
|
|
||||||
$.getJSON('/api/note/note/' + last.note.id + '/?format=json', function (note) {
|
|
||||||
last.note.user = note.user
|
|
||||||
$.getJSON('/api/user/' + last.note.user + '/', function (user) {
|
|
||||||
$('#last_name').val(user.last_name)
|
|
||||||
$('#first_name').val(user.first_name)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
$.getJSON('/api/user/' + last.note.user + '/', function (user) {
|
|
||||||
$('#last_name').val(user.last_name)
|
|
||||||
$('#first_name').val(user.first_name)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
autoCompleteNote('source_note', 'source_note_list', sources, sources_notes_display,
|
|
||||||
'source_alias', 'source_note', 'user_note', 'profile_pic', checkUniqueNote)
|
|
||||||
autoCompleteNote('dest_note', 'dest_note_list', dests, dests_notes_display,
|
|
||||||
'dest_alias', 'dest_note', 'user_note', 'profile_pic', checkUniqueNote)
|
|
||||||
|
|
||||||
const source = $('#source_note')
|
|
||||||
const dest = $('#dest_note')
|
|
||||||
|
|
||||||
$('#type_transfer').change(function () {
|
|
||||||
if (LOCK) { return }
|
|
||||||
|
|
||||||
$('#source_me_div').removeClass('d-none')
|
|
||||||
$('#source_note').removeClass('is-invalid')
|
|
||||||
$('#dest_note').removeClass('is-invalid')
|
|
||||||
$('#special_transaction_div').addClass('d-none')
|
|
||||||
source.removeClass('d-none')
|
|
||||||
$('#source_note_list').removeClass('d-none')
|
|
||||||
$('#credit_type').addClass('d-none')
|
|
||||||
dest.removeClass('d-none')
|
|
||||||
$('#dest_note_list').removeClass('d-none')
|
|
||||||
$('#debit_type').addClass('d-none')
|
|
||||||
|
|
||||||
$('#source_note_label').text(select_emitters_label)
|
|
||||||
$('#dest_note_label').text(select_receveirs_label)
|
|
||||||
|
|
||||||
location.hash = 'transfer'
|
|
||||||
})
|
|
||||||
|
|
||||||
$('#type_credit').change(function () {
|
|
||||||
if (LOCK) { return }
|
|
||||||
|
|
||||||
$('#source_me_div').addClass('d-none')
|
|
||||||
$('#source_note').removeClass('is-invalid')
|
|
||||||
$('#dest_note').removeClass('is-invalid')
|
|
||||||
$('#special_transaction_div').removeClass('d-none')
|
|
||||||
$('#source_note_list').addClass('d-none')
|
|
||||||
$('#dest_note_list').removeClass('d-none')
|
|
||||||
source.addClass('d-none')
|
|
||||||
source.tooltip('hide')
|
|
||||||
$('#credit_type').removeClass('d-none')
|
|
||||||
dest.removeClass('d-none')
|
|
||||||
dest.val('')
|
|
||||||
dest.tooltip('hide')
|
|
||||||
$('#debit_type').addClass('d-none')
|
|
||||||
|
|
||||||
$('#source_note_label').text(transfer_type_label)
|
|
||||||
$('#dest_note_label').text(select_receveir_label)
|
|
||||||
|
|
||||||
if (dests_notes_display.length > 1) {
|
|
||||||
$('#dest_note_list').html('')
|
|
||||||
dests_notes_display.length = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
location.hash = 'credit'
|
|
||||||
})
|
|
||||||
|
|
||||||
$('#type_debit').change(function () {
|
|
||||||
if (LOCK) { return }
|
|
||||||
|
|
||||||
$('#source_me_div').addClass('d-none')
|
|
||||||
$('#source_note').removeClass('is-invalid')
|
|
||||||
$('#dest_note').removeClass('is-invalid')
|
|
||||||
$('#special_transaction_div').removeClass('d-none')
|
|
||||||
$('#source_note_list').removeClass('d-none')
|
|
||||||
$('#dest_note_list').addClass('d-none')
|
|
||||||
source.removeClass('d-none')
|
|
||||||
source.val('')
|
|
||||||
source.tooltip('hide')
|
|
||||||
$('#credit_type').addClass('d-none')
|
|
||||||
dest.addClass('d-none')
|
|
||||||
dest.tooltip('hide')
|
|
||||||
$('#debit_type').removeClass('d-none')
|
|
||||||
|
|
||||||
$('#source_note_label').text(select_emitter_label)
|
|
||||||
$('#dest_note_label').text(transfer_type_label)
|
|
||||||
|
|
||||||
if (sources_notes_display.length > 1) {
|
|
||||||
$('#source_note_list').html('')
|
|
||||||
sources_notes_display.length = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
location.hash = 'debit'
|
|
||||||
})
|
|
||||||
|
|
||||||
$('#credit_type').change(function () {
|
|
||||||
const type = $('#credit_type option:selected').text()
|
|
||||||
if ($('#type_credit').is(':checked')) { source.val(type) } else { dest.val(type) }
|
|
||||||
})
|
|
||||||
|
|
||||||
// Ensure we begin in transfer mode. Removing these lines may cause problems when reloading.
|
|
||||||
const type_transfer = $('#type_transfer') // Default mode
|
|
||||||
type_transfer.removeAttr('checked')
|
|
||||||
$('#type_credit').removeAttr('checked')
|
|
||||||
$('#type_debit').removeAttr('checked')
|
|
||||||
|
|
||||||
if (location.hash) { $('#type_' + location.hash.substr(1)).click() } else { type_transfer.click() }
|
|
||||||
|
|
||||||
$('#source_me').click(function () {
|
|
||||||
if (LOCK) { return }
|
|
||||||
|
|
||||||
// Shortcut to set the current user as the only emitter
|
|
||||||
sources_notes_display.length = 0
|
|
||||||
sources.length = 0
|
|
||||||
$('#source_note_list').html('')
|
|
||||||
|
|
||||||
const source_note = $('#source_note')
|
|
||||||
source_note.focus()
|
|
||||||
source_note.val('')
|
|
||||||
let event = jQuery.Event('keyup')
|
|
||||||
event.originalEvent = { charCode: 97 }
|
|
||||||
source_note.trigger(event)
|
|
||||||
source_note.val(username)
|
|
||||||
event = jQuery.Event('keyup')
|
|
||||||
event.originalEvent = { charCode: 97 }
|
|
||||||
source_note.trigger(event)
|
|
||||||
const fill_note = function () {
|
|
||||||
if (sources.length === 0) {
|
|
||||||
setTimeout(fill_note, 100)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
event = jQuery.Event('keypress')
|
|
||||||
event.originalEvent = { charCode: 13 }
|
|
||||||
source_note.trigger(event)
|
|
||||||
|
|
||||||
source_note.tooltip('hide')
|
|
||||||
source_note.val('')
|
|
||||||
$('#dest_note').focus()
|
|
||||||
}
|
|
||||||
fill_note()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// Make transfer when pressing Enter on the amount section
|
|
||||||
$('#amount, #reason, #last_name, #first_name, #bank').keypress((event) => {
|
|
||||||
if (event.originalEvent.charCode === 13) {
|
|
||||||
$('#btn_transfer').click()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
$('#btn_transfer').click(function () {
|
|
||||||
if (LOCK) { return }
|
|
||||||
|
|
||||||
LOCK = true
|
|
||||||
|
|
||||||
let error = false
|
|
||||||
|
|
||||||
const amount_field = $('#amount')
|
|
||||||
amount_field.removeClass('is-invalid')
|
|
||||||
$('#amount-required').html('')
|
|
||||||
|
|
||||||
const reason_field = $('#reason')
|
|
||||||
reason_field.removeClass('is-invalid')
|
|
||||||
$('#reason-required').html('')
|
|
||||||
|
|
||||||
if (!amount_field.val() || isNaN(amount_field.val()) || amount_field.val() <= 0) {
|
|
||||||
amount_field.addClass('is-invalid')
|
|
||||||
$('#amount-required').html('<strong>' + gettext('This field is required and must contain a decimal positive number.') + '</strong>')
|
|
||||||
error = true
|
|
||||||
}
|
|
||||||
|
|
||||||
const amount = Math.round(100 * amount_field.val())
|
|
||||||
if (amount > 2147483647) {
|
|
||||||
amount_field.addClass('is-invalid')
|
|
||||||
$('#amount-required').html('<strong>' + gettext('The amount must stay under 21,474,836.47 €.') + '</strong>')
|
|
||||||
error = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!reason_field.val() && $('#type_transfer').is(':checked')) {
|
|
||||||
reason_field.addClass('is-invalid')
|
|
||||||
$('#reason-required').html('<strong>' + gettext('This field is required.') + '</strong>')
|
|
||||||
error = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sources_notes_display.length && !$('#type_credit').is(':checked')) {
|
|
||||||
$('#source_note').addClass('is-invalid')
|
|
||||||
error = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dests_notes_display.length && !$('#type_debit').is(':checked')) {
|
|
||||||
$('#dest_note').addClass('is-invalid')
|
|
||||||
error = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
LOCK = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let reason = reason_field.val()
|
|
||||||
|
|
||||||
if ($('#type_transfer').is(':checked')) {
|
|
||||||
// We copy the arrays to ensure that transactions are well-processed even if the form is reset
|
|
||||||
[...sources_notes_display].forEach(function (source) {
|
|
||||||
[...dests_notes_display].forEach(function (dest) {
|
|
||||||
if (source.note.id === dest.note.id) {
|
|
||||||
addMsg(interpolate(gettext('Warning: the transaction of %s from %s to %s was not made because ' +
|
|
||||||
'it is the same source and destination note.'), [pretty_money(amount), source.name, dest.name]), 'warning', 10000)
|
|
||||||
LOCK = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$.post('/api/note/transaction/transaction/',
|
|
||||||
{
|
|
||||||
csrfmiddlewaretoken: CSRF_TOKEN,
|
|
||||||
quantity: source.quantity * dest.quantity,
|
|
||||||
amount: amount,
|
|
||||||
reason: reason,
|
|
||||||
valid: true,
|
|
||||||
polymorphic_ctype: TRANSFER_POLYMORPHIC_CTYPE,
|
|
||||||
resourcetype: 'Transaction',
|
|
||||||
source: source.note.id,
|
|
||||||
source_alias: source.name,
|
|
||||||
destination: dest.note.id,
|
|
||||||
destination_alias: dest.name
|
|
||||||
}).done(function () {
|
|
||||||
if (source.note.membership && source.note.membership.date_end < new Date().toISOString()) {
|
|
||||||
addMsg(interpolate(gettext('Warning, the emitter note %s is no more a BDE member.'), [source.name]), 'danger', 30000)
|
|
||||||
}
|
|
||||||
if (dest.note.membership && dest.note.membership.date_end < new Date().toISOString()) {
|
|
||||||
addMsg(interpolate(gettext('Warning, the destination note %s is no more a BDE member.'), [dest.name]), 'danger', 30000)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isNaN(source.note.balance)) {
|
|
||||||
const newBalance = source.note.balance - source.quantity * dest.quantity * amount
|
|
||||||
if (newBalance <= -2000) {
|
|
||||||
addMsg(interpolate(gettext('Warning, the transaction of %s from the note %s to the note %s succeed, but the emitter note %s is very negative.'),
|
|
||||||
[pretty_money(source.quantity * dest.quantity * amount), source.name, dest.name, source.name]), 'danger', 10000)
|
|
||||||
reset()
|
|
||||||
return
|
|
||||||
} else if (newBalance < 0) {
|
|
||||||
addMsg(interpolate(gettext('Warning, the transaction of %s from the note %s to the note %s succeed, but the emitter note %s is negative.'),
|
|
||||||
[pretty_money(source.quantity * dest.quantity * amount), source.name, dest.name, source.name]), 'danger', 10000)
|
|
||||||
reset()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
addMsg(interpolate(gettext('Transfer of %s from %s to %s succeed!'),
|
|
||||||
[pretty_money(source.quantity * dest.quantity * amount), source.name, dest.name]), 'success', 10000)
|
|
||||||
|
|
||||||
reset()
|
|
||||||
}).fail(function (err) { // do it again but valid = false
|
|
||||||
const errObj = JSON.parse(err.responseText)
|
|
||||||
if (errObj.non_field_errors) {
|
|
||||||
addMsg(interpolate(gettext('Transfer of %s from %s to %s failed: %s'),
|
|
||||||
[pretty_money(source.quantity * dest.quantity * amount), source.name, dest.name, errObj.non_field_errors]), 'danger')
|
|
||||||
LOCK = false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
$.post('/api/note/transaction/transaction/',
|
|
||||||
{
|
|
||||||
csrfmiddlewaretoken: CSRF_TOKEN,
|
|
||||||
quantity: source.quantity * dest.quantity,
|
|
||||||
amount: amount,
|
|
||||||
reason: reason,
|
|
||||||
valid: false,
|
|
||||||
invalidity_reason: 'Solde insuffisant',
|
|
||||||
polymorphic_ctype: TRANSFER_POLYMORPHIC_CTYPE,
|
|
||||||
resourcetype: 'Transaction',
|
|
||||||
source: source.note.id,
|
|
||||||
source_alias: source.name,
|
|
||||||
destination: dest.note.id,
|
|
||||||
destination_alias: dest.name
|
|
||||||
}).done(function () {
|
|
||||||
addMsg(interpolate(gettext('Transfer of %s from %s to %s failed: %s'),
|
|
||||||
[pretty_money(source.quantity * dest.quantity * amount), source.name, dest.name, gettext('insufficient funds')]), 'danger', 10000)
|
|
||||||
reset()
|
|
||||||
}).fail(function (err) {
|
|
||||||
const errObj = JSON.parse(err.responseText)
|
|
||||||
let error = errObj.detail ? errObj.detail : errObj.non_field_errors
|
|
||||||
if (!error) { error = err.responseText }
|
|
||||||
addMsg(interpolate(gettext('Transfer of %s from %s to %s failed: %s'),
|
|
||||||
[pretty_money(source.quantity * dest.quantity * amount), source.name, dest.name, error]), 'danger')
|
|
||||||
LOCK = false
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else if ($('#type_credit').is(':checked') || $('#type_debit').is(':checked')) {
|
|
||||||
let special_note
|
|
||||||
let user_note
|
|
||||||
let alias
|
|
||||||
const given_reason = reason
|
|
||||||
let source_id, dest_id
|
|
||||||
if ($('#type_credit').is(':checked')) {
|
|
||||||
special_note = $('#credit_type').val()
|
|
||||||
user_note = dests_notes_display[0].note
|
|
||||||
alias = dests_notes_display[0].name
|
|
||||||
source_id = special_note
|
|
||||||
dest_id = user_note.id
|
|
||||||
reason = 'Crédit ' + $('#credit_type option:selected').text().toLowerCase()
|
|
||||||
if (given_reason.length > 0) { reason += ' (' + given_reason + ')' }
|
|
||||||
} else {
|
|
||||||
special_note = $('#debit_type').val()
|
|
||||||
user_note = sources_notes_display[0].note
|
|
||||||
alias = sources_notes_display[0].name
|
|
||||||
source_id = user_note.id
|
|
||||||
dest_id = special_note
|
|
||||||
reason = 'Retrait ' + $('#debit_type option:selected').text().toLowerCase()
|
|
||||||
if (given_reason.length > 0) { reason += ' (' + given_reason + ')' }
|
|
||||||
}
|
|
||||||
$.post('/api/note/transaction/transaction/',
|
|
||||||
{
|
|
||||||
csrfmiddlewaretoken: CSRF_TOKEN,
|
|
||||||
quantity: 1,
|
|
||||||
amount: amount,
|
|
||||||
reason: reason,
|
|
||||||
valid: true,
|
|
||||||
polymorphic_ctype: SPECIAL_TRANSFER_POLYMORPHIC_CTYPE,
|
|
||||||
resourcetype: 'SpecialTransaction',
|
|
||||||
source: source_id,
|
|
||||||
source_alias: sources_notes_display.length ? alias : null,
|
|
||||||
destination: dest_id,
|
|
||||||
destination_alias: dests_notes_display.length ? alias : null,
|
|
||||||
last_name: $('#last_name').val(),
|
|
||||||
first_name: $('#first_name').val(),
|
|
||||||
bank: $('#bank').val()
|
|
||||||
}).done(function () {
|
|
||||||
addMsg(gettext('Credit/debit succeed!'), 'success', 10000)
|
|
||||||
if (user_note.membership && user_note.membership.date_end < new Date().toISOString()) { addMsg(gettext('Warning, the emitter note %s is no more a BDE member.'), 'danger', 10000) }
|
|
||||||
reset()
|
|
||||||
}).fail(function (err) {
|
|
||||||
const errObj = JSON.parse(err.responseText)
|
|
||||||
let error = errObj.detail ? errObj.detail : errObj.non_field_errors
|
|
||||||
if (!error) { error = err.responseText }
|
|
||||||
addMsg(interpolate(gettext('Credit/debit failed: %s'), [error]), 'danger', 10000)
|
|
||||||
LOCK = false
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
@ -18,6 +18,7 @@ def create_special_notes(apps, schema_editor):
|
|||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
dependencies = [
|
dependencies = [
|
||||||
('note', '0001_initial'),
|
('note', '0001_initial'),
|
||||||
|
('logs', '0001_initial'),
|
||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
|
Loading…
Reference in New Issue
Block a user