nodebb-plugin-onekite-calendar 2.0.76 → 2.0.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/admin.js +0 -1
- package/lib/api.js +23 -11
- package/lib/scheduler.js +0 -1
- package/package.json +1 -1
- package/public/admin.js +2 -12
- package/public/client.js +10 -1
package/lib/admin.js
CHANGED
|
@@ -89,7 +89,6 @@ admin.approveReservation = async function (req, res) {
|
|
|
89
89
|
r.pickupLat = String((req.body && req.body.pickupLat) || '').trim();
|
|
90
90
|
r.pickupLon = String((req.body && req.body.pickupLon) || '').trim();
|
|
91
91
|
r.approvedAt = Date.now();
|
|
92
|
-
r.paymentDeferred = !!(req.body && req.body.paymentDeferred);
|
|
93
92
|
|
|
94
93
|
try {
|
|
95
94
|
const approver = await user.getUserFields(req.uid, ['username']);
|
package/lib/api.js
CHANGED
|
@@ -1321,6 +1321,9 @@ api.createReservation = async function (req, res) {
|
|
|
1321
1321
|
|
|
1322
1322
|
const isForSelf = (targetUid === uid);
|
|
1323
1323
|
|
|
1324
|
+
// Explicit regularization flag: admin records a payment directly (any date, any target)
|
|
1325
|
+
const isRegularization = !!isValidator && !!(req.body && req.body.isRegularization);
|
|
1326
|
+
|
|
1324
1327
|
// Free only when validator creates for themselves with a future date (within configured maxDays)
|
|
1325
1328
|
const validatorFreeMaxDays = (() => {
|
|
1326
1329
|
try {
|
|
@@ -1328,10 +1331,17 @@ api.createReservation = async function (req, res) {
|
|
|
1328
1331
|
return Number.isFinite(v) ? v : 0;
|
|
1329
1332
|
} catch (e) { return 0; }
|
|
1330
1333
|
})();
|
|
1331
|
-
const isValidatorFree = !!isValidator && isForSelf && !isPastDate && (validatorFreeMaxDays <= 0 || nbDays <= validatorFreeMaxDays);
|
|
1334
|
+
const isValidatorFree = !!isValidator && !isRegularization && isForSelf && !isPastDate && (validatorFreeMaxDays <= 0 || nbDays <= validatorFreeMaxDays);
|
|
1335
|
+
|
|
1336
|
+
// Past-dated reservation for self → paid immediately (no checkbox needed)
|
|
1337
|
+
const isRegularizationSelf = !!isValidator && !isRegularization && isForSelf && isPastDate;
|
|
1338
|
+
// Past-dated reservation for a third party without explicit regularization → awaiting_payment
|
|
1339
|
+
const isRegularizationOther = !!isValidator && !isRegularization && !isForSelf && isPastDate;
|
|
1332
1340
|
|
|
1333
|
-
|
|
1334
|
-
const
|
|
1341
|
+
const isAutoPaid = isValidatorFree || isRegularizationSelf || isRegularization;
|
|
1342
|
+
const resolvedStatus = isAutoPaid ? 'paid'
|
|
1343
|
+
: isRegularizationOther ? 'awaiting_payment'
|
|
1344
|
+
: 'pending';
|
|
1335
1345
|
|
|
1336
1346
|
const resv = {
|
|
1337
1347
|
rid,
|
|
@@ -1348,14 +1358,15 @@ api.createReservation = async function (req, res) {
|
|
|
1348
1358
|
end,
|
|
1349
1359
|
startDate,
|
|
1350
1360
|
endDate,
|
|
1351
|
-
status:
|
|
1361
|
+
status: resolvedStatus,
|
|
1352
1362
|
createdAt: now,
|
|
1353
|
-
paidAt:
|
|
1354
|
-
|
|
1355
|
-
|
|
1363
|
+
paidAt: isAutoPaid ? now : 0,
|
|
1364
|
+
approvedAt: (isAutoPaid || isRegularizationOther) ? now : 0,
|
|
1365
|
+
approvedBy: (isAutoPaid || isRegularizationOther) ? uid : 0,
|
|
1366
|
+
approvedByUsername: (isAutoPaid || isRegularizationOther) ? (creatorUsername || '') : '',
|
|
1356
1367
|
isFree: !!isValidatorFree,
|
|
1357
1368
|
total: isValidatorFree ? 0 : (isNaN(total) ? 0 : total),
|
|
1358
|
-
manuallyPaid: isRegularization ? true : undefined,
|
|
1369
|
+
manuallyPaid: (isRegularizationSelf || isRegularization) ? true : undefined,
|
|
1359
1370
|
};
|
|
1360
1371
|
|
|
1361
1372
|
// Validator self-reservations are FREE (no payment required) and tracked separately in accounting.
|
|
@@ -1368,7 +1379,8 @@ api.createReservation = async function (req, res) {
|
|
|
1368
1379
|
|
|
1369
1380
|
// Audit
|
|
1370
1381
|
const auditAction = isValidatorFree ? 'reservation_self_checked'
|
|
1371
|
-
: isRegularization ? 'reservation_manually_paid'
|
|
1382
|
+
: (isRegularizationSelf || isRegularization) ? 'reservation_manually_paid'
|
|
1383
|
+
: isRegularizationOther ? 'reservation_regularization_other'
|
|
1372
1384
|
: 'reservation_requested';
|
|
1373
1385
|
await auditLog(auditAction, uid, {
|
|
1374
1386
|
targetType: 'reservation',
|
|
@@ -1385,7 +1397,7 @@ api.createReservation = async function (req, res) {
|
|
|
1385
1397
|
status: resv.status,
|
|
1386
1398
|
});
|
|
1387
1399
|
|
|
1388
|
-
if (!isValidatorFree && !isRegularization) {
|
|
1400
|
+
if (!isValidatorFree && !isRegularizationSelf && !isRegularization) {
|
|
1389
1401
|
|
|
1390
1402
|
|
|
1391
1403
|
// Notify groups by email (NodeBB emailer config)
|
|
@@ -1459,7 +1471,7 @@ api.createReservation = async function (req, res) {
|
|
|
1459
1471
|
|
|
1460
1472
|
}
|
|
1461
1473
|
|
|
1462
|
-
res.json({ ok: true, rid, status: resv.status, autoPaid:
|
|
1474
|
+
res.json({ ok: true, rid, status: resv.status, autoPaid: isAutoPaid });
|
|
1463
1475
|
};
|
|
1464
1476
|
|
|
1465
1477
|
api.searchUsers = async function (req, res) {
|
package/lib/scheduler.js
CHANGED
|
@@ -224,7 +224,6 @@ async function processAwaitingPayment(preIds, preReservations) {
|
|
|
224
224
|
const rid = ids[i];
|
|
225
225
|
const r = reservations[i];
|
|
226
226
|
if (!r || r.status !== 'awaiting_payment') continue;
|
|
227
|
-
if (r.paymentDeferred) continue;
|
|
228
227
|
|
|
229
228
|
const approvedAt = parseInt(r.approvedAt || r.validatedAt || 0, 10) || 0;
|
|
230
229
|
if (!approvedAt) continue;
|
package/package.json
CHANGED
package/public/admin.js
CHANGED
|
@@ -838,10 +838,6 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
838
838
|
<label class="form-label">Heure de récupération</label>
|
|
839
839
|
<select class="form-select" id="onekite-pickup-time">${opts}</select>
|
|
840
840
|
</div>
|
|
841
|
-
<div class="form-check mb-2">
|
|
842
|
-
<input class="form-check-input" type="checkbox" id="onekite-payment-deferred" />
|
|
843
|
-
<label class="form-check-label" for="onekite-payment-deferred">Paiement différé <span class="text-muted" style="font-size:12px;">(pas d'annulation automatique)</span></label>
|
|
844
|
-
</div>
|
|
845
841
|
<div class="text-muted" style="font-size:12px;">Ces infos seront appliquées aux ${rids.length} demandes sélectionnées.</div>
|
|
846
842
|
`;
|
|
847
843
|
const dlg = bootbox.dialog({
|
|
@@ -860,9 +856,8 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
860
856
|
const pickupTime = (document.getElementById('onekite-pickup-time')?.value || '').trim();
|
|
861
857
|
const pickupLat = (document.getElementById('onekite-pickup-lat')?.value || '').trim();
|
|
862
858
|
const pickupLon = (document.getElementById('onekite-pickup-lon')?.value || '').trim();
|
|
863
|
-
const paymentDeferred = !!(document.getElementById('onekite-payment-deferred')?.checked);
|
|
864
859
|
for (const rr of rids) {
|
|
865
|
-
await approve(rr, { pickupAddress, notes, pickupTime, pickupLat, pickupLon
|
|
860
|
+
await approve(rr, { pickupAddress, notes, pickupTime, pickupLat, pickupLon });
|
|
866
861
|
}
|
|
867
862
|
showAlert('success', `${rids.length} demande(s) validée(s).`);
|
|
868
863
|
await refreshPending();
|
|
@@ -1015,10 +1010,6 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
1015
1010
|
<label class="form-label">Heure de récupération</label>
|
|
1016
1011
|
<select class="form-select" id="onekite-pickup-time">${opts}</select>
|
|
1017
1012
|
</div>
|
|
1018
|
-
<div class="form-check mb-2">
|
|
1019
|
-
<input class="form-check-input" type="checkbox" id="onekite-payment-deferred" />
|
|
1020
|
-
<label class="form-check-label" for="onekite-payment-deferred">Paiement différé <span class="text-muted" style="font-size:12px;">(pas d'annulation automatique)</span></label>
|
|
1021
|
-
</div>
|
|
1022
1013
|
`;
|
|
1023
1014
|
|
|
1024
1015
|
const dlg = bootbox.dialog({
|
|
@@ -1037,8 +1028,7 @@ define('admin/plugins/calendar-onekite', ['alerts', 'bootbox'], function (alerts
|
|
|
1037
1028
|
const pickupTime = (document.getElementById('onekite-pickup-time')?.value || '').trim();
|
|
1038
1029
|
const pickupLat = (document.getElementById('onekite-pickup-lat')?.value || '').trim();
|
|
1039
1030
|
const pickupLon = (document.getElementById('onekite-pickup-lon')?.value || '').trim();
|
|
1040
|
-
|
|
1041
|
-
await approve(rid, { pickupAddress, notes, pickupTime, pickupLat, pickupLon, paymentDeferred });
|
|
1031
|
+
await approve(rid, { pickupAddress, notes, pickupTime, pickupLat, pickupLon });
|
|
1042
1032
|
if (rowEl && rowEl.parentNode) rowEl.parentNode.removeChild(rowEl);
|
|
1043
1033
|
showAlert('success', 'Demande validée.');
|
|
1044
1034
|
await refreshPending();
|
package/public/client.js
CHANGED
|
@@ -1229,6 +1229,12 @@ function toDatetimeLocalValue(date) {
|
|
|
1229
1229
|
<label style="font-size:13px; font-weight:600; margin-bottom:3px; display:block;">Pour (pseudo, vide = moi-même)</label>
|
|
1230
1230
|
<input type="text" class="form-control form-control-sm" id="onekite-target-username" placeholder="Pseudo de l'adhérent" autocomplete="off">
|
|
1231
1231
|
</div>
|
|
1232
|
+
<div class="mb-2">
|
|
1233
|
+
<div class="form-check">
|
|
1234
|
+
<input class="form-check-input" type="checkbox" id="onekite-regularization">
|
|
1235
|
+
<label class="form-check-label" for="onekite-regularization" style="font-size:13px;">Régularisation <span class="text-muted" style="font-size:12px;">(passe directement en payé)</span></label>
|
|
1236
|
+
</div>
|
|
1237
|
+
</div>
|
|
1232
1238
|
` : '';
|
|
1233
1239
|
|
|
1234
1240
|
const messageHtml = `
|
|
@@ -1280,7 +1286,8 @@ function toDatetimeLocalValue(date) {
|
|
|
1280
1286
|
// Return the effective end date (exclusive) because duration shortcuts can
|
|
1281
1287
|
// change the range without updating the original FullCalendar selection.
|
|
1282
1288
|
const targetUsername = isValidatorMode ? ((document.getElementById('onekite-target-username') || {}).value || '').trim() : '';
|
|
1283
|
-
|
|
1289
|
+
const isRegularization = isValidatorMode ? !!((document.getElementById('onekite-regularization') || {}).checked) : false;
|
|
1290
|
+
resolve({ itemIds, itemNames, total, days, endDate: toLocalYmd(end), targetUsername, isRegularization });
|
|
1284
1291
|
},
|
|
1285
1292
|
},
|
|
1286
1293
|
},
|
|
@@ -1568,6 +1575,7 @@ function toDatetimeLocalValue(date) {
|
|
|
1568
1575
|
total: chosen.total,
|
|
1569
1576
|
};
|
|
1570
1577
|
if (chosen.targetUsername) reqPayload.targetUsername = chosen.targetUsername;
|
|
1578
|
+
if (chosen.isRegularization) reqPayload.isRegularization = true;
|
|
1571
1579
|
const resp = await requestReservation(reqPayload);
|
|
1572
1580
|
if (resp && (resp.autoPaid || String(resp.status) === 'paid')) {
|
|
1573
1581
|
showAlert('success', chosen.targetUsername ? `Réservation confirmée pour ${chosen.targetUsername}.` : 'Réservation confirmée.');
|
|
@@ -1659,6 +1667,7 @@ function toDatetimeLocalValue(date) {
|
|
|
1659
1667
|
total: chosen.total,
|
|
1660
1668
|
};
|
|
1661
1669
|
if (chosen.targetUsername) reqPayload.targetUsername = chosen.targetUsername;
|
|
1670
|
+
if (chosen.isRegularization) reqPayload.isRegularization = true;
|
|
1662
1671
|
const resp = await requestReservation(reqPayload);
|
|
1663
1672
|
if (resp && (resp.autoPaid || String(resp.status) === 'paid')) {
|
|
1664
1673
|
showAlert('success', chosen.targetUsername ? `Réservation confirmée pour ${chosen.targetUsername}.` : 'Réservation confirmée.');
|