// Import Big.js for precise decimal arithmetic import Big from 'big.js'; // Import utility function for handling number conversions import { GetNumber } from "./util.js"; /** * Adds multiple numbers with high precision using Big.js * @param numbers - Array of numbers to add * @returns The sum as a number */ export function Add(...numbers: number[]): number { // Convert potential null/undefined values to numbers numbers = numbers.map(n => GetNumber(n)); if (numbers.length === 0) return 0; // Initialize result with the first number let result = new Big(numbers[0]); // Add each subsequent number to the result using a for loop for (let i = 1; i < numbers.length; i++) { const bigNumber = new Big(numbers[i]); result = result.plus(bigNumber); } // Convert back to JavaScript number type return Number(result.toString()); } /** * Subtracts multiple numbers with high precision using Big.js * @param numbers - Array of numbers where the first is subtracted by all others * @returns The subtraction result as a number */ export function Subtract(...numbers: number[]): number { // Convert potential null/undefined values to numbers numbers = numbers.map(n => GetNumber(n)); if (numbers.length === 0) return 0; // Initialize result with the first number let result = new Big(numbers[0]); // Subtract each subsequent number from the result using a for loop for (let i = 1; i < numbers.length; i++) { const bigNumber = new Big(numbers[i]); result = result.minus(bigNumber); } // Convert back to JavaScript number type return Number(result.toString()); } /** * Multiplies multiple numbers with high precision using Big.js * @param numbers - Array of numbers to multiply * @returns The product as a number */ export function Multiply(...numbers: number[]): number { // Convert potential null/undefined values to numbers numbers = numbers.map(n => GetNumber(n)); if (numbers.length === 0) return 0; if (numbers.length === 1) return numbers[0]; // Initialize result with the first number let result = new Big(numbers[0]); // Multiply each subsequent number with the result using a for loop for (let i = 1; i < numbers.length; i++) { const bigNumber = new Big(numbers[i]); result = result.times(bigNumber); } // Convert back to JavaScript number type return Number(result.toString()); } /** * Divides multiple numbers with high precision using Big.js * @param numbers - Array of numbers where the first is divided by all others * @returns The division result as a number */ export function Divide(...numbers: number[]): number { // Convert potential null/undefined values to numbers numbers = numbers.map(n => GetNumber(n)); if (numbers.length === 0) return 0; if (numbers.length === 1) return numbers[0]; // Initialize result with the first number let result = new Big(numbers[0]); // Divide the result by each subsequent number using a for loop for (let i = 1; i < numbers.length; i++) { // Check for division by zero if (numbers[i] === 0) { throw new Error('Division by zero is not allowed'); } const bigNumber = new Big(numbers[i]); result = result.div(bigNumber); } // Convert back to JavaScript number type return Number(result.toString()); } /** * Calculates discounted or marked-up price based on a percentage * @param originalPrice - The starting price * @param discountPercentage - Percentage to apply (discount or markup) * @param markUp - When true, adds the percentage; when false, subtracts it * @returns The final price after discount/markup as a number */ export function CalcDiscPrice(originalPrice: number, discountPercentage: number, markUp: boolean = false): number { const price = GetNumber(originalPrice); const perc = GetNumber(discountPercentage); const discountAmount = Multiply(price, Divide(perc, 100)); return markUp ? Add(price, discountAmount) : Subtract(price, discountAmount); // Convert inputs to Big.js objects for precision // const price = new Big(GetNumber(originalPrice)); // const percentage = new Big(GetNumber(discountPercentage)).div(100); // // Calculate the amount to add or subtract // const discountAmount = price.mul(percentage); // // Calculate final price directly with Big.js // let result: any; // if (markUp) { // // Perform markup calculation (add the calculated amount) // result = price.plus(discountAmount); // } else { // // Perform discount calculation (subtract the calculated amount) // result = price.minus(discountAmount); // } // const finalPrice = result.toNumber(); // return finalPrice; } /** * Calculates a price with markup applied * @param originalPrice - The starting price * @param markupPercentage - Percentage to mark up by * @returns The final marked-up price as a number */ export function CalcMarkup(originalPrice: number, markupPercentage: number): number { const price = GetNumber(originalPrice); const perc = GetNumber(markupPercentage); const markupAmount = Multiply(price, Divide(perc, 100)); return Add(price, markupAmount); // Convert inputs to Big.js objects for precision // const price = new Big(GetNumber(originalPrice)); // const percentage = new Big(GetNumber(markupPercentage)).div(100); // // Calculate markup amount based on percentage of original price // const markupAmount = price.mul(percentage); // // Add markup amount to original price // const result = price.plus(markupAmount); // return result.toNumber(); } /** * Calculates a price with markdown (discount) applied * @param originalPrice - The starting price * @param markdownPercentage - Percentage to mark down by * @returns The final marked-down price as a number */ export function CalcMarkdown(originalPrice: number, markdownPercentage: number): number { const price = GetNumber(originalPrice); const perc = GetNumber(markdownPercentage); const markdownAmount = Multiply(price, Divide(perc, 100)); return Subtract(price, markdownAmount); // Convert inputs to Big.js objects for precision // const price = new Big(GetNumber(originalPrice)); // const percentage = new Big(GetNumber(markdownPercentage)).div(100); // // Calculate markdown amount based on percentage of original price // const markdownAmount = price.mul(percentage); // // Subtract markdown amount from original price // const result = price.minus(markdownAmount); // return result.toNumber(); } /** * Calculates the margin value as a percentage based on price and cost * @param price - The selling price of the item * @param cost - The cost of the item * @returns The margin value as a percentage */ export function GetMarginValue(price: number, cost: number): number { // Ensure inputs are valid numbers using GetNumber utility const validPrice = GetNumber(price); const validCost = GetNumber(cost); // Calculate margin percentage: ((price - cost) / price) * 100 const margin = Multiply(Divide(Subtract(validPrice, validCost), validPrice), 100); // Return the calculated margin return margin; }