Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 105 additions & 0 deletions src/common/transactionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,106 @@ class TransactionHelper {
}
}

// Rekursive Hilfsfunktion, um das Kreuzprodukt zu berechnen
function cartesianProductHelper(
possiblePrices: PaymentTransactionItem[][],
index: number,
currentProduct: PaymentTransactionItem[],
allProducts: PaymentTransactionItem[][]
): void {
if (index === possiblePrices.length) {
allProducts.push([...currentProduct]);
return;
}

for (const price of possiblePrices[index]) {
currentProduct[index] = price;
cartesianProductHelper(
possiblePrices,
index + 1,
currentProduct,
allProducts
);
}
}

// Funktion, um das Kreuzprodukt aller möglichen Preise für die Elemente in 'items' zu erhalten
function getCrossProduct(
items: PaymentTransactionItem[]
): PaymentTransactionItem[][] {
const possiblePriceList: PaymentTransactionItem[][] = items.map((item) =>
getPossiblePrices(item.product).map((coinamount) => {
item.effective_price = coinamount;
return item;
})
);

const allProducts: PaymentTransactionItem[][] = [];

cartesianProductHelper(possiblePriceList, 0, [], allProducts);

return allProducts;
}

export function findOptimalSolutionForTokenUsage(
account: AccountDto,
items: PaymentTransactionItem[]
): PaymentTransactionItem[][] {
// let rounded = Math.floor(bottleStamps * 0.1)
let bottleStamps = account.balance.BottleStamp ?? 0;
let coffeeStamps = account.balance.CoffeeStamp ?? 0;
let centAmount = account.balance.Cent ?? 0;

// Liste aller möglichen Preis/Token-Kombinationen.
const crossProduct = getCrossProduct(items);

// Listen zusammenfassen zu Gesamtpunkten, Gesamtpreis
const paymentItemSums = crossProduct.map(getPaymentItemSum);

// Elemente aus Liste löschen, die den verfügbaren Punktestand/Geld überschreiten
paymentItemSums.filter(
(coinAmount) =>
!(
(coinAmount.BottleStamp ?? 0) > bottleStamps ||
(coinAmount.CoffeeStamp ?? 0) > coffeeStamps ||
(coinAmount.Cent ?? 0) > centAmount
)
);

// geringsten Preis finden
let smallestPrice: number = paymentItemSums[0].Cent ?? 0; // TODO: Wenn liste leer, kann eig auch abgebrochen werden.
for (let coinAmount of paymentItemSums) {
let sum = coinAmount.Cent ?? 0; // TODO: Was, wenn coinAmount nicht existert? erstmal auf null gesetzt.
if (sum < smallestPrice) smallestPrice = sum;
}

// Elemente für den geringsten Preis finden
crossProduct.filter(
(productList) => getPaymentItemSum(productList).Cent == smallestPrice
);

// geringsten Tokenverbrauch ermitteln
const paymentItemSums_short = crossProduct.map(getPaymentItemSum);

let smallestTokenAmount: number =
(paymentItemSums_short[0].BottleStamp ?? 0) +
(paymentItemSums_short[0].CoffeeStamp ?? 0);
for (let tokenAmount of paymentItemSums_short) {
let sum = (tokenAmount.BottleStamp ?? 0) + (tokenAmount.CoffeeStamp ?? 0);
if (sum < smallestTokenAmount) smallestTokenAmount = sum;
}

// erstbesten Eintrag mit dieser Tokenanzahl finden
crossProduct.filter(
(productList) =>
(getPaymentItemSum(productList).BottleStamp ?? 0) +
(getPaymentItemSum(productList).CoffeeStamp ?? 0) ==
smallestTokenAmount
);

return crossProduct;
}

export function calculateStampPaymentTransactionItems(
account: AccountDto,
items: PaymentTransactionItem[]
Expand All @@ -235,6 +335,11 @@ export function calculateStampPaymentTransactionItems(
items
);

// TODO: Optimale Lösung ist:
// crossProduct[0]
const optimalSolution: PaymentTransactionItem[] =
findOptimalSolutionForTokenUsage(account, items)[0];

let maxPrice: number = 0;
let maxIndex: number = -1;

Expand Down
28 changes: 14 additions & 14 deletions src/dashboardApp/components/transaction/CoinAmountView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type StyledCoinAmountViewProps = {
};
const StyledCoinAmountView = styled.div`
display: flex;
width: 11.5rem;
width: 11.5em;
cursor: default;
user-select: none;
position: relative;
Expand All @@ -24,13 +24,13 @@ const StyledCoinAmountView = styled.div`
content: "";
display: block;
position: absolute;
top: -0.6rem;
left: -1.8rem;
right: -0.6rem;
bottom: -0.6rem;
top: -0.6em;
left: -1.8em;
right: -0.6em;
bottom: -0.6em;
background-color: transparent;
z-index: -1;
border-radius: 0.2rem;
border-radius: 0.2em;
transition: background-color 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}

Expand All @@ -49,7 +49,7 @@ const StyledCoinAmountView = styled.div`
}

svg {
font-size: 1.1rem !important;
font-size: 1.1em !important;
}

&.large {
Expand All @@ -66,21 +66,21 @@ const StyledCoinAmountEntry = styled.div`
display: flex;
align-items: center;
justify-content: right;
width: 3.5rem;
width: 3.5em;

& > span {
line-height: 1rem;
padding-right: 0.2rem;
min-width: 1rem;
padding-top: 0.1rem;
line-height: 1em;
padding-right: 0.2em;
min-width: 1em;
padding-top: 0.1em;
}

&:first-of-type {
width: 4.5rem;
width: 4.5em;
}

&:not(:first-of-type) {
margin-left: 0.5rem;
margin-left: 0.5em;
}
`;

Expand Down