30 lines
814 B
PHP
30 lines
814 B
PHP
<?php
|
|
function nextInvoiceNo(PDO $pdo, int $year): string {
|
|
$pdo->beginTransaction();
|
|
try {
|
|
// row lock (InnoDB)
|
|
$stmt = $pdo->prepare("SELECT last_number FROM invoice_counters WHERE year = :y FOR UPDATE");
|
|
$stmt->execute([':y' => $year]);
|
|
$row = $stmt->fetch(PDO::FETCH_ASSOC);
|
|
|
|
if (!$row) {
|
|
$last = 0;
|
|
$pdo->prepare("INSERT INTO invoice_counters (year, last_number) VALUES (:y, 0)")
|
|
->execute([':y' => $year]);
|
|
} else {
|
|
$last = (int)$row['last_number'];
|
|
}
|
|
|
|
$next = $last + 1;
|
|
$pdo->prepare("UPDATE invoice_counters SET last_number = :n WHERE year = :y")
|
|
->execute([':n' => $next, ':y' => $year]);
|
|
|
|
$pdo->commit();
|
|
|
|
return sprintf("RE-%d-%04d", $year, $next);
|
|
} catch (Throwable $e) {
|
|
$pdo->rollBack();
|
|
throw $e;
|
|
}
|
|
}
|