ultimatepos/Modules/IndustrialEngineering/Services/CodeGeneratorService.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;
}
}