$lines * @param array{type:string, value:int}|null $adjustment * @return array{lines_net:int, adjustment:int, net:int, tax:int, gross:int} */ public static function totals(array $lines, ?array $adjustment, int $rateBasisPoints): array { $linesNet = 0; foreach ($lines as $line) { $linesNet += self::lineNet((int) $line['unit_net_cents'], (int) $line['quantity_milli']); } $adjusted = $adjustment === null ? 0 : self::adjustment($linesNet, (string) $adjustment['type'], (int) $adjustment['value']); $net = $linesNet + $adjusted; $tax = self::tax($net, $rateBasisPoints); return [ 'lines_net' => $linesNet, 'adjustment' => $adjusted, 'net' => $net, 'tax' => $tax, 'gross' => $net + $tax, ]; } /** "1.234,56" — Austrian formatting, done here so no view invents its own. */ public static function money(int $cents): string { return number_format($cents / 100, 2, ',', '.'); } /** "12", "1,5", "0,25" — trailing zeroes dropped, because "12,000 Std." reads as a defect. */ public static function quantity(int $quantityMilli): string { $formatted = number_format($quantityMilli / 1000, 3, ',', '.'); return rtrim(rtrim($formatted, '0'), ','); } }