u
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import {
|
||||
formatPriceAmount,
|
||||
grossFromNet,
|
||||
netFromGross,
|
||||
parsePriceInput,
|
||||
} from './price';
|
||||
@@ -156,3 +157,87 @@ export function formatPhotoSizeKb(fullSize) {
|
||||
export function formatPhotoDimensions(fullW, fullH) {
|
||||
return `${fullW}×${fullH}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the sales price (VK-Preis) and tax rate for an article.
|
||||
* Inspects `article.prices` (matching optional `customerGroupId`, falling back to base price),
|
||||
* top-level `article.net` / `article.price` / `article.vknetto`, and calculates gross with optional rebate.
|
||||
*
|
||||
* @param {object|null} article
|
||||
* @param {object} [options]
|
||||
* @param {number|string|null} [options.customerGroupId]
|
||||
* @param {number|string} [options.defaultTaxRate=19]
|
||||
* @param {number|string} [options.rebate=0]
|
||||
* @returns {{ net: number|null, gross: number|null, taxRate: number|null }}
|
||||
*/
|
||||
export function resolveSalesPrice(article, { customerGroupId, defaultTaxRate = 19, rebate = 0 } = {}) {
|
||||
const normTax = defaultTaxRate != null && Number.isFinite(Number(defaultTaxRate)) ? Number(defaultTaxRate) : 19;
|
||||
if (!article) {
|
||||
return { net: null, gross: null, taxRate: normTax };
|
||||
}
|
||||
|
||||
const r = Number.isFinite(Number(rebate)) ? Number(rebate) : 0;
|
||||
|
||||
let matchedPrice = null;
|
||||
if (Array.isArray(article.prices) && article.prices.length > 0) {
|
||||
if (customerGroupId != null) {
|
||||
matchedPrice =
|
||||
article.prices.find(
|
||||
(p) => String(p.customergroupId) === String(customerGroupId) && (p.minmultiplier === 1 || p.minmultiplier == null)
|
||||
) ||
|
||||
article.prices.find((p) => String(p.customergroupId) === String(customerGroupId));
|
||||
}
|
||||
if (!matchedPrice) {
|
||||
matchedPrice = primaryPrice(article);
|
||||
}
|
||||
}
|
||||
|
||||
let net = null;
|
||||
let taxRate = null;
|
||||
let gross = null;
|
||||
|
||||
if (matchedPrice) {
|
||||
if (matchedPrice.net != null && Number.isFinite(Number(matchedPrice.net))) {
|
||||
net = Number(matchedPrice.net);
|
||||
}
|
||||
const rawTax = matchedPrice.taxRate ?? matchedPrice.tax;
|
||||
if (rawTax != null && Number.isFinite(Number(rawTax))) {
|
||||
taxRate = Number(rawTax);
|
||||
}
|
||||
if (matchedPrice.gross != null && Number.isFinite(Number(matchedPrice.gross))) {
|
||||
gross = Number(matchedPrice.gross);
|
||||
} else if (net != null && taxRate != null) {
|
||||
gross = priceBrutto(matchedPrice);
|
||||
}
|
||||
}
|
||||
|
||||
if (net == null) {
|
||||
const rawNet = article.price ?? article.net ?? article.vknetto;
|
||||
if (rawNet != null && Number.isFinite(Number(rawNet))) {
|
||||
net = Number(rawNet);
|
||||
}
|
||||
}
|
||||
|
||||
if (taxRate == null) {
|
||||
const rawTax = article.taxRate ?? article.taxrate ?? article.tax;
|
||||
taxRate = rawTax != null && Number.isFinite(Number(rawTax)) ? Number(rawTax) : normTax;
|
||||
}
|
||||
|
||||
if (gross == null && article.gross != null && Number.isFinite(Number(article.gross))) {
|
||||
gross = Number(article.gross);
|
||||
}
|
||||
|
||||
if (net == null && gross != null && taxRate != null) {
|
||||
net = netFromGross(gross, taxRate, 0);
|
||||
}
|
||||
|
||||
if (net != null && taxRate != null) {
|
||||
if (r !== 0) {
|
||||
gross = grossFromNet(net, taxRate, r);
|
||||
} else if (gross == null) {
|
||||
gross = Math.round((net * (1 + taxRate / 100) + Number.EPSILON) * 100) / 100;
|
||||
}
|
||||
}
|
||||
|
||||
return { net, gross, taxRate };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user