66 lines
2.0 KiB
PHP
66 lines
2.0 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
namespace Esun\OrderNumber\Model;
|
|
|
|
use Magento\Framework\App\ResourceConnection;
|
|
use Magento\Framework\DB\Sequence\SequenceInterface;
|
|
|
|
class WebsiteSequence implements SequenceInterface
|
|
{
|
|
private const TABLE_NAME = 'esun_order_number_sequence';
|
|
|
|
private ?int $lastValue = null;
|
|
|
|
public function __construct(
|
|
private readonly ResourceConnection $resource,
|
|
private readonly Config $config,
|
|
private readonly int $websiteId
|
|
) {
|
|
}
|
|
|
|
public function getCurrentValue(): ?string
|
|
{
|
|
if ($this->lastValue === null) {
|
|
return null;
|
|
}
|
|
|
|
return $this->config->getSiteName($this->websiteId) . $this->lastValue;
|
|
}
|
|
|
|
public function getNextValue(): string
|
|
{
|
|
$connection = $this->resource->getConnection('sales');
|
|
$table = $this->resource->getTableName(self::TABLE_NAME, 'sales');
|
|
$initialLastValue = $this->config->getStartNumber($this->websiteId) - 1;
|
|
|
|
$connection->beginTransaction();
|
|
try {
|
|
// The no-op duplicate update safely creates one counter per Website under concurrency.
|
|
$connection->insertOnDuplicate(
|
|
$table,
|
|
['website_id' => $this->websiteId, 'last_value' => $initialLastValue],
|
|
['website_id']
|
|
);
|
|
$lastValue = (int)$connection->fetchOne(
|
|
$connection->select()
|
|
->from($table, ['last_value'])
|
|
->where('website_id = ?', $this->websiteId)
|
|
->forUpdate(true)
|
|
);
|
|
$this->lastValue = $lastValue + 1;
|
|
$connection->update(
|
|
$table,
|
|
['last_value' => $this->lastValue],
|
|
['website_id = ?' => $this->websiteId]
|
|
);
|
|
$connection->commit();
|
|
} catch (\Throwable $exception) {
|
|
$connection->rollBack();
|
|
throw $exception;
|
|
}
|
|
|
|
return (string)$this->getCurrentValue();
|
|
}
|
|
}
|