invoicemgmt-1.0.0/src/InvoiceNumberGenerator.php
src/InvoiceNumberGenerator.php
<?php
declare(strict_types=1);
namespace Drupal\invoicemgmt;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
/**
* Service for generating unique invoice numbers.
*/
class InvoiceNumberGenerator {
/**
* The config factory.
*/
protected ConfigFactoryInterface $configFactory;
/**
* The database connection.
*/
protected Connection $database;
/**
* Constructs a new InvoiceNumberGenerator.
*/
public function __construct(ConfigFactoryInterface $config_factory, Connection $database) {
$this->configFactory = $config_factory;
$this->database = $database;
}
/**
* Generates a unique invoice number.
*
* Format: PREFIX-YYYYMM-UNIQUECODE
* Example: INV-202501-001
*/
public function generateInvoiceNumber(): string {
$config = $this->configFactory->get('invoicemgmt.settings');
$prefix = $config->get('invoice_number_prefix') ?: 'INV';
// Get current year and month.
$year_month = date('Ym');
// Generate unique code for this month.
$unique_code = $this->getNextUniqueCode($prefix, $year_month);
return sprintf('%s-%s-%03d', $prefix, $year_month, $unique_code);
}
/**
* Gets the next unique code for the given prefix and year-month.
*/
protected function getNextUniqueCode(string $prefix, string $year_month): int {
$pattern = $prefix . '-' . $year_month . '-%';
// Query to find the highest existing number for this month.
$query = $this->database->select('node__field_invoice_number', 'fin')
->fields('fin', ['field_invoice_number_value'])
->condition('field_invoice_number_value', $pattern, 'LIKE')
->orderBy('field_invoice_number_value', 'DESC')
->range(0, 1);
$result = $query->execute()->fetchField();
if ($result) {
// Extract the numeric part and increment it.
$parts = explode('-', $result);
if (count($parts) === 3 && is_numeric($parts[2])) {
return intval($parts[2]) + 1;
}
}
// Start with 1 if no existing numbers found.
return 1;
}
}
