Von Hand vergebenes CC-Guthaben ohne Redesign
Der Knopf trug bisher die Regel des Shops: ein CC-Paket ist ein Platz plus ein Redesign. Fuer Einzelfaelle - jemand bekommt einen Platz als Ausgleich, aus einer Absprache, weil etwas schiefging - war das zu viel. "+ CC-Guthaben" schreibt jetzt nur den Platz gut. Wer ein volles Paket nachtragen will, klickt zusaetzlich auf "+ Redesign-Paket". Der Abgleich mit dem Shop bleibt unberuehrt: dort ist ein Paket weiterhin beides, und die Regel dafuer steht unveraendert an einer Stelle. In der Historie steht "CC-Guthaben (von Hand)" statt "CC-Paket" - eine eigene Quelle, damit zu sehen ist, dass kein Kauf dahintersteht. Das Minus daneben nimmt entsprechend diese Zugabe zurueck.
This commit is contained in:
@@ -4,9 +4,9 @@ import { CreditKind, CreditSource } from '@prisma/client';
|
||||
import { requireAdmin, requireEditor } from '../auth/guard.js';
|
||||
import {
|
||||
bookAdjustment,
|
||||
bookCcPackage,
|
||||
bookKulanz,
|
||||
bookRedesignPackage,
|
||||
grantCcSlot,
|
||||
removeLastGrant,
|
||||
reverseGroup,
|
||||
} from '../services/credits.js';
|
||||
@@ -15,10 +15,15 @@ import { contextOf, idParam, optionalNote, parseWith } from './helpers.js';
|
||||
const noteBody = z.object({ note: optionalNote });
|
||||
|
||||
export async function creditRoutes(app: FastifyInstance): Promise<void> {
|
||||
/**
|
||||
* Von Hand einen CC-Platz vergeben - ohne das Redesign, das in einem
|
||||
* gekauften Paket steckt. Der Abgleich mit dem Shop bleibt davon
|
||||
* unberührt: dort ist ein Paket weiterhin beides.
|
||||
*/
|
||||
app.post('/api/players/:id/credits/cc-package', { preHandler: requireEditor }, async (request) => {
|
||||
const { id } = parseWith(idParam, request.params);
|
||||
const body = parseWith(noteBody, request.body ?? {});
|
||||
return bookCcPackage(id, contextOf(request), { note: body.note });
|
||||
return grantCcSlot(id, contextOf(request), { note: body.note });
|
||||
});
|
||||
|
||||
app.post(
|
||||
@@ -50,7 +55,7 @@ export async function creditRoutes(app: FastifyInstance): Promise<void> {
|
||||
{ preHandler: requireEditor },
|
||||
async (request) => {
|
||||
const { id } = parseWith(idParam, request.params);
|
||||
return removeLastGrant(id, CreditSource.CC_PACKAGE, contextOf(request));
|
||||
return removeLastGrant(id, CreditSource.CC_GRANT, contextOf(request));
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -181,6 +181,47 @@ export async function bookCcPackage(
|
||||
return { groupId, balances: await getBalances(playerId) };
|
||||
}
|
||||
|
||||
/**
|
||||
* Vergibt einen CC-Platz von Hand, ohne das Redesign aus einem Paket.
|
||||
*
|
||||
* Ein gekauftes CC-Paket bringt beides mit - so ist es im Shop, und so
|
||||
* bucht es der Abgleich. Von Hand gibt es aber Einzelfälle, in denen jemand
|
||||
* nur einen Platz bekommen soll: als Ausgleich, aus einer Absprache, weil
|
||||
* etwas schiefging. Dafür ist das hier da, und deshalb trägt es eine eigene
|
||||
* Quelle - in der Historie soll zu sehen sein, dass kein Kauf dahintersteht.
|
||||
*/
|
||||
export async function grantCcSlot(
|
||||
playerId: number,
|
||||
ctx: ActionContext,
|
||||
options: { note?: string | undefined } = {},
|
||||
): Promise<{ groupId: string; balances: Balances }> {
|
||||
await requirePlayer(playerId);
|
||||
const groupId = randomUUID();
|
||||
|
||||
await prisma.$transaction(async (tx) => {
|
||||
await tx.creditLedger.create({
|
||||
data: {
|
||||
playerId,
|
||||
kind: CreditKind.CC,
|
||||
amount: 1,
|
||||
source: CreditSource.CC_GRANT,
|
||||
groupId,
|
||||
note: options.note ?? null,
|
||||
createdById: ctx.actorId,
|
||||
},
|
||||
});
|
||||
|
||||
await recordAudit(tx, ctx, {
|
||||
action: 'credit.cc_grant',
|
||||
targetType: 'player',
|
||||
targetId: playerId,
|
||||
details: { groupId, note: options.note ?? null },
|
||||
});
|
||||
});
|
||||
|
||||
return { groupId, balances: await getBalances(playerId) };
|
||||
}
|
||||
|
||||
export async function bookRedesignPackage(
|
||||
playerId: number,
|
||||
ctx: ActionContext,
|
||||
@@ -289,6 +330,7 @@ export async function bookAdjustment(
|
||||
*/
|
||||
/// Was sich über die Knöpfe auf der Spielerseite eintragen lässt.
|
||||
const HANDEINTRAEGE = [
|
||||
CreditSource.CC_GRANT,
|
||||
CreditSource.CC_PACKAGE,
|
||||
CreditSource.REDESIGN_PACKAGE,
|
||||
CreditSource.KULANZ,
|
||||
@@ -326,11 +368,13 @@ export async function removeLastGrant(
|
||||
|
||||
if (!juengste) {
|
||||
const was =
|
||||
source === CreditSource.CC_PACKAGE
|
||||
? 'CC-Paket'
|
||||
: source === CreditSource.REDESIGN_PACKAGE
|
||||
? 'Redesign-Paket'
|
||||
: 'Kulanz';
|
||||
source === CreditSource.CC_GRANT
|
||||
? 'CC-Guthaben'
|
||||
: source === CreditSource.CC_PACKAGE
|
||||
? 'CC-Paket'
|
||||
: source === CreditSource.REDESIGN_PACKAGE
|
||||
? 'Redesign-Paket'
|
||||
: 'Kulanz';
|
||||
throw conflict(
|
||||
'NOTHING_TO_REMOVE',
|
||||
`Es gibt kein von Hand eingetragenes ${was}, das sich zurücknehmen liesse. Aus einem Import gebuchte Pakete werden über die Historie storniert.`,
|
||||
|
||||
Reference in New Issue
Block a user