99 lines
3.3 KiB
PHP
99 lines
3.3 KiB
PHP
<?php
|
|
|
|
namespace Modules\IndustrialEngineering\Services;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Support\Str;
|
|
|
|
class CodeGeneratorService
|
|
{
|
|
/** @var array<string, string> */
|
|
protected array $prefixes = [
|
|
'product' => 'PRD',
|
|
'line' => 'LIN',
|
|
'machine' => 'MCH',
|
|
'item' => 'ITM',
|
|
'revision' => 'REV',
|
|
'bom' => 'BOM',
|
|
'scenario' => 'CST',
|
|
'release' => 'REL',
|
|
'unit' => 'UNT',
|
|
'asset' => 'AST',
|
|
'sourcing' => 'SRC',
|
|
'research' => 'RND',
|
|
'eco' => 'ECO',
|
|
];
|
|
|
|
public function suggest(string $type, int $businessId): string
|
|
{
|
|
$prefix = $this->prefixes[$type] ?? strtoupper(Str::substr($type, 0, 3));
|
|
$year = now()->format('Y');
|
|
$seq = $this->nextSequence($type, $businessId);
|
|
|
|
return sprintf('IE-%s-%s-%04d', $prefix, $year, $seq);
|
|
}
|
|
|
|
/**
|
|
* Resolve user code: manual if provided, otherwise auto-generated unique code.
|
|
*/
|
|
public function resolveCode(string $type, int $businessId, ?string $manualCode, Model $model, string $codeColumn = 'platform_code'): array
|
|
{
|
|
$autoCode = $this->suggest($type, $businessId);
|
|
|
|
while ($this->codeExists($model, $businessId, 'auto_code', $autoCode)) {
|
|
$autoCode = $this->suggest($type, $businessId);
|
|
}
|
|
|
|
$manual = trim((string) $manualCode);
|
|
$effectiveCode = $manual !== '' ? $manual : $autoCode;
|
|
|
|
if ($this->codeExists($model, $businessId, $codeColumn, $effectiveCode)) {
|
|
throw new \InvalidArgumentException(__('industrialengineering::lang.code_already_exists', ['code' => $effectiveCode]));
|
|
}
|
|
|
|
return [
|
|
'auto_code' => $autoCode,
|
|
$codeColumn => $effectiveCode,
|
|
];
|
|
}
|
|
|
|
protected function codeExists(Model $model, int $businessId, string $column, string $code): bool
|
|
{
|
|
$query = $model->newQuery()->where('business_id', $businessId)->where($column, $code);
|
|
|
|
return $query->exists();
|
|
}
|
|
|
|
protected function nextSequence(string $type, int $businessId): int
|
|
{
|
|
$map = [
|
|
'product' => [\Modules\IndustrialEngineering\Models\ProductPlatform::class, 'auto_code'],
|
|
'line' => [\Modules\IndustrialEngineering\Models\LineTemplate::class, 'auto_code'],
|
|
'machine' => [\Modules\IndustrialEngineering\Models\LineTemplate::class, 'auto_code'],
|
|
'item' => [\Modules\IndustrialEngineering\Models\ItemMaster::class, 'auto_code'],
|
|
'revision' => [\Modules\IndustrialEngineering\Models\LineRevision::class, 'auto_code'],
|
|
'bom' => [\Modules\IndustrialEngineering\Models\Bom::class, 'auto_code'],
|
|
'eco' => [\Modules\IndustrialEngineering\Models\EngineeringChangeOrder::class, 'auto_code'],
|
|
];
|
|
|
|
if (! isset($map[$type])) {
|
|
return random_int(1, 9999);
|
|
}
|
|
|
|
[$class, $col] = $map[$type];
|
|
$year = now()->format('Y');
|
|
$prefix = $this->prefixes[$type] ?? 'GEN';
|
|
|
|
$last = $class::where('business_id', $businessId)
|
|
->where($col, 'like', "IE-{$prefix}-{$year}-%")
|
|
->orderByDesc($col)
|
|
->value($col);
|
|
|
|
if (! $last || ! preg_match('/-(\d{4})$/', $last, $m)) {
|
|
return 1;
|
|
}
|
|
|
|
return (int) $m[1] + 1;
|
|
}
|
|
}
|