From d0778790db76914260907ea4e98b5d846d06bb66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aaron=20D=C3=B6tsch?= <aaron@fsmpi.rwth-aachen.de> Date: Wed, 12 Jul 2023 14:34:46 +0200 Subject: [PATCH] Add CANT_GO_NEGATIVE flag Until now you could always go into debt. There is a flag so you don't have to pay extra if your balance is negative, but now there also is a flag so you can't even go negative. --- src/components/ItemList.svelte | 14 ++++++++++---- src/lib/flags.js | 1 + src/routes/+page.svelte | 9 ++++++--- src/routes/api/[slug]/+server.js | 1 + 4 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/components/ItemList.svelte b/src/components/ItemList.svelte index 2311f44..bc33036 100644 --- a/src/components/ItemList.svelte +++ b/src/components/ItemList.svelte @@ -3,9 +3,9 @@ import ItemIcon from "./ItemIcon.svelte"; export let items; - export let priceModifier; export let onClick; export let inView; + export let cartWorth, balance, cantGoNegative; let element; </script> @@ -34,17 +34,23 @@ .item__premium { font-size: .8em; } + + .disabled { + opacity: 0.5; + cursor: not-allowed; + } </style> <IntersectionObserver {element} bind:intersecting={inView} rootMargin="0px 0px -50% 0px"> <div class="available-items" bind:this={element}> {#each items as item} - <div class="item" on:click={()=>onClick(item)}> + {@const disabled = cantGoNegative && item.price+item.premium>balance-cartWorth} + <div class="item" class:disabled on:click={()=>onClick(item)}> <ItemIcon icon={item.image} name={item.name} size="100%" containerStyle="margin-bottom:.5em" /> <div class="item__name">{item.name}</div> - <div class="item__price">{(priceModifier(item.price)/100).toFixed(2)}€</div> + <div class="item__price">{(item.price/100).toFixed(2)}€</div> {#if item.premium} - <div class="item__premium">+{(priceModifier(item.premium)/100).toFixed(2)}€</div> + <div class="item__premium">+{(item.premium/100).toFixed(2)}€</div> {/if} </div> {/each} diff --git a/src/lib/flags.js b/src/lib/flags.js index a9b331f..0edc761 100644 --- a/src/lib/flags.js +++ b/src/lib/flags.js @@ -3,4 +3,5 @@ export const Flags = { NO_PREMIUM: 1<<1, NO_BALANCE: 1<<2, CANT_TRANSFER: 1<<3, + CANT_GO_NEGATIVE: 1<<4, }; diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index 65e1304..80efc51 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -23,13 +23,14 @@ let isFetchingBuy = false; let cart = []; - $: cartItems = cart.map(item => { + function getItemFromRaw(item){ if(item.type === "article") return Object.assign({type: "article"}, items.find(i => i.code === item.code)); else if(item.type === "custom") return {type: "custom", name: "Manuell", price: item.price, premium: 0, code: item.code}; else if(item.type === "pfand") return {type: "pfand", name: "Pfand", price: item.price, premium: 0, code: item.code}; else if(item.type === "voucher") return {type: "voucher", name: "Gutschein", price: item.price, premium: 0, code: item.code}; else return addMessage(MessageType.ERROR, "Unbekannter Artikeltyp: " + item.type); - }); + } + $: cartItems = cart.map(item => getItemFromRaw(item)); function emptyCart(){ if(isFetchingBuy) return addMessage(MessageType.ERROR, "Der Kauf wird gerade ausgeführt. Bitte warten..."); cart = []; @@ -37,6 +38,8 @@ } function addToCart(item){ if(isFetchingBuy) return addMessage(MessageType.ERROR, "Der Kauf wird gerade ausgeführt. Bitte warten..."); + let article = getItemFromRaw(item); + if(cartItems.reduce((acc, item)=>acc+item.price+item.premium, 0) + article.price + article.premium > data.user.balance && data.user.perms & Flags.CANT_GO_NEGATIVE) return addMessage(MessageType.WARN, "Nicht genügend Guthaben"); cart = [...cart, item]; resetTimer(); } @@ -313,7 +316,7 @@ {#each categories as category, i} <h2 bind:this={categoryElements[i].element}>{category.name}</h2> <div class="item-list"> - <ItemList items={items.filter(item=>item.categoryId===category.id&&item.show)} onClick={item=>addToCart({type: "article", code: item.code})} priceModifier={x=>x} bind:inView={elementsInView[i]} /> + <ItemList items={items.filter(item=>item.categoryId===category.id&&item.show)} onClick={item=>addToCart({type: "article", code: item.code})} bind:inView={elementsInView[i]} cartWorth={cartItems.reduce((acc,item)=>acc+item.price+item.premium,0)} balance={data.user.balance} cantGoNegative={!!(data.user.perms&Flags.CANT_GO_NEGATIVE)} /> </div> {/each} </div> diff --git a/src/routes/api/[slug]/+server.js b/src/routes/api/[slug]/+server.js index 666681d..d172f41 100644 --- a/src/routes/api/[slug]/+server.js +++ b/src/routes/api/[slug]/+server.js @@ -41,6 +41,7 @@ export async function POST(event) { const priceModifier = getPriceModifier(user.balance, !!(user.perms & Flags.NO_PREMIUM)); if(!isValidCart(data.items, articles, data.vouchers, vouchers, priceModifier)) return new Response(JSON.stringify({message: "Invalid cart"}), {headers: {'content-type': 'application/json', 'status': 400}}); const items = [...data.items, ...data.vouchers.map(voucher => ({...voucher, code: Codes.Voucher}))]; + if(user.perms & Flags.CANT_GO_NEGATIVE && items.reduce((acc, item) => acc + item.price + item.premium, 0) > user.balance) return new Response(JSON.stringify({message: "Not enough balance"}), {headers: {'content-type': 'application/json', 'status': 400}}); const res = await buyArticles(user.id, user.card, items, data.vouchers, !!(user.perms & Flags.NO_BALANCE)); return new Response(JSON.stringify(res), {headers: {'content-type': 'application/json', 'status': 200}}); }catch(e){ -- GitLab