Refactor employee management by implementing automatic employee number generation, updating national ID handling, and enhancing localization for gender and nationality fields across various resources. Adjust form components and validation logic to improve user experience and data integrity.
This commit is contained in:
@@ -8,14 +8,14 @@ enum Gender: string
|
|||||||
{
|
{
|
||||||
case Male = 'male';
|
case Male = 'male';
|
||||||
case Female = 'female';
|
case Female = 'female';
|
||||||
case Other = 'other';
|
// case Other = 'other';
|
||||||
|
|
||||||
public function label(): string
|
public function label(): string
|
||||||
{
|
{
|
||||||
return match ($this) {
|
return match ($this) {
|
||||||
self::Male => __('enums.gender.male'),
|
self::Male => __('enums.gender.male'),
|
||||||
self::Female => __('enums.gender.female'),
|
self::Female => __('enums.gender.female'),
|
||||||
self::Other => __('enums.gender.other'),
|
// self::Other => __('enums.gender.other'),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ enum Gender: string
|
|||||||
return match ($this) {
|
return match ($this) {
|
||||||
self::Male => 'info',
|
self::Male => 'info',
|
||||||
self::Female => 'pink',
|
self::Female => 'pink',
|
||||||
self::Other => 'gray',
|
// self::Other => 'gray',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ enum Gender: string
|
|||||||
return match ($this) {
|
return match ($this) {
|
||||||
self::Male => 'heroicon-o-user',
|
self::Male => 'heroicon-o-user',
|
||||||
self::Female => 'heroicon-o-user',
|
self::Female => 'heroicon-o-user',
|
||||||
self::Other => 'heroicon-o-users',
|
// self::Other => 'heroicon-o-users',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace App\Exports;
|
namespace App\Exports;
|
||||||
|
|
||||||
use App\Models\Employee;
|
use App\Models\Employee;
|
||||||
|
use App\Support\Countries;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use Illuminate\Database\Eloquent\Builder;
|
||||||
use Maatwebsite\Excel\Concerns\FromQuery;
|
use Maatwebsite\Excel\Concerns\FromQuery;
|
||||||
use Maatwebsite\Excel\Concerns\WithHeadings;
|
use Maatwebsite\Excel\Concerns\WithHeadings;
|
||||||
@@ -39,7 +40,7 @@ class EmployeesExport implements FromQuery, WithHeadings, WithMapping
|
|||||||
return [
|
return [
|
||||||
'Employee Number',
|
'Employee Number',
|
||||||
'Full Name',
|
'Full Name',
|
||||||
'National ID',
|
'Nationality',
|
||||||
'Gender',
|
'Gender',
|
||||||
'Birth Date',
|
'Birth Date',
|
||||||
'Phone',
|
'Phone',
|
||||||
@@ -63,7 +64,7 @@ class EmployeesExport implements FromQuery, WithHeadings, WithMapping
|
|||||||
return [
|
return [
|
||||||
$employee->employee_number,
|
$employee->employee_number,
|
||||||
$employee->full_name,
|
$employee->full_name,
|
||||||
$employee->national_id,
|
Countries::name($employee->national_id) ?? $employee->national_id,
|
||||||
$employee->gender?->value,
|
$employee->gender?->value,
|
||||||
$employee->birth_date?->toDateString(),
|
$employee->birth_date?->toDateString(),
|
||||||
$employee->phone,
|
$employee->phone,
|
||||||
|
|||||||
@@ -5,10 +5,11 @@ namespace App\Filament\Resources\Employees\Schemas;
|
|||||||
use App\Enums\EmploymentStatus;
|
use App\Enums\EmploymentStatus;
|
||||||
use App\Enums\Gender;
|
use App\Enums\Gender;
|
||||||
use App\Filament\Support\HrForm;
|
use App\Filament\Support\HrForm;
|
||||||
|
use App\Support\Countries;
|
||||||
use Filament\Forms\Components\DatePicker;
|
use Filament\Forms\Components\DatePicker;
|
||||||
use Filament\Forms\Components\Select;
|
use Filament\Forms\Components\Select;
|
||||||
use Filament\Forms\Components\TextInput;
|
|
||||||
use Filament\Forms\Components\Textarea;
|
use Filament\Forms\Components\Textarea;
|
||||||
|
use Filament\Forms\Components\TextInput;
|
||||||
use Filament\Schemas\Components\Tabs;
|
use Filament\Schemas\Components\Tabs;
|
||||||
use Filament\Schemas\Components\Tabs\Tab;
|
use Filament\Schemas\Components\Tabs\Tab;
|
||||||
use Filament\Schemas\Schema;
|
use Filament\Schemas\Schema;
|
||||||
@@ -30,24 +31,32 @@ class EmployeeForm
|
|||||||
->imageEditor(),
|
->imageEditor(),
|
||||||
TextInput::make('employee_number')
|
TextInput::make('employee_number')
|
||||||
->label(__('hr.fields.employee_number'))
|
->label(__('hr.fields.employee_number'))
|
||||||
->required()
|
->disabled()
|
||||||
->maxLength(50)
|
->dehydrated(false)
|
||||||
->unique(ignoreRecord: true),
|
->visibleOn('edit'),
|
||||||
TextInput::make('full_name')
|
TextInput::make('full_name')
|
||||||
->label(__('hr.fields.full_name'))
|
->label(__('hr.fields.full_name'))
|
||||||
->required()
|
->required()
|
||||||
->maxLength(255),
|
->maxLength(255),
|
||||||
TextInput::make('national_id')
|
Select::make('national_id')
|
||||||
->label(__('hr.fields.national_id'))
|
->label(__('hr.fields.national_id'))
|
||||||
->maxLength(50),
|
->options(fn (): array => Countries::options())
|
||||||
|
->searchable()
|
||||||
|
->native(false)
|
||||||
|
->default(Countries::default())
|
||||||
|
->required(),
|
||||||
|
|
||||||
Select::make('gender')
|
Select::make('gender')
|
||||||
->label(__('hr.fields.gender'))
|
->label(__('hr.fields.gender'))
|
||||||
->options(Gender::class)
|
->options(Gender::class)
|
||||||
->required()
|
->required()
|
||||||
->native(false),
|
->native(false),
|
||||||
|
|
||||||
DatePicker::make('birth_date')
|
DatePicker::make('birth_date')
|
||||||
->label(__('hr.fields.birth_date'))
|
->label(__('hr.fields.birth_date'))
|
||||||
->required(),
|
->required()
|
||||||
|
->native(false),
|
||||||
|
|
||||||
TextInput::make('phone')
|
TextInput::make('phone')
|
||||||
->label(__('hr.fields.phone'))
|
->label(__('hr.fields.phone'))
|
||||||
->tel()
|
->tel()
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ use App\Enums\Gender;
|
|||||||
use App\Models\Employee;
|
use App\Models\Employee;
|
||||||
use App\Models\Vacation;
|
use App\Models\Vacation;
|
||||||
use App\Services\Employee\EmployeeStatisticsService;
|
use App\Services\Employee\EmployeeStatisticsService;
|
||||||
|
use App\Support\Countries;
|
||||||
use Filament\Infolists\Components\ImageEntry;
|
use Filament\Infolists\Components\ImageEntry;
|
||||||
use Filament\Infolists\Components\TextEntry;
|
use Filament\Infolists\Components\TextEntry;
|
||||||
use Filament\Schemas\Components\Section;
|
use Filament\Schemas\Components\Section;
|
||||||
@@ -42,6 +43,7 @@ class EmployeeInfolist
|
|||||||
->label(__('hr.fields.full_name')),
|
->label(__('hr.fields.full_name')),
|
||||||
TextEntry::make('national_id')
|
TextEntry::make('national_id')
|
||||||
->label(__('hr.fields.national_id'))
|
->label(__('hr.fields.national_id'))
|
||||||
|
->formatStateUsing(fn (?string $state): string => Countries::name($state) ?? $state ?? '—')
|
||||||
->placeholder('—'),
|
->placeholder('—'),
|
||||||
TextEntry::make('gender')
|
TextEntry::make('gender')
|
||||||
->label(__('hr.fields.gender'))
|
->label(__('hr.fields.gender'))
|
||||||
@@ -153,16 +155,16 @@ class EmployeeInfolist
|
|||||||
TextEntry::make('leave_balance_taken')
|
TextEntry::make('leave_balance_taken')
|
||||||
->label(__('hr.fields.days_taken'))
|
->label(__('hr.fields.days_taken'))
|
||||||
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->vacationTaken)
|
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->vacationTaken)
|
||||||
->suffix(' ' . __('hr.messages.days_suffix')),
|
->suffix(' '.__('hr.messages.days_suffix')),
|
||||||
TextEntry::make('leave_balance_remaining')
|
TextEntry::make('leave_balance_remaining')
|
||||||
->label(__('hr.fields.days_remaining'))
|
->label(__('hr.fields.days_remaining'))
|
||||||
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->vacationRemaining)
|
->state(fn (Employee $record): int => app(EmployeeStatisticsService::class)->summary($record)->vacationRemaining)
|
||||||
->suffix(' ' . __('hr.messages.days_suffix'))
|
->suffix(' '.__('hr.messages.days_suffix'))
|
||||||
->color('success'),
|
->color('success'),
|
||||||
TextEntry::make('leave_balance_total')
|
TextEntry::make('leave_balance_total')
|
||||||
->label(__('hr.fields.annual_allowance'))
|
->label(__('hr.fields.annual_allowance'))
|
||||||
->state(fn (): int => (int) config('hr.annual_leave_days'))
|
->state(fn (): int => (int) config('hr.annual_leave_days'))
|
||||||
->suffix(' ' . __('hr.messages.days_suffix')),
|
->suffix(' '.__('hr.messages.days_suffix')),
|
||||||
])
|
])
|
||||||
->columns(3),
|
->columns(3),
|
||||||
Section::make(__('hr.sections.upcoming_approved_leave'))
|
Section::make(__('hr.sections.upcoming_approved_leave'))
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ namespace App\Filament\Resources\Employees\Tables;
|
|||||||
|
|
||||||
use App\Enums\EmploymentStatus;
|
use App\Enums\EmploymentStatus;
|
||||||
use App\Enums\Gender;
|
use App\Enums\Gender;
|
||||||
|
use App\Exports\EmployeesExport;
|
||||||
|
use App\Filament\Support\ExportExcelAction;
|
||||||
use App\Models\Department;
|
use App\Models\Department;
|
||||||
use App\Models\Employee;
|
use App\Models\Employee;
|
||||||
use App\Filament\Support\ExportExcelAction;
|
use App\Support\Countries;
|
||||||
use Filament\Actions\BulkAction;
|
use Filament\Actions\BulkAction;
|
||||||
use Filament\Actions\BulkActionGroup;
|
use Filament\Actions\BulkActionGroup;
|
||||||
use Filament\Actions\DeleteBulkAction;
|
use Filament\Actions\DeleteBulkAction;
|
||||||
@@ -37,6 +39,7 @@ class EmployeesTable
|
|||||||
->sortable(),
|
->sortable(),
|
||||||
TextColumn::make('national_id')
|
TextColumn::make('national_id')
|
||||||
->label(__('hr.fields.national_id'))
|
->label(__('hr.fields.national_id'))
|
||||||
|
->formatStateUsing(fn (?string $state): ?string => Countries::name($state) ?? $state)
|
||||||
->searchable()
|
->searchable()
|
||||||
->toggleable(),
|
->toggleable(),
|
||||||
TextColumn::make('gender')
|
TextColumn::make('gender')
|
||||||
@@ -126,7 +129,7 @@ class EmployeesTable
|
|||||||
])
|
])
|
||||||
->toolbarActions([
|
->toolbarActions([
|
||||||
BulkActionGroup::make([
|
BulkActionGroup::make([
|
||||||
ExportExcelAction::bulk('exportSelected', \App\Exports\EmployeesExport::class, 'employees.xlsx'),
|
ExportExcelAction::bulk('exportSelected', EmployeesExport::class, 'employees.xlsx'),
|
||||||
BulkAction::make('changeDepartment')
|
BulkAction::make('changeDepartment')
|
||||||
->label(__('hr.actions.change_department'))
|
->label(__('hr.actions.change_department'))
|
||||||
->icon('heroicon-o-building-office-2')
|
->icon('heroicon-o-building-office-2')
|
||||||
|
|||||||
30
app/Http/Middleware/SetLocale.php
Normal file
30
app/Http/Middleware/SetLocale.php
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Middleware;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class SetLocale
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Handle an incoming request.
|
||||||
|
*
|
||||||
|
* @param Closure(Request): (Response) $next
|
||||||
|
*/
|
||||||
|
public function handle(Request $request, Closure $next): Response
|
||||||
|
{
|
||||||
|
if (! $request->user()) {
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
$locale = $request->user()->locale;
|
||||||
|
|
||||||
|
if (isset($locale)) {
|
||||||
|
app()->setLocale($locale);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $next($request);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -48,6 +48,38 @@ class Employee extends Model
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected static function booted(): void
|
||||||
|
{
|
||||||
|
static::saving(function (Employee $employee): void {
|
||||||
|
if (blank($employee->employee_number)) {
|
||||||
|
$employee->employee_number = static::generateUniqueEmployeeNumber();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function generateUniqueEmployeeNumber(): string
|
||||||
|
{
|
||||||
|
$prefix = (string) config('hr.employee_number.prefix', 'EMP-');
|
||||||
|
$padding = (int) config('hr.employee_number.padding', 5);
|
||||||
|
|
||||||
|
$latestNumber = static::withTrashed()
|
||||||
|
->where('employee_number', 'like', $prefix.'%')
|
||||||
|
->pluck('employee_number')
|
||||||
|
->map(function (string $number) use ($prefix): ?int {
|
||||||
|
if (! preg_match('/^'.preg_quote($prefix, '/').'(\d+)$/', $number, $matches)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int) $matches[1];
|
||||||
|
})
|
||||||
|
->filter()
|
||||||
|
->max();
|
||||||
|
|
||||||
|
$next = ($latestNumber ?? 0) + 1;
|
||||||
|
|
||||||
|
return $prefix.str_pad((string) $next, $padding, '0', STR_PAD_LEFT);
|
||||||
|
}
|
||||||
|
|
||||||
public function department(): BelongsTo
|
public function department(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Department::class);
|
return $this->belongsTo(Department::class);
|
||||||
|
|||||||
@@ -4,13 +4,15 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace App\Providers\Filament;
|
namespace App\Providers\Filament;
|
||||||
|
|
||||||
use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
|
use App\Enums\NavigationGroup as NavigationGroupEnum;
|
||||||
use App\Enums\NavigationGroup;
|
|
||||||
use App\Filament\Pages\Dashboard;
|
use App\Filament\Pages\Dashboard;
|
||||||
|
use BezhanSalleh\FilamentShield\FilamentShieldPlugin;
|
||||||
|
use Filament\FontProviders\GoogleFontProvider;
|
||||||
use Filament\Http\Middleware\Authenticate;
|
use Filament\Http\Middleware\Authenticate;
|
||||||
use Filament\Http\Middleware\AuthenticateSession;
|
use Filament\Http\Middleware\AuthenticateSession;
|
||||||
use Filament\Http\Middleware\DisableBladeIconComponents;
|
use Filament\Http\Middleware\DisableBladeIconComponents;
|
||||||
use Filament\Http\Middleware\DispatchServingFilamentEvent;
|
use Filament\Http\Middleware\DispatchServingFilamentEvent;
|
||||||
|
use Filament\Navigation\NavigationGroup as FilamentNavigationGroup;
|
||||||
use Filament\Panel;
|
use Filament\Panel;
|
||||||
use Filament\PanelProvider;
|
use Filament\PanelProvider;
|
||||||
use Filament\Support\Colors\Color;
|
use Filament\Support\Colors\Color;
|
||||||
@@ -20,7 +22,6 @@ use Illuminate\Foundation\Http\Middleware\PreventRequestForgery;
|
|||||||
use Illuminate\Routing\Middleware\SubstituteBindings;
|
use Illuminate\Routing\Middleware\SubstituteBindings;
|
||||||
use Illuminate\Session\Middleware\StartSession;
|
use Illuminate\Session\Middleware\StartSession;
|
||||||
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
use Illuminate\View\Middleware\ShareErrorsFromSession;
|
||||||
use Filament\FontProviders\GoogleFontProvider;
|
|
||||||
|
|
||||||
class AdminPanelProvider extends PanelProvider
|
class AdminPanelProvider extends PanelProvider
|
||||||
{
|
{
|
||||||
@@ -39,7 +40,14 @@ class AdminPanelProvider extends PanelProvider
|
|||||||
'gray' => Color::Slate,
|
'gray' => Color::Slate,
|
||||||
])
|
])
|
||||||
->font('Inter', provider: GoogleFontProvider::class)
|
->font('Inter', provider: GoogleFontProvider::class)
|
||||||
->navigationGroups(NavigationGroup::class)
|
->navigationGroups(
|
||||||
|
collect(NavigationGroupEnum::cases())
|
||||||
|
->mapWithKeys(fn (NavigationGroupEnum $case): array => [
|
||||||
|
$case->name => FilamentNavigationGroup::make()
|
||||||
|
->label(fn (): ?string => $case->getLabel()),
|
||||||
|
])
|
||||||
|
->all(),
|
||||||
|
)
|
||||||
->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources')
|
->discoverResources(in: app_path('Filament/Resources'), for: 'App\Filament\Resources')
|
||||||
->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages')
|
->discoverPages(in: app_path('Filament/Pages'), for: 'App\Filament\Pages')
|
||||||
->pages([
|
->pages([
|
||||||
@@ -49,7 +57,7 @@ class AdminPanelProvider extends PanelProvider
|
|||||||
->widgets([])
|
->widgets([])
|
||||||
->plugins([
|
->plugins([
|
||||||
FilamentShieldPlugin::make()
|
FilamentShieldPlugin::make()
|
||||||
->navigationGroup(NavigationGroup::System),
|
->navigationGroup(NavigationGroupEnum::System),
|
||||||
])
|
])
|
||||||
->middleware([
|
->middleware([
|
||||||
EncryptCookies::class,
|
EncryptCookies::class,
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ use App\Models\Department;
|
|||||||
use App\Models\Employee;
|
use App\Models\Employee;
|
||||||
use App\Models\Position;
|
use App\Models\Position;
|
||||||
use App\Models\Shift;
|
use App\Models\Shift;
|
||||||
|
use App\Support\Countries;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
|
||||||
@@ -22,9 +23,9 @@ class EmployeeImportTransformer
|
|||||||
public function toAttributes(EmployeeRowDto $dto): array
|
public function toAttributes(EmployeeRowDto $dto): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'employee_number' => $dto->employeeNumber,
|
'employee_number' => $dto->employeeNumber !== '' ? $dto->employeeNumber : null,
|
||||||
'full_name' => $dto->fullName,
|
'full_name' => $dto->fullName,
|
||||||
'national_id' => $dto->nationalId,
|
'national_id' => $this->resolveNationality($dto->nationalId),
|
||||||
'gender' => $this->resolveGender($dto->gender),
|
'gender' => $this->resolveGender($dto->gender),
|
||||||
'birth_date' => $this->parseDate($dto->birthDate),
|
'birth_date' => $this->parseDate($dto->birthDate),
|
||||||
'phone' => $dto->phone ?? config('hr.default_phone'),
|
'phone' => $dto->phone ?? config('hr.default_phone'),
|
||||||
@@ -45,10 +46,6 @@ class EmployeeImportTransformer
|
|||||||
{
|
{
|
||||||
$errors = [];
|
$errors = [];
|
||||||
|
|
||||||
if ($dto->employeeNumber === '') {
|
|
||||||
$errors[] = 'Employee number is required.';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($dto->fullName === '') {
|
if ($dto->fullName === '') {
|
||||||
$errors[] = 'Full name is required.';
|
$errors[] = 'Full name is required.';
|
||||||
}
|
}
|
||||||
@@ -65,22 +62,42 @@ class EmployeeImportTransformer
|
|||||||
$errors[] = "Shift \"{$dto->shift}\" was not found.";
|
$errors[] = "Shift \"{$dto->shift}\" was not found.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($dto->nationalId && $this->resolveNationality($dto->nationalId) === null) {
|
||||||
|
$errors[] = "Nationality \"{$dto->nationalId}\" was not found.";
|
||||||
|
}
|
||||||
|
|
||||||
return $errors;
|
return $errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function isDuplicate(EmployeeRowDto $dto): bool
|
public function isDuplicate(EmployeeRowDto $dto): bool
|
||||||
{
|
{
|
||||||
return Employee::query()
|
$hasEmployeeNumber = $dto->employeeNumber !== '';
|
||||||
->where(function ($query) use ($dto): void {
|
$nationality = $this->resolveNationality($dto->nationalId);
|
||||||
$query->where('employee_number', $dto->employeeNumber);
|
|
||||||
|
|
||||||
if ($dto->nationalId) {
|
if (! $hasEmployeeNumber && $nationality === null) {
|
||||||
$query->orWhere('national_id', $dto->nationalId);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Employee::query()
|
||||||
|
->where(function ($query) use ($dto, $hasEmployeeNumber, $nationality): void {
|
||||||
|
if ($hasEmployeeNumber) {
|
||||||
|
$query->where('employee_number', $dto->employeeNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($nationality !== null) {
|
||||||
|
$hasEmployeeNumber
|
||||||
|
? $query->orWhere('national_id', $nationality)
|
||||||
|
: $query->where('national_id', $nationality);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
->exists();
|
->exists();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function resolveNationality(?string $value): ?string
|
||||||
|
{
|
||||||
|
return Countries::resolve($value);
|
||||||
|
}
|
||||||
|
|
||||||
private function resolveGender(?string $value): ?Gender
|
private function resolveGender(?string $value): ?Gender
|
||||||
{
|
{
|
||||||
if ($value === null) {
|
if ($value === null) {
|
||||||
|
|||||||
124
app/Support/Countries.php
Normal file
124
app/Support/Countries.php
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Support;
|
||||||
|
|
||||||
|
class Countries
|
||||||
|
{
|
||||||
|
public const DEFAULT = 'TM';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
|
public static function codes(): array
|
||||||
|
{
|
||||||
|
/** @var array{codes: array<int, string>} $config */
|
||||||
|
$config = config('countries');
|
||||||
|
|
||||||
|
return $config['codes'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
|
public static function options(?string $locale = null): array
|
||||||
|
{
|
||||||
|
$locale ??= app()->getLocale();
|
||||||
|
$options = [];
|
||||||
|
|
||||||
|
foreach (self::codes() as $code) {
|
||||||
|
$name = self::name($code, $locale);
|
||||||
|
|
||||||
|
if ($name !== null) {
|
||||||
|
$options[$code] = $name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uasort($options, fn (string $a, string $b): int => strcasecmp($a, $b));
|
||||||
|
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function name(?string $code, ?string $locale = null): ?string
|
||||||
|
{
|
||||||
|
if ($code === null || $code === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$code = strtoupper($code);
|
||||||
|
$locale ??= app()->getLocale();
|
||||||
|
|
||||||
|
$name = self::translation($code, $locale);
|
||||||
|
|
||||||
|
if ($name === null && $locale !== 'en') {
|
||||||
|
$name = self::translation($code, 'en');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isValid(?string $code): bool
|
||||||
|
{
|
||||||
|
if ($code === null || $code === '') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return in_array(strtoupper($code), self::codes(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function resolve(?string $value, ?string $locale = null): ?string
|
||||||
|
{
|
||||||
|
if ($value === null || trim($value) === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$value = trim($value);
|
||||||
|
$upper = strtoupper($value);
|
||||||
|
|
||||||
|
if (self::isValid($upper)) {
|
||||||
|
return $upper;
|
||||||
|
}
|
||||||
|
|
||||||
|
$locale ??= app()->getLocale();
|
||||||
|
|
||||||
|
foreach (self::codes() as $code) {
|
||||||
|
$name = self::name($code, $locale);
|
||||||
|
|
||||||
|
if ($name !== null && strcasecmp($name, $value) === 0) {
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($locale !== 'en') {
|
||||||
|
foreach (self::codes() as $code) {
|
||||||
|
$name = self::name($code, 'en');
|
||||||
|
|
||||||
|
if ($name !== null && strcasecmp($name, $value) === 0) {
|
||||||
|
return $code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function translation(string $code, string $locale): ?string
|
||||||
|
{
|
||||||
|
$path = lang_path("{$locale}/countries.php");
|
||||||
|
|
||||||
|
if (! is_file($path)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @var array<string, string> $names */
|
||||||
|
$names = require $path;
|
||||||
|
|
||||||
|
return $names[$code] ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function default(): string
|
||||||
|
{
|
||||||
|
return self::DEFAULT;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ use Illuminate\Foundation\Application;
|
|||||||
use Illuminate\Foundation\Configuration\Exceptions;
|
use Illuminate\Foundation\Configuration\Exceptions;
|
||||||
use Illuminate\Foundation\Configuration\Middleware;
|
use Illuminate\Foundation\Configuration\Middleware;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use App\Http\Middleware\SetLocale;
|
||||||
|
|
||||||
return Application::configure(basePath: dirname(__DIR__))
|
return Application::configure(basePath: dirname(__DIR__))
|
||||||
->withRouting(
|
->withRouting(
|
||||||
@@ -12,7 +13,7 @@ return Application::configure(basePath: dirname(__DIR__))
|
|||||||
health: '/up',
|
health: '/up',
|
||||||
)
|
)
|
||||||
->withMiddleware(function (Middleware $middleware): void {
|
->withMiddleware(function (Middleware $middleware): void {
|
||||||
//
|
// $middleware->web(SetLocale::class);
|
||||||
})
|
})
|
||||||
->withExceptions(function (Exceptions $exceptions): void {
|
->withExceptions(function (Exceptions $exceptions): void {
|
||||||
$exceptions->shouldRenderJsonWhen(
|
$exceptions->shouldRenderJsonWhen(
|
||||||
|
|||||||
204
config/countries.php
Normal file
204
config/countries.php
Normal file
@@ -0,0 +1,204 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'codes' => [
|
||||||
|
0 => 'TM',
|
||||||
|
1 => 'RU',
|
||||||
|
2 => 'KZ',
|
||||||
|
3 => 'UZ',
|
||||||
|
4 => 'TR',
|
||||||
|
5 => 'IR',
|
||||||
|
6 => 'AF',
|
||||||
|
7 => 'AZ',
|
||||||
|
8 => 'KG',
|
||||||
|
9 => 'TJ',
|
||||||
|
10 => 'UA',
|
||||||
|
11 => 'CN',
|
||||||
|
12 => 'DE',
|
||||||
|
13 => 'US',
|
||||||
|
14 => 'GB',
|
||||||
|
15 => 'AD',
|
||||||
|
16 => 'AE',
|
||||||
|
17 => 'AG',
|
||||||
|
18 => 'AL',
|
||||||
|
19 => 'AM',
|
||||||
|
20 => 'AO',
|
||||||
|
21 => 'AR',
|
||||||
|
22 => 'AT',
|
||||||
|
23 => 'AU',
|
||||||
|
24 => 'BA',
|
||||||
|
25 => 'BB',
|
||||||
|
26 => 'BD',
|
||||||
|
27 => 'BE',
|
||||||
|
28 => 'BF',
|
||||||
|
29 => 'BG',
|
||||||
|
30 => 'BH',
|
||||||
|
31 => 'BI',
|
||||||
|
32 => 'BJ',
|
||||||
|
33 => 'BN',
|
||||||
|
34 => 'BO',
|
||||||
|
35 => 'BR',
|
||||||
|
36 => 'BS',
|
||||||
|
37 => 'BT',
|
||||||
|
38 => 'BW',
|
||||||
|
39 => 'BY',
|
||||||
|
40 => 'BZ',
|
||||||
|
41 => 'CA',
|
||||||
|
42 => 'CD',
|
||||||
|
43 => 'CF',
|
||||||
|
44 => 'CG',
|
||||||
|
45 => 'CH',
|
||||||
|
46 => 'CI',
|
||||||
|
47 => 'CL',
|
||||||
|
48 => 'CM',
|
||||||
|
49 => 'CO',
|
||||||
|
50 => 'CR',
|
||||||
|
51 => 'CU',
|
||||||
|
52 => 'CV',
|
||||||
|
53 => 'CY',
|
||||||
|
54 => 'CZ',
|
||||||
|
55 => 'DJ',
|
||||||
|
56 => 'DK',
|
||||||
|
57 => 'DM',
|
||||||
|
58 => 'DO',
|
||||||
|
59 => 'DZ',
|
||||||
|
60 => 'EC',
|
||||||
|
61 => 'EE',
|
||||||
|
62 => 'EG',
|
||||||
|
63 => 'ER',
|
||||||
|
64 => 'ES',
|
||||||
|
65 => 'ET',
|
||||||
|
66 => 'FI',
|
||||||
|
67 => 'FJ',
|
||||||
|
68 => 'FM',
|
||||||
|
69 => 'FR',
|
||||||
|
70 => 'GA',
|
||||||
|
71 => 'GD',
|
||||||
|
72 => 'GE',
|
||||||
|
73 => 'GH',
|
||||||
|
74 => 'GM',
|
||||||
|
75 => 'GN',
|
||||||
|
76 => 'GQ',
|
||||||
|
77 => 'GR',
|
||||||
|
78 => 'GT',
|
||||||
|
79 => 'GW',
|
||||||
|
80 => 'GY',
|
||||||
|
81 => 'HN',
|
||||||
|
82 => 'HR',
|
||||||
|
83 => 'HT',
|
||||||
|
84 => 'HU',
|
||||||
|
85 => 'ID',
|
||||||
|
86 => 'IE',
|
||||||
|
87 => 'IL',
|
||||||
|
88 => 'IN',
|
||||||
|
89 => 'IQ',
|
||||||
|
90 => 'IS',
|
||||||
|
91 => 'IT',
|
||||||
|
92 => 'JM',
|
||||||
|
93 => 'JO',
|
||||||
|
94 => 'JP',
|
||||||
|
95 => 'KE',
|
||||||
|
96 => 'KH',
|
||||||
|
97 => 'KI',
|
||||||
|
98 => 'KM',
|
||||||
|
99 => 'KN',
|
||||||
|
100 => 'KP',
|
||||||
|
101 => 'KR',
|
||||||
|
102 => 'KW',
|
||||||
|
103 => 'LA',
|
||||||
|
104 => 'LB',
|
||||||
|
105 => 'LC',
|
||||||
|
106 => 'LI',
|
||||||
|
107 => 'LK',
|
||||||
|
108 => 'LR',
|
||||||
|
109 => 'LS',
|
||||||
|
110 => 'LT',
|
||||||
|
111 => 'LU',
|
||||||
|
112 => 'LV',
|
||||||
|
113 => 'LY',
|
||||||
|
114 => 'MA',
|
||||||
|
115 => 'MC',
|
||||||
|
116 => 'MD',
|
||||||
|
117 => 'ME',
|
||||||
|
118 => 'MG',
|
||||||
|
119 => 'MH',
|
||||||
|
120 => 'MK',
|
||||||
|
121 => 'ML',
|
||||||
|
122 => 'MM',
|
||||||
|
123 => 'MN',
|
||||||
|
124 => 'MR',
|
||||||
|
125 => 'MT',
|
||||||
|
126 => 'MU',
|
||||||
|
127 => 'MV',
|
||||||
|
128 => 'MW',
|
||||||
|
129 => 'MX',
|
||||||
|
130 => 'MY',
|
||||||
|
131 => 'MZ',
|
||||||
|
132 => 'NA',
|
||||||
|
133 => 'NE',
|
||||||
|
134 => 'NG',
|
||||||
|
135 => 'NI',
|
||||||
|
136 => 'NL',
|
||||||
|
137 => 'NO',
|
||||||
|
138 => 'NP',
|
||||||
|
139 => 'NR',
|
||||||
|
140 => 'NZ',
|
||||||
|
141 => 'OM',
|
||||||
|
142 => 'PA',
|
||||||
|
143 => 'PE',
|
||||||
|
144 => 'PG',
|
||||||
|
145 => 'PH',
|
||||||
|
146 => 'PK',
|
||||||
|
147 => 'PL',
|
||||||
|
148 => 'PS',
|
||||||
|
149 => 'PT',
|
||||||
|
150 => 'PW',
|
||||||
|
151 => 'PY',
|
||||||
|
152 => 'QA',
|
||||||
|
153 => 'RO',
|
||||||
|
154 => 'RS',
|
||||||
|
155 => 'RW',
|
||||||
|
156 => 'SA',
|
||||||
|
157 => 'SB',
|
||||||
|
158 => 'SC',
|
||||||
|
159 => 'SD',
|
||||||
|
160 => 'SE',
|
||||||
|
161 => 'SG',
|
||||||
|
162 => 'SI',
|
||||||
|
163 => 'SK',
|
||||||
|
164 => 'SL',
|
||||||
|
165 => 'SM',
|
||||||
|
166 => 'SN',
|
||||||
|
167 => 'SO',
|
||||||
|
168 => 'SR',
|
||||||
|
169 => 'SS',
|
||||||
|
170 => 'ST',
|
||||||
|
171 => 'SV',
|
||||||
|
172 => 'SY',
|
||||||
|
173 => 'SZ',
|
||||||
|
174 => 'TD',
|
||||||
|
175 => 'TG',
|
||||||
|
176 => 'TH',
|
||||||
|
177 => 'TL',
|
||||||
|
178 => 'TN',
|
||||||
|
179 => 'TO',
|
||||||
|
180 => 'TT',
|
||||||
|
181 => 'TV',
|
||||||
|
182 => 'TW',
|
||||||
|
183 => 'TZ',
|
||||||
|
184 => 'UG',
|
||||||
|
185 => 'UY',
|
||||||
|
186 => 'VA',
|
||||||
|
187 => 'VC',
|
||||||
|
188 => 'VE',
|
||||||
|
189 => 'VN',
|
||||||
|
190 => 'VU',
|
||||||
|
191 => 'WS',
|
||||||
|
192 => 'YE',
|
||||||
|
193 => 'ZA',
|
||||||
|
194 => 'ZM',
|
||||||
|
195 => 'ZW',
|
||||||
|
],
|
||||||
|
];
|
||||||
@@ -12,6 +12,11 @@ return [
|
|||||||
|
|
||||||
'default_phone' => '+993 61 92 92 48',
|
'default_phone' => '+993 61 92 92 48',
|
||||||
|
|
||||||
|
'employee_number' => [
|
||||||
|
'prefix' => 'EMP-',
|
||||||
|
'padding' => 5,
|
||||||
|
],
|
||||||
|
|
||||||
'file_uploads' => [
|
'file_uploads' => [
|
||||||
'disk' => 'local',
|
'disk' => 'local',
|
||||||
'directory' => 'hr',
|
'directory' => 'hr',
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use App\Models\Department;
|
|||||||
use App\Models\Employee;
|
use App\Models\Employee;
|
||||||
use App\Models\Position;
|
use App\Models\Position;
|
||||||
use App\Models\Shift;
|
use App\Models\Shift;
|
||||||
|
use App\Support\Countries;
|
||||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -30,9 +31,9 @@ class EmployeeFactory extends Factory
|
|||||||
$gender = fake()->randomElement(Gender::cases());
|
$gender = fake()->randomElement(Gender::cases());
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'employee_number' => 'EMP-'.fake()->unique()->numerify('#####'),
|
'employee_number' => '',
|
||||||
'full_name' => fake()->name($gender === Gender::Female ? 'female' : 'male'),
|
'full_name' => fake()->name($gender === Gender::Female ? 'female' : 'male'),
|
||||||
'national_id' => fake()->optional(0.8)->numerify('##########'),
|
'national_id' => fake()->optional(0.8)->randomElement(Countries::codes()),
|
||||||
'gender' => $gender,
|
'gender' => $gender,
|
||||||
'birth_date' => $birthDate,
|
'birth_date' => $birthDate,
|
||||||
'phone' => '+993 61 92 92 48',
|
'phone' => '+993 61 92 92 48',
|
||||||
|
|||||||
202
lang/en/countries.php
Normal file
202
lang/en/countries.php
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'AF' => 'Afghanistan',
|
||||||
|
'AL' => 'Albania',
|
||||||
|
'DZ' => 'Algeria',
|
||||||
|
'AD' => 'Andorra',
|
||||||
|
'AO' => 'Angola',
|
||||||
|
'AG' => 'Antigua and Barbuda',
|
||||||
|
'AR' => 'Argentina',
|
||||||
|
'AM' => 'Armenia',
|
||||||
|
'AU' => 'Australia',
|
||||||
|
'AT' => 'Austria',
|
||||||
|
'AZ' => 'Azerbaijan',
|
||||||
|
'BS' => 'Bahamas',
|
||||||
|
'BH' => 'Bahrain',
|
||||||
|
'BD' => 'Bangladesh',
|
||||||
|
'BB' => 'Barbados',
|
||||||
|
'BY' => 'Belarus',
|
||||||
|
'BE' => 'Belgium',
|
||||||
|
'BZ' => 'Belize',
|
||||||
|
'BJ' => 'Benin',
|
||||||
|
'BT' => 'Bhutan',
|
||||||
|
'BO' => 'Bolivia',
|
||||||
|
'BA' => 'Bosnia and Herzegovina',
|
||||||
|
'BW' => 'Botswana',
|
||||||
|
'BR' => 'Brazil',
|
||||||
|
'BN' => 'Brunei',
|
||||||
|
'BG' => 'Bulgaria',
|
||||||
|
'BF' => 'Burkina Faso',
|
||||||
|
'BI' => 'Burundi',
|
||||||
|
'CV' => 'Cabo Verde',
|
||||||
|
'KH' => 'Cambodia',
|
||||||
|
'CM' => 'Cameroon',
|
||||||
|
'CA' => 'Canada',
|
||||||
|
'CF' => 'Central African Republic',
|
||||||
|
'TD' => 'Chad',
|
||||||
|
'CL' => 'Chile',
|
||||||
|
'CN' => 'China',
|
||||||
|
'CO' => 'Colombia',
|
||||||
|
'KM' => 'Comoros',
|
||||||
|
'CG' => 'Congo',
|
||||||
|
'CD' => 'Congo (DRC)',
|
||||||
|
'CR' => 'Costa Rica',
|
||||||
|
'CI' => 'Côte d\'Ivoire',
|
||||||
|
'HR' => 'Croatia',
|
||||||
|
'CU' => 'Cuba',
|
||||||
|
'CY' => 'Cyprus',
|
||||||
|
'CZ' => 'Czechia',
|
||||||
|
'DK' => 'Denmark',
|
||||||
|
'DJ' => 'Djibouti',
|
||||||
|
'DM' => 'Dominica',
|
||||||
|
'DO' => 'Dominican Republic',
|
||||||
|
'EC' => 'Ecuador',
|
||||||
|
'EG' => 'Egypt',
|
||||||
|
'SV' => 'El Salvador',
|
||||||
|
'GQ' => 'Equatorial Guinea',
|
||||||
|
'ER' => 'Eritrea',
|
||||||
|
'EE' => 'Estonia',
|
||||||
|
'SZ' => 'Eswatini',
|
||||||
|
'ET' => 'Ethiopia',
|
||||||
|
'FJ' => 'Fiji',
|
||||||
|
'FI' => 'Finland',
|
||||||
|
'FR' => 'France',
|
||||||
|
'GA' => 'Gabon',
|
||||||
|
'GM' => 'Gambia',
|
||||||
|
'GE' => 'Georgia',
|
||||||
|
'DE' => 'Germany',
|
||||||
|
'GH' => 'Ghana',
|
||||||
|
'GR' => 'Greece',
|
||||||
|
'GD' => 'Grenada',
|
||||||
|
'GT' => 'Guatemala',
|
||||||
|
'GN' => 'Guinea',
|
||||||
|
'GW' => 'Guinea-Bissau',
|
||||||
|
'GY' => 'Guyana',
|
||||||
|
'HT' => 'Haiti',
|
||||||
|
'HN' => 'Honduras',
|
||||||
|
'HU' => 'Hungary',
|
||||||
|
'IS' => 'Iceland',
|
||||||
|
'IN' => 'India',
|
||||||
|
'ID' => 'Indonesia',
|
||||||
|
'IR' => 'Iran',
|
||||||
|
'IQ' => 'Iraq',
|
||||||
|
'IE' => 'Ireland',
|
||||||
|
'IL' => 'Israel',
|
||||||
|
'IT' => 'Italy',
|
||||||
|
'JM' => 'Jamaica',
|
||||||
|
'JP' => 'Japan',
|
||||||
|
'JO' => 'Jordan',
|
||||||
|
'KZ' => 'Kazakhstan',
|
||||||
|
'KE' => 'Kenya',
|
||||||
|
'KI' => 'Kiribati',
|
||||||
|
'KP' => 'North Korea',
|
||||||
|
'KR' => 'South Korea',
|
||||||
|
'KW' => 'Kuwait',
|
||||||
|
'KG' => 'Kyrgyzstan',
|
||||||
|
'LA' => 'Laos',
|
||||||
|
'LV' => 'Latvia',
|
||||||
|
'LB' => 'Lebanon',
|
||||||
|
'LS' => 'Lesotho',
|
||||||
|
'LR' => 'Liberia',
|
||||||
|
'LY' => 'Libya',
|
||||||
|
'LI' => 'Liechtenstein',
|
||||||
|
'LT' => 'Lithuania',
|
||||||
|
'LU' => 'Luxembourg',
|
||||||
|
'MG' => 'Madagascar',
|
||||||
|
'MW' => 'Malawi',
|
||||||
|
'MY' => 'Malaysia',
|
||||||
|
'MV' => 'Maldives',
|
||||||
|
'ML' => 'Mali',
|
||||||
|
'MT' => 'Malta',
|
||||||
|
'MH' => 'Marshall Islands',
|
||||||
|
'MR' => 'Mauritania',
|
||||||
|
'MU' => 'Mauritius',
|
||||||
|
'MX' => 'Mexico',
|
||||||
|
'FM' => 'Micronesia',
|
||||||
|
'MD' => 'Moldova',
|
||||||
|
'MC' => 'Monaco',
|
||||||
|
'MN' => 'Mongolia',
|
||||||
|
'ME' => 'Montenegro',
|
||||||
|
'MA' => 'Morocco',
|
||||||
|
'MZ' => 'Mozambique',
|
||||||
|
'MM' => 'Myanmar',
|
||||||
|
'NA' => 'Namibia',
|
||||||
|
'NR' => 'Nauru',
|
||||||
|
'NP' => 'Nepal',
|
||||||
|
'NL' => 'Netherlands',
|
||||||
|
'NZ' => 'New Zealand',
|
||||||
|
'NI' => 'Nicaragua',
|
||||||
|
'NE' => 'Niger',
|
||||||
|
'NG' => 'Nigeria',
|
||||||
|
'MK' => 'North Macedonia',
|
||||||
|
'NO' => 'Norway',
|
||||||
|
'OM' => 'Oman',
|
||||||
|
'PK' => 'Pakistan',
|
||||||
|
'PW' => 'Palau',
|
||||||
|
'PS' => 'Palestine',
|
||||||
|
'PA' => 'Panama',
|
||||||
|
'PG' => 'Papua New Guinea',
|
||||||
|
'PY' => 'Paraguay',
|
||||||
|
'PE' => 'Peru',
|
||||||
|
'PH' => 'Philippines',
|
||||||
|
'PL' => 'Poland',
|
||||||
|
'PT' => 'Portugal',
|
||||||
|
'QA' => 'Qatar',
|
||||||
|
'RO' => 'Romania',
|
||||||
|
'RU' => 'Russia',
|
||||||
|
'RW' => 'Rwanda',
|
||||||
|
'KN' => 'Saint Kitts and Nevis',
|
||||||
|
'LC' => 'Saint Lucia',
|
||||||
|
'VC' => 'Saint Vincent and the Grenadines',
|
||||||
|
'WS' => 'Samoa',
|
||||||
|
'SM' => 'San Marino',
|
||||||
|
'ST' => 'São Tomé and Príncipe',
|
||||||
|
'SA' => 'Saudi Arabia',
|
||||||
|
'SN' => 'Senegal',
|
||||||
|
'RS' => 'Serbia',
|
||||||
|
'SC' => 'Seychelles',
|
||||||
|
'SL' => 'Sierra Leone',
|
||||||
|
'SG' => 'Singapore',
|
||||||
|
'SK' => 'Slovakia',
|
||||||
|
'SI' => 'Slovenia',
|
||||||
|
'SB' => 'Solomon Islands',
|
||||||
|
'SO' => 'Somalia',
|
||||||
|
'ZA' => 'South Africa',
|
||||||
|
'SS' => 'South Sudan',
|
||||||
|
'ES' => 'Spain',
|
||||||
|
'LK' => 'Sri Lanka',
|
||||||
|
'SD' => 'Sudan',
|
||||||
|
'SR' => 'Suriname',
|
||||||
|
'SE' => 'Sweden',
|
||||||
|
'CH' => 'Switzerland',
|
||||||
|
'SY' => 'Syria',
|
||||||
|
'TW' => 'Taiwan',
|
||||||
|
'TJ' => 'Tajikistan',
|
||||||
|
'TZ' => 'Tanzania',
|
||||||
|
'TH' => 'Thailand',
|
||||||
|
'TL' => 'Timor-Leste',
|
||||||
|
'TG' => 'Togo',
|
||||||
|
'TO' => 'Tonga',
|
||||||
|
'TT' => 'Trinidad and Tobago',
|
||||||
|
'TN' => 'Tunisia',
|
||||||
|
'TR' => 'Turkey',
|
||||||
|
'TM' => 'Turkmenistan',
|
||||||
|
'TV' => 'Tuvalu',
|
||||||
|
'UG' => 'Uganda',
|
||||||
|
'UA' => 'Ukraine',
|
||||||
|
'AE' => 'United Arab Emirates',
|
||||||
|
'GB' => 'United Kingdom',
|
||||||
|
'US' => 'United States',
|
||||||
|
'UY' => 'Uruguay',
|
||||||
|
'UZ' => 'Uzbekistan',
|
||||||
|
'VU' => 'Vanuatu',
|
||||||
|
'VA' => 'Vatican City',
|
||||||
|
'VE' => 'Venezuela',
|
||||||
|
'VN' => 'Vietnam',
|
||||||
|
'YE' => 'Yemen',
|
||||||
|
'ZM' => 'Zambia',
|
||||||
|
'ZW' => 'Zimbabwe',
|
||||||
|
];
|
||||||
@@ -4,8 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
'gender' => [
|
'gender' => [
|
||||||
'male' => 'Male',
|
'male' => 'Erkek',
|
||||||
'female' => 'Female',
|
'female' => 'Aýal',
|
||||||
'other' => 'Other',
|
'other' => 'Other',
|
||||||
],
|
],
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ return [
|
|||||||
'photo' => 'Photo',
|
'photo' => 'Photo',
|
||||||
'employee_number' => 'Employee Number',
|
'employee_number' => 'Employee Number',
|
||||||
'full_name' => 'Full Name',
|
'full_name' => 'Full Name',
|
||||||
'national_id' => 'National ID',
|
'national_id' => 'Nationality',
|
||||||
'gender' => 'Gender',
|
'gender' => 'Gender',
|
||||||
'birth_date' => 'Birth Date',
|
'birth_date' => 'Birth Date',
|
||||||
'phone' => 'Phone',
|
'phone' => 'Phone',
|
||||||
|
|||||||
202
lang/ru/countries.php
Normal file
202
lang/ru/countries.php
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'AF' => 'Афганистан',
|
||||||
|
'AL' => 'Албания',
|
||||||
|
'DZ' => 'Алжир',
|
||||||
|
'AD' => 'Андорра',
|
||||||
|
'AO' => 'Ангола',
|
||||||
|
'AG' => 'Антигуа и Барбуда',
|
||||||
|
'AR' => 'Аргентина',
|
||||||
|
'AM' => 'Армения',
|
||||||
|
'AU' => 'Австралия',
|
||||||
|
'AT' => 'Австрия',
|
||||||
|
'AZ' => 'Азербайджан',
|
||||||
|
'BS' => 'Багамы',
|
||||||
|
'BH' => 'Бахрейн',
|
||||||
|
'BD' => 'Бангладеш',
|
||||||
|
'BB' => 'Барбados',
|
||||||
|
'BY' => 'Беларусь',
|
||||||
|
'BE' => 'Бельгия',
|
||||||
|
'BZ' => 'Белиз',
|
||||||
|
'BJ' => 'Бенин',
|
||||||
|
'BT' => 'Бутан',
|
||||||
|
'BO' => 'Боливия',
|
||||||
|
'BA' => 'Босния и Герцеговина',
|
||||||
|
'BW' => 'Ботсвана',
|
||||||
|
'BR' => 'Бразилия',
|
||||||
|
'BN' => 'Бруней',
|
||||||
|
'BG' => 'Болгария',
|
||||||
|
'BF' => 'Буркина-Фaso',
|
||||||
|
'BI' => 'Бурунди',
|
||||||
|
'CV' => 'Кabo-Верде',
|
||||||
|
'KH' => 'Кambodja',
|
||||||
|
'CM' => 'Кamerun',
|
||||||
|
'CA' => 'Кanada',
|
||||||
|
'CF' => 'Центральноафриканская Республика',
|
||||||
|
'TD' => 'Чad',
|
||||||
|
'CL' => 'Чili',
|
||||||
|
'CN' => 'Китay',
|
||||||
|
'CO' => 'Кolumbiya',
|
||||||
|
'KM' => 'Коморские Острова',
|
||||||
|
'CG' => 'Республика Конgo',
|
||||||
|
'CD' => 'Демократическая Республика Конgo',
|
||||||
|
'CR' => 'Кosta-Rika',
|
||||||
|
'CI' => 'Кôte-d\'Ivoire',
|
||||||
|
'HR' => 'Хorvatiya',
|
||||||
|
'CU' => 'Кuba',
|
||||||
|
'CY' => 'Кipr',
|
||||||
|
'CZ' => 'Чехiya',
|
||||||
|
'DK' => 'Daniya',
|
||||||
|
'DJ' => 'Джibuti',
|
||||||
|
'DM' => 'Dominika',
|
||||||
|
'DO' => 'Dominikanskaya Respublika',
|
||||||
|
'EC' => 'Ekvador',
|
||||||
|
'EG' => 'Egipet',
|
||||||
|
'SV' => 'Sal\'vador',
|
||||||
|
'GQ' => 'Ekvatorial\'naya Gvineya',
|
||||||
|
'ER' => 'Eritreya',
|
||||||
|
'EE' => 'Estoniya',
|
||||||
|
'SZ' => 'Esvatini',
|
||||||
|
'ET' => 'Efiopiya',
|
||||||
|
'FJ' => 'Fidzhi',
|
||||||
|
'FI' => 'Finlyandiya',
|
||||||
|
'FR' => 'Frantsiya',
|
||||||
|
'GA' => 'Gabon',
|
||||||
|
'GM' => 'Gambiya',
|
||||||
|
'GE' => 'Gruziya',
|
||||||
|
'DE' => 'Germaniya',
|
||||||
|
'GH' => 'Gana',
|
||||||
|
'GR' => 'Gretsiya',
|
||||||
|
'GD' => 'Grenada',
|
||||||
|
'GT' => 'Gvatemala',
|
||||||
|
'GN' => 'Gvineya',
|
||||||
|
'GW' => 'Gvineya-Bisau',
|
||||||
|
'GY' => 'Gayana',
|
||||||
|
'HT' => 'Gaiti',
|
||||||
|
'HN' => 'Gonduras',
|
||||||
|
'HU' => 'Vengriya',
|
||||||
|
'IS' => 'Islandiya',
|
||||||
|
'IN' => 'Indiya',
|
||||||
|
'ID' => 'Indoneziya',
|
||||||
|
'IR' => 'Иран',
|
||||||
|
'IQ' => 'Irak',
|
||||||
|
'IE' => 'Irlandiya',
|
||||||
|
'IL' => 'Izra il',
|
||||||
|
'IT' => 'Italiya',
|
||||||
|
'JM' => 'Yamayka',
|
||||||
|
'JP' => 'Yaponiya',
|
||||||
|
'JO' => 'Iordaniya',
|
||||||
|
'KZ' => 'Казахстан',
|
||||||
|
'KE' => 'Keniya',
|
||||||
|
'KI' => 'Kiribati',
|
||||||
|
'KP' => 'KNDR',
|
||||||
|
'KR' => 'Respublika Koreya',
|
||||||
|
'KW' => 'Kuveyt',
|
||||||
|
'KG' => 'Kyrgyzstan',
|
||||||
|
'LA' => 'Laos',
|
||||||
|
'LV' => 'Latviya',
|
||||||
|
'LB' => 'Livan',
|
||||||
|
'LS' => 'Lesoto',
|
||||||
|
'LR' => 'Liberiya',
|
||||||
|
'LY' => 'Liviya',
|
||||||
|
'LI' => 'Likhhtenshteyn',
|
||||||
|
'LT' => 'Litva',
|
||||||
|
'LU' => 'Lyuksemburg',
|
||||||
|
'MG' => 'Madagaskar',
|
||||||
|
'MW' => 'Malavi',
|
||||||
|
'MY' => 'Malayziya',
|
||||||
|
'MV' => 'Mal\'divy',
|
||||||
|
'ML' => 'Mali',
|
||||||
|
'MT' => 'Mal\'ta',
|
||||||
|
'MH' => 'Marshallovy Ostrova',
|
||||||
|
'MR' => 'Mavritaniya',
|
||||||
|
'MU' => 'Mavrikiy',
|
||||||
|
'MX' => 'Meksika',
|
||||||
|
'FM' => 'Mikroneziya',
|
||||||
|
'MD' => 'Moldova',
|
||||||
|
'MC' => 'Monako',
|
||||||
|
'MN' => 'Mongoliya',
|
||||||
|
'ME' => 'Chernogoriya',
|
||||||
|
'MA' => 'Marokko',
|
||||||
|
'MZ' => 'Mozambik',
|
||||||
|
'MM' => 'Myanma',
|
||||||
|
'NA' => 'Namibiya',
|
||||||
|
'NR' => 'Nauru',
|
||||||
|
'NP' => 'Nepal',
|
||||||
|
'NL' => 'Niderlandy',
|
||||||
|
'NZ' => 'Novaya Zelandiya',
|
||||||
|
'NI' => 'Nikaragua',
|
||||||
|
'NE' => 'Niger',
|
||||||
|
'NG' => 'Nigeriya',
|
||||||
|
'MK' => 'Severnaya Makedoniya',
|
||||||
|
'NO' => 'Norvegiya',
|
||||||
|
'OM' => 'Oman',
|
||||||
|
'PK' => 'Pakistan',
|
||||||
|
'PW' => 'Palau',
|
||||||
|
'PS' => 'Palestina',
|
||||||
|
'PA' => 'Panama',
|
||||||
|
'PG' => 'Papua — Novaya Gvineya',
|
||||||
|
'PY' => 'Paragvay',
|
||||||
|
'PE' => 'Peru',
|
||||||
|
'PH' => 'Filippiny',
|
||||||
|
'PL' => 'Pol\'sha',
|
||||||
|
'PT' => 'Portugaliya',
|
||||||
|
'QA' => 'Katar',
|
||||||
|
'RO' => 'Rumyniya',
|
||||||
|
'RU' => 'Россия',
|
||||||
|
'RW' => 'Ruanda',
|
||||||
|
'KN' => 'Sent-Kits i Nevis',
|
||||||
|
'LC' => 'Sent-Lyusiya',
|
||||||
|
'VC' => 'Sent-Vinsent i Grenadiny',
|
||||||
|
'WS' => 'Samoa',
|
||||||
|
'SM' => 'San-Marino',
|
||||||
|
'ST' => 'San-Tome i Prinsipi',
|
||||||
|
'SA' => 'Saudovskaya Araviya',
|
||||||
|
'SN' => 'Senegal',
|
||||||
|
'RS' => 'Serbiya',
|
||||||
|
'SC' => 'Seyshely',
|
||||||
|
'SL' => 'Serra-Leone',
|
||||||
|
'SG' => 'Singapur',
|
||||||
|
'SK' => 'Slovakiya',
|
||||||
|
'SI' => 'Sloveniya',
|
||||||
|
'SB' => 'Solomonovy Ostrova',
|
||||||
|
'SO' => 'Somali',
|
||||||
|
'ZA' => 'Yuzhno-Afrikanskaya Respublika',
|
||||||
|
'SS' => 'Yuzhnyy Sudan',
|
||||||
|
'ES' => 'Ispaniya',
|
||||||
|
'LK' => 'Shri-Lanka',
|
||||||
|
'SD' => 'Sudan',
|
||||||
|
'SR' => 'Surinam',
|
||||||
|
'SE' => 'Shvetsiya',
|
||||||
|
'CH' => 'Shveytsariya',
|
||||||
|
'SY' => 'Siriya',
|
||||||
|
'TW' => 'Tayvan',
|
||||||
|
'TJ' => 'Tadzhikistan',
|
||||||
|
'TZ' => 'Tanzaniya',
|
||||||
|
'TH' => 'Tailand',
|
||||||
|
'TL' => 'Timor-Leste',
|
||||||
|
'TG' => 'Togo',
|
||||||
|
'TO' => 'Tonga',
|
||||||
|
'TT' => 'Trinidad i Tobago',
|
||||||
|
'TN' => 'Tunis',
|
||||||
|
'TR' => 'Турция',
|
||||||
|
'TM' => 'Туркmenistan',
|
||||||
|
'TV' => 'Tuvalu',
|
||||||
|
'UG' => 'Uganda',
|
||||||
|
'UA' => 'Ukraina',
|
||||||
|
'AE' => 'OAE',
|
||||||
|
'GB' => 'Velikobritaniya',
|
||||||
|
'US' => 'SShA',
|
||||||
|
'UY' => 'Urugvay',
|
||||||
|
'UZ' => 'Uzbekistan',
|
||||||
|
'VU' => 'Vanuatu',
|
||||||
|
'VA' => 'Vatikan',
|
||||||
|
'VE' => 'Venesuela',
|
||||||
|
'VN' => 'Vetnam',
|
||||||
|
'YE' => 'Yemen',
|
||||||
|
'ZM' => 'Zambiya',
|
||||||
|
'ZW' => 'Zimbabve',
|
||||||
|
];
|
||||||
@@ -48,7 +48,7 @@ return [
|
|||||||
'photo' => 'Фото',
|
'photo' => 'Фото',
|
||||||
'employee_number' => 'Табельный номер',
|
'employee_number' => 'Табельный номер',
|
||||||
'full_name' => 'ФИО',
|
'full_name' => 'ФИО',
|
||||||
'national_id' => 'Национальный ID',
|
'national_id' => 'Гражданство',
|
||||||
'gender' => 'Пол',
|
'gender' => 'Пол',
|
||||||
'birth_date' => 'Дата рождения',
|
'birth_date' => 'Дата рождения',
|
||||||
'phone' => 'Телефон',
|
'phone' => 'Телефон',
|
||||||
|
|||||||
202
lang/tk/countries.php
Normal file
202
lang/tk/countries.php
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
return [
|
||||||
|
'AF' => 'Owganystan',
|
||||||
|
'AL' => 'Albaniýa',
|
||||||
|
'DZ' => 'Aljir',
|
||||||
|
'AD' => 'Andorra',
|
||||||
|
'AO' => 'Angola',
|
||||||
|
'AG' => 'Antigua and Barbuda',
|
||||||
|
'AR' => 'Argentina',
|
||||||
|
'AM' => 'Ermenistan',
|
||||||
|
'AU' => 'Awstraliýa',
|
||||||
|
'AT' => 'Awstriýa',
|
||||||
|
'AZ' => 'Azerbaýjan',
|
||||||
|
'BS' => 'Bagama adalary',
|
||||||
|
'BH' => 'Bahreýn',
|
||||||
|
'BD' => 'Bangladesh',
|
||||||
|
'BB' => 'Barbados',
|
||||||
|
'BY' => 'Belarus',
|
||||||
|
'BE' => 'Belgiýa',
|
||||||
|
'BZ' => 'Belize',
|
||||||
|
'BJ' => 'Benin',
|
||||||
|
'BT' => 'Butan',
|
||||||
|
'BO' => 'Boliwiýa',
|
||||||
|
'BA' => 'Bosniýa we Gersegowina',
|
||||||
|
'BW' => 'Botswana',
|
||||||
|
'BR' => 'Braziliýa',
|
||||||
|
'BN' => 'Bruneý',
|
||||||
|
'BG' => 'Bolgariýa',
|
||||||
|
'BF' => 'Burkina Faso',
|
||||||
|
'BI' => 'Burundi',
|
||||||
|
'CV' => 'Cabo Verde',
|
||||||
|
'KH' => 'Kamboja',
|
||||||
|
'CM' => 'Cameroon',
|
||||||
|
'CA' => 'Kanada',
|
||||||
|
'CF' => 'Central African Republic',
|
||||||
|
'TD' => 'Chad',
|
||||||
|
'CL' => 'Çili',
|
||||||
|
'CN' => 'Hytaý',
|
||||||
|
'CO' => 'Kolumbiýa',
|
||||||
|
'KM' => 'Comoros',
|
||||||
|
'CG' => 'Congo',
|
||||||
|
'CD' => 'Congo (DRC)',
|
||||||
|
'CR' => 'Kosta-Rika',
|
||||||
|
'CI' => 'Côte d\'Ivoire',
|
||||||
|
'HR' => 'Horwatiýa',
|
||||||
|
'CU' => 'Kuba',
|
||||||
|
'CY' => 'Kipr',
|
||||||
|
'CZ' => 'Çeh Respublikasy',
|
||||||
|
'DK' => 'Daniýa',
|
||||||
|
'DJ' => 'Djibouti',
|
||||||
|
'DM' => 'Dominica',
|
||||||
|
'DO' => 'Dominikan Respublikasy',
|
||||||
|
'EC' => 'Ekwador',
|
||||||
|
'EG' => 'Müsür',
|
||||||
|
'SV' => 'Salwador',
|
||||||
|
'GQ' => 'Equatorial Guinea',
|
||||||
|
'ER' => 'Eritrea',
|
||||||
|
'EE' => 'Estoniýa',
|
||||||
|
'SZ' => 'Eswatini',
|
||||||
|
'ET' => 'Efiopiýa',
|
||||||
|
'FJ' => 'Fiji',
|
||||||
|
'FI' => 'Finlandiýa',
|
||||||
|
'FR' => 'Fransiýa',
|
||||||
|
'GA' => 'Gabon',
|
||||||
|
'GM' => 'Gambia',
|
||||||
|
'GE' => 'Gruziýa',
|
||||||
|
'DE' => 'Germaniýa',
|
||||||
|
'GH' => 'Ghana',
|
||||||
|
'GR' => 'Gresiýa',
|
||||||
|
'GD' => 'Grenada',
|
||||||
|
'GT' => 'Gwatemala',
|
||||||
|
'GN' => 'Guinea',
|
||||||
|
'GW' => 'Guinea-Bissau',
|
||||||
|
'GY' => 'Gaýana',
|
||||||
|
'HT' => 'Gaiti',
|
||||||
|
'HN' => 'Gonduras',
|
||||||
|
'HU' => 'Wengriýa',
|
||||||
|
'IS' => 'Islandiýa',
|
||||||
|
'IN' => 'Hindistan',
|
||||||
|
'ID' => 'Indoneziýa',
|
||||||
|
'IR' => 'Eýran',
|
||||||
|
'IQ' => 'Yrak',
|
||||||
|
'IE' => 'Irlandiýa',
|
||||||
|
'IL' => 'Ysrail',
|
||||||
|
'IT' => 'Italiýa',
|
||||||
|
'JM' => 'Ýamaýka',
|
||||||
|
'JP' => 'Ýaponiýa',
|
||||||
|
'JO' => 'Iordaniýa',
|
||||||
|
'KZ' => 'Gazagystan',
|
||||||
|
'KE' => 'Keniýa',
|
||||||
|
'KI' => 'Kiribati',
|
||||||
|
'KP' => 'Demokratik Halk Respublikasy',
|
||||||
|
'KR' => 'Günorta Koreýa',
|
||||||
|
'KW' => 'Kuweýt',
|
||||||
|
'KG' => 'Gyrgyzystan',
|
||||||
|
'LA' => 'Laos',
|
||||||
|
'LV' => 'Latwiýa',
|
||||||
|
'LB' => 'Liwan',
|
||||||
|
'LS' => 'Lesotho',
|
||||||
|
'LR' => 'Liberia',
|
||||||
|
'LY' => 'Liwiýa',
|
||||||
|
'LI' => 'Lihtenshteýn',
|
||||||
|
'LT' => 'Litwa',
|
||||||
|
'LU' => 'Lýuksemburg',
|
||||||
|
'MG' => 'Madagascar',
|
||||||
|
'MW' => 'Malawi',
|
||||||
|
'MY' => 'Malaýziýa',
|
||||||
|
'MV' => 'Maldiwler',
|
||||||
|
'ML' => 'Mali',
|
||||||
|
'MT' => 'Malta',
|
||||||
|
'MH' => 'Marşall adalary',
|
||||||
|
'MR' => 'Mauritania',
|
||||||
|
'MU' => 'Mauritius',
|
||||||
|
'MX' => 'Meksika',
|
||||||
|
'FM' => 'Mikroneziýa',
|
||||||
|
'MD' => 'Moldowa',
|
||||||
|
'MC' => 'Monako',
|
||||||
|
'MN' => 'Mongoliýa',
|
||||||
|
'ME' => 'Chernogoriýa',
|
||||||
|
'MA' => 'Marokko',
|
||||||
|
'MZ' => 'Mozambique',
|
||||||
|
'MM' => 'Mýanma',
|
||||||
|
'NA' => 'Namibia',
|
||||||
|
'NR' => 'Nauru',
|
||||||
|
'NP' => 'Nepal',
|
||||||
|
'NL' => 'Gollandiýa',
|
||||||
|
'NZ' => 'Täze Zelandiýa',
|
||||||
|
'NI' => 'Nikaragua',
|
||||||
|
'NE' => 'Niger',
|
||||||
|
'NG' => 'Nigeriýa',
|
||||||
|
'MK' => 'Demirgazyk Makedoniýa',
|
||||||
|
'NO' => 'Norwegiýa',
|
||||||
|
'OM' => 'Oman',
|
||||||
|
'PK' => 'Pakistan',
|
||||||
|
'PW' => 'Palau',
|
||||||
|
'PS' => 'Palestina',
|
||||||
|
'PA' => 'Panama',
|
||||||
|
'PG' => 'Papua — Täze Gwineýa',
|
||||||
|
'PY' => 'Paragwaý',
|
||||||
|
'PE' => 'Peru',
|
||||||
|
'PH' => 'Filippinler',
|
||||||
|
'PL' => 'Polşa',
|
||||||
|
'PT' => 'Portugaliýa',
|
||||||
|
'QA' => 'Katar',
|
||||||
|
'RO' => 'Rumyniýa',
|
||||||
|
'RU' => 'Rusiya',
|
||||||
|
'RW' => 'Rwanda',
|
||||||
|
'KN' => 'Saint Kitts and Nevis',
|
||||||
|
'LC' => 'Saint Lucia',
|
||||||
|
'VC' => 'Saint Vincent and the Grenadines',
|
||||||
|
'WS' => 'Samoa',
|
||||||
|
'SM' => 'San-Marino',
|
||||||
|
'ST' => 'São Tomé and Príncipe',
|
||||||
|
'SA' => 'Saud Arabystany',
|
||||||
|
'SN' => 'Senegal',
|
||||||
|
'RS' => 'Serbiýa',
|
||||||
|
'SC' => 'Seychelles',
|
||||||
|
'SL' => 'Sierra Leone',
|
||||||
|
'SG' => 'Singapur',
|
||||||
|
'SK' => 'Slowakiýa',
|
||||||
|
'SI' => 'Slovenia',
|
||||||
|
'SB' => 'Solomon adalary',
|
||||||
|
'SO' => 'Somalia',
|
||||||
|
'ZA' => 'Günorta Afrika',
|
||||||
|
'SS' => 'South Sudan',
|
||||||
|
'ES' => 'Ispaniýa',
|
||||||
|
'LK' => 'Shri-Lanka',
|
||||||
|
'SD' => 'Sudan',
|
||||||
|
'SR' => 'Surinam',
|
||||||
|
'SE' => 'Shwesiýa',
|
||||||
|
'CH' => 'Shweýsariýa',
|
||||||
|
'SY' => 'Siriýa',
|
||||||
|
'TW' => 'Taýwan',
|
||||||
|
'TJ' => 'Täjikistan',
|
||||||
|
'TZ' => 'Tanzania',
|
||||||
|
'TH' => 'Taýland',
|
||||||
|
'TL' => 'Timor-Leste',
|
||||||
|
'TG' => 'Togo',
|
||||||
|
'TO' => 'Tonga',
|
||||||
|
'TT' => 'Trinidad we Tobago',
|
||||||
|
'TN' => 'Tunis',
|
||||||
|
'TR' => 'Türkiýe',
|
||||||
|
'TM' => 'Türkmenistan',
|
||||||
|
'TV' => 'Tuwalu',
|
||||||
|
'UG' => 'Uganda',
|
||||||
|
'UA' => 'Ukraina',
|
||||||
|
'AE' => 'Birleşik Arap Emirlikleri',
|
||||||
|
'GB' => 'Beýik Britaniýa',
|
||||||
|
'US' => 'Amerika Birleşik Ştatlary',
|
||||||
|
'UY' => 'Urugwaý',
|
||||||
|
'UZ' => 'Ozbekistan',
|
||||||
|
'VU' => 'Wanuatu',
|
||||||
|
'VA' => 'Watikan',
|
||||||
|
'VE' => 'Wenesuela',
|
||||||
|
'VN' => 'Wýetnam',
|
||||||
|
'YE' => 'Ýemen',
|
||||||
|
'ZM' => 'Zambia',
|
||||||
|
'ZW' => 'Zimbabwe',
|
||||||
|
];
|
||||||
@@ -48,7 +48,7 @@ return [
|
|||||||
'photo' => 'Surat',
|
'photo' => 'Surat',
|
||||||
'employee_number' => 'Işgär belgisi',
|
'employee_number' => 'Işgär belgisi',
|
||||||
'full_name' => 'Doly ady',
|
'full_name' => 'Doly ady',
|
||||||
'national_id' => 'Milli ID',
|
'national_id' => 'Raýatlyk',
|
||||||
'gender' => 'Jyns',
|
'gender' => 'Jyns',
|
||||||
'birth_date' => 'Doglan senesi',
|
'birth_date' => 'Doglan senesi',
|
||||||
'phone' => 'Telefon',
|
'phone' => 'Telefon',
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ beforeEach(function (): void {
|
|||||||
it('skips duplicate employees during import', function (): void {
|
it('skips duplicate employees during import', function (): void {
|
||||||
Employee::factory()->create([
|
Employee::factory()->create([
|
||||||
'employee_number' => 'EMP-90001',
|
'employee_number' => 'EMP-90001',
|
||||||
'national_id' => '1234567890',
|
'national_id' => 'TM',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$rows = [[
|
$rows = [[
|
||||||
'employee_number' => 'EMP-90001',
|
'employee_number' => 'EMP-90001',
|
||||||
'full_name' => 'Duplicate Employee',
|
'full_name' => 'Duplicate Employee',
|
||||||
'national_id' => '1234567890',
|
'national_id' => 'TM',
|
||||||
'department' => 'Engineering',
|
'department' => 'Engineering',
|
||||||
'position' => 'Developer',
|
'position' => 'Developer',
|
||||||
'shift' => 'Day Shift',
|
'shift' => 'Day Shift',
|
||||||
@@ -68,6 +68,29 @@ it('imports valid employee rows', function (): void {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('imports valid employee rows without an employee number', function (): void {
|
||||||
|
$rows = [[
|
||||||
|
'full_name' => 'Auto Number Employee',
|
||||||
|
'gender' => 'male',
|
||||||
|
'birth_date' => '1992-02-20',
|
||||||
|
'department' => 'Engineering',
|
||||||
|
'position' => 'Developer',
|
||||||
|
'shift' => 'Day Shift',
|
||||||
|
'hire_date' => '2024-04-01',
|
||||||
|
]];
|
||||||
|
|
||||||
|
$result = $this->importService->import(ImportType::Employees, $rows);
|
||||||
|
|
||||||
|
expect($result->imported)->toBe(1)
|
||||||
|
->and($result->skipped)->toBe(0)
|
||||||
|
->and($result->failed)->toBe(0);
|
||||||
|
|
||||||
|
$employee = Employee::query()->where('full_name', 'Auto Number Employee')->first();
|
||||||
|
|
||||||
|
expect($employee)->not->toBeNull()
|
||||||
|
->and($employee->employee_number)->toBe('EMP-00001');
|
||||||
|
});
|
||||||
|
|
||||||
it('reports validation errors for invalid employee rows', function (): void {
|
it('reports validation errors for invalid employee rows', function (): void {
|
||||||
$rows = [[
|
$rows = [[
|
||||||
'employee_number' => '',
|
'employee_number' => '',
|
||||||
@@ -93,8 +116,7 @@ it('validates required fields and unknown references', function (): void {
|
|||||||
|
|
||||||
$errors = $this->transformer->validate($dto);
|
$errors = $this->transformer->validate($dto);
|
||||||
|
|
||||||
expect($errors)->toContain('Employee number is required.')
|
expect($errors)->toContain('Full name is required.')
|
||||||
->and($errors)->toContain('Full name is required.')
|
|
||||||
->and($errors)->toContain('Department "Missing Department" was not found.')
|
->and($errors)->toContain('Department "Missing Department" was not found.')
|
||||||
->and($errors)->toContain('Position "Missing Position" was not found.')
|
->and($errors)->toContain('Position "Missing Position" was not found.')
|
||||||
->and($errors)->toContain('Shift "Missing Shift" was not found.');
|
->and($errors)->toContain('Shift "Missing Shift" was not found.');
|
||||||
@@ -103,7 +125,7 @@ it('validates required fields and unknown references', function (): void {
|
|||||||
it('detects duplicates by employee number or national id', function (): void {
|
it('detects duplicates by employee number or national id', function (): void {
|
||||||
Employee::factory()->create([
|
Employee::factory()->create([
|
||||||
'employee_number' => 'EMP-80001',
|
'employee_number' => 'EMP-80001',
|
||||||
'national_id' => '9988776655',
|
'national_id' => 'TM',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$duplicateByNumber = EmployeeRowDto::fromMappedRow([
|
$duplicateByNumber = EmployeeRowDto::fromMappedRow([
|
||||||
@@ -114,7 +136,7 @@ it('detects duplicates by employee number or national id', function (): void {
|
|||||||
$duplicateByNationalId = EmployeeRowDto::fromMappedRow([
|
$duplicateByNationalId = EmployeeRowDto::fromMappedRow([
|
||||||
'employee_number' => 'EMP-80002',
|
'employee_number' => 'EMP-80002',
|
||||||
'full_name' => 'Another Person',
|
'full_name' => 'Another Person',
|
||||||
'national_id' => '9988776655',
|
'national_id' => 'TM',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
expect($this->transformer->isDuplicate($duplicateByNumber))->toBeTrue()
|
expect($this->transformer->isDuplicate($duplicateByNumber))->toBeTrue()
|
||||||
|
|||||||
@@ -35,6 +35,19 @@ it('returns translated navigation group labels', function (): void {
|
|||||||
expect(NavigationGroup::LeaveManagement->getLabel())->toBe('Dynç alyş dolandyryşy');
|
expect(NavigationGroup::LeaveManagement->getLabel())->toBe('Dynç alyş dolandyryşy');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns translated filament navigation group labels at request time', function (): void {
|
||||||
|
$admin = createAdminUser(['locale' => 'tk']);
|
||||||
|
|
||||||
|
$this->actingAs($admin);
|
||||||
|
|
||||||
|
App::setLocale('tk');
|
||||||
|
|
||||||
|
$groups = filament()->getNavigation();
|
||||||
|
$labels = collect($groups)->map->getLabel()->filter()->values()->all();
|
||||||
|
|
||||||
|
expect($labels)->toContain('Gurama', 'Işgärler', 'Dynç alyş dolandyryşy', 'Ýazgylar');
|
||||||
|
});
|
||||||
|
|
||||||
it('returns translated filament resource navigation labels', function (): void {
|
it('returns translated filament resource navigation labels', function (): void {
|
||||||
App::setLocale('tk');
|
App::setLocale('tk');
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,32 @@ it('defines expected employee relationships', function (): void {
|
|||||||
->and($employee->documents)->toHaveCount(1);
|
->and($employee->documents)->toHaveCount(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('generates an employee number on save when number is blank', function (): void {
|
||||||
|
$employee = Employee::factory()->create([
|
||||||
|
'employee_number' => '',
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect($employee->employee_number)->toBe('EMP-00001');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not overwrite an existing employee number on update', function (): void {
|
||||||
|
$employee = Employee::factory()->create([
|
||||||
|
'employee_number' => 'EMP-CUSTOM',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$employee->update(['full_name' => 'Updated Name']);
|
||||||
|
|
||||||
|
expect($employee->fresh()->employee_number)->toBe('EMP-CUSTOM');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('increments employee numbers sequentially', function (): void {
|
||||||
|
$first = Employee::factory()->create(['employee_number' => '']);
|
||||||
|
$second = Employee::factory()->create(['employee_number' => '']);
|
||||||
|
|
||||||
|
expect($first->employee_number)->toBe('EMP-00001')
|
||||||
|
->and($second->employee_number)->toBe('EMP-00002');
|
||||||
|
});
|
||||||
|
|
||||||
it('enforces a unique employee number', function (): void {
|
it('enforces a unique employee number', function (): void {
|
||||||
Employee::factory()->create(['employee_number' => 'EMP-UNIQUE']);
|
Employee::factory()->create(['employee_number' => 'EMP-UNIQUE']);
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ it('creates an employee with the provided data', function (): void {
|
|||||||
$shift = Shift::factory()->create();
|
$shift = Shift::factory()->create();
|
||||||
|
|
||||||
$employee = $this->service->create([
|
$employee = $this->service->create([
|
||||||
'employee_number' => 'EMP-10001',
|
|
||||||
'full_name' => 'John Doe',
|
'full_name' => 'John Doe',
|
||||||
'gender' => 'male',
|
'gender' => 'male',
|
||||||
'birth_date' => '1990-05-15',
|
'birth_date' => '1990-05-15',
|
||||||
@@ -39,16 +38,37 @@ it('creates an employee with the provided data', function (): void {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
expect($employee)->toBeInstanceOf(Employee::class)
|
expect($employee)->toBeInstanceOf(Employee::class)
|
||||||
->and($employee->employee_number)->toBe('EMP-10001')
|
->and($employee->employee_number)->toBe('EMP-00001')
|
||||||
->and($employee->full_name)->toBe('John Doe')
|
->and($employee->full_name)->toBe('John Doe')
|
||||||
->and($employee->employment_status)->toBe(EmploymentStatus::Active);
|
->and($employee->employment_status)->toBe(EmploymentStatus::Active);
|
||||||
|
|
||||||
$this->assertDatabaseHas('employees', [
|
$this->assertDatabaseHas('employees', [
|
||||||
'employee_number' => 'EMP-10001',
|
'employee_number' => 'EMP-00001',
|
||||||
'full_name' => 'John Doe',
|
'full_name' => 'John Doe',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('creates an employee with an explicit employee number', function (): void {
|
||||||
|
$department = Department::factory()->create();
|
||||||
|
$position = Position::factory()->create();
|
||||||
|
$shift = Shift::factory()->create();
|
||||||
|
|
||||||
|
$employee = $this->service->create([
|
||||||
|
'employee_number' => 'EMP-10001',
|
||||||
|
'full_name' => 'Jane Doe',
|
||||||
|
'gender' => 'female',
|
||||||
|
'birth_date' => '1991-06-20',
|
||||||
|
'phone' => '+993 61 92 92 48',
|
||||||
|
'department_id' => $department->id,
|
||||||
|
'position_id' => $position->id,
|
||||||
|
'shift_id' => $shift->id,
|
||||||
|
'employment_status' => EmploymentStatus::Active,
|
||||||
|
'hire_date' => '2024-02-01',
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect($employee->employee_number)->toBe('EMP-10001');
|
||||||
|
});
|
||||||
|
|
||||||
it('terminates an employee and notifies hr managers', function (): void {
|
it('terminates an employee and notifies hr managers', function (): void {
|
||||||
$employee = Employee::factory()->active()->create();
|
$employee = Employee::factory()->active()->create();
|
||||||
$terminationDate = Carbon::parse('2025-06-30');
|
$terminationDate = Carbon::parse('2025-06-30');
|
||||||
|
|||||||
Reference in New Issue
Block a user