reduce balance on cart buy

This commit is contained in:
SimonFJ20 2025-03-18 15:02:22 +01:00
parent fcaad4f876
commit 27b633cc1e
2 changed files with 61 additions and 1 deletions

View File

@ -27,6 +27,10 @@ void route_post_carts_purchase(HttpCtx* ctx)
size_t item_amount = req.items.size;
// accumulate product_prices and total
int64_t total_dkk_cent = 0;
ProductPriceVec prices;
product_price_vec_construct(&prices);
@ -38,9 +42,34 @@ void route_post_carts_purchase(HttpCtx* ctx)
RESPOND_SERVER_ERROR(ctx);
goto l0_return;
}
total_dkk_cent += price.price_dkk_cent;
product_price_vec_push(&prices, price);
}
// check and update user balance
User user;
DbRes db_res = db_user_with_id(cx->db, &user, session->user_id);
if (db_res != DbRes_Ok) {
RESPOND_SERVER_ERROR(ctx);
goto l0_return;
}
if (user.balance_dkk_cent < total_dkk_cent) {
RESPOND_JSON(
ctx, 200, "{\"ok\":false,\"message\":\"insufficient funds\"}");
goto l0_return;
}
user.balance_dkk_cent -= total_dkk_cent;
db_res = db_user_update(cx->db, &user);
if (db_res != DbRes_Ok) {
RESPOND_SERVER_ERROR(ctx);
goto l0_return;
}
// assemble receipt
Receipt receipt = {
.id = 0,
.user_id = session->user_id,
@ -59,8 +88,10 @@ void route_post_carts_purchase(HttpCtx* ctx)
});
}
// insert receipt
int64_t receipt_id;
DbRes db_res = db_receipt_insert(cx->db, &receipt, &receipt_id);
db_res = db_receipt_insert(cx->db, &receipt, &receipt_id);
if (db_res != DbRes_Ok) {
RESPOND_SERVER_ERROR(ctx);
goto l0_return;
@ -71,5 +102,6 @@ void route_post_carts_purchase(HttpCtx* ctx)
l0_return:
receipt_destroy(&receipt);
product_price_vec_destroy(&prices);
user_destroy(&user);
carts_purchase_req_destroy(&req);
}

View File

@ -49,6 +49,8 @@ Deno.test("test backend", async (t) => {
assertEquals(sessionUserRes.ok, true);
});
const user1 = await sessionUser(token);
await t.step("test /api/users/balance/add", async () => {
const sessionUserRes = await post<{ ok: boolean }>(
"/api/users/balance/add",
@ -60,6 +62,9 @@ Deno.test("test backend", async (t) => {
assertEquals(sessionUserRes.ok, true);
});
const user2 = await sessionUser(token);
assertNotEquals(user1.balance_dkk_cent, user2.balance_dkk_cent);
await testCartsAndReceipts(t, token!);
await t.step("test /api/sessions/logout", async () => {
@ -76,6 +81,8 @@ Deno.test("test backend", async (t) => {
async function testCartsAndReceipts(t: Deno.TestContext, token: string) {
let receiptId: number | undefined = undefined;
const user1 = await sessionUser(token);
await t.step("test /api/carts/purchase", async () => {
const res = await post<{ ok: boolean; receipt_id: number }>(
"/api/carts/purchase",
@ -92,6 +99,9 @@ async function testCartsAndReceipts(t: Deno.TestContext, token: string) {
receiptId = res.receipt_id;
});
const user2 = await sessionUser(token);
assertNotEquals(user1.balance_dkk_cent, user2.balance_dkk_cent);
if (!receiptId) {
return;
}
@ -125,6 +135,24 @@ async function testCartsAndReceipts(t: Deno.TestContext, token: string) {
});
}
type SessionUser = { id: number; email: string; balance_dkk_cent: number };
async function sessionUser(
token: string,
): Promise<SessionUser> {
const res = await get<{
ok: boolean;
user: SessionUser;
}>(
"/api/sessions/user",
{ "Session-Token": token! },
);
if (!res.ok) {
throw new Error();
}
return res.user;
}
function get<Res>(
path: string,
headers: Record<string, string>,