Skip to content

Repository files navigation

RuFaker

Tests Coverage Packagist PHP

Российские тестовые данные для PHP: реквизиты организации, физлица и банка.

  • Организация — правовая форма, краткое и полное наименование, ИНН, ОГРН или ОГРНИП, КПП, регион, дата регистрации, руководитель и его должность;
  • Физлицо — фамилия, имя, отчество, пол, дата рождения, ИНН;
  • Банк — краткое и полное наименование, БИК, корреспондентский и расчётный счёт.

Данные не противоречат друг другу — это главное отличие от генератора случайных цифр.

  • ИНН, ОГРН и КПП одной организации выданы в одном регионе и одной налоговой;
  • у предпринимателя есть ФИО, но нет КПП; у юрлица есть КПП и название, но нет ФИО;
  • предприниматель и он же как физлицо носят один ИНН: после регистрации номер не меняется;
  • организацию не зарегистрировали раньше, чем открылся её реестр, а предпринимателя — раньше его восемнадцатилетия;
  • год внутри ОГРН совпадает с датой регистрации;
  • счёт проходит проверку по БИК своего банка;
  • один и тот же БИК всегда даёт один и тот же банк: у двух его клиентов совпадут название банка и корреспондентский счёт;
  • фамилия, имя и отчество согласованы по роду — Иванова Мария Петровна, а не Иванов Мария Петровна.

Значения строятся по действующим правилам: контрольные суммы считаются по настоящим формулам, структура номеров и границы дат взяты из законов и классификаторов. Сгенерированный ИНН, ОГРН или счёт проходит ту же проверку, что и настоящий, поэтому пакет умеет не только выдавать значения, но и валидировать.

Содержание

Установка

composer require --dev rufaker/rufaker

Нужен PHP 8.3 или новее. Зависимостей нет — только сам PHP.

Быстрый старт

use RuFaker\RuFaker;

$ru = new RuFaker();

$company = $ru->organization();

$company->shortName;  // 'ООО "Ромашка"'
$company->fullName;   // 'Общество с ограниченной ответственностью "Ромашка"'
$company->form;       // 'ООО'
$company->inn;        // '1492876987'
$company->ogrn;       // '1101459307355'
$company->kpp;        // '145901001'
$company->region;     // '14'

$bank = $ru->bankAccount();

$bank->shortName;      // 'ПАО "Эталон Банк"'
$bank->bik;            // '040834121'
$bank->correspondent;  // '30101810700000000121'
$bank->settlement;     // '40702810500006981360'

$person = $ru->person();

$person->lastName;    // 'Беляев'
$person->firstName;   // 'Демьян'
$person->patronymic;  // 'Кириллович'
$person->gender;      // 'мужской'
$person->fullName;    // 'Беляев Демьян Кириллович'
$person->birthDate;   // '1987-08-28'
$person->inn;         // '231232028482'

Все поля — строки, готовые к подстановке в фикстуру, фабрику или запрос. В них стоит то, что написано в документе: ООО, мужской. Машинное значение перечисления берётся со скобками: $company->form()->value даёт 'ooo', $person->gender()->value'male'.

Как устроена выдача

Поле без скобок — строка, то же имя со скобками — типизированное значение. Это правило работает во всём пакете:

$company->inn;    // '1492876987' — string
$company->inn();  // RuFaker\Requisite\Inn — тип, знающий про себя всё

Строка нужна чаще, поэтому её запись короче. Скобки — когда важен не текст, а смысл значения:

$company->inn()->region();               // Requisite\Region — регион, к которому приписан ИНН
$company->ogrn()->year();                // 2015 — год записи в реестре
$company->form()->hasKpp();              // true — бывает ли КПП у этой формы
$company->form()->balanceAccount();      // '40702' — какой счёт открывает банк
$bank->settlement()->isCorrespondent();  // false — расчётный счёт, не корреспондентский
$person->gender()->value;                // 'male'

Когда строки нужны сразу все, набор отдаёт их одним массивом — toArray(), а json_encode() возвращает то же самое. Ключи в snake_case:

$company->toArray();
// [
//     'form' => 'ООО',
//     'short_name' => 'ООО "Ромашка"',
//     'full_name' => 'Общество с ограниченной ответственностью "Ромашка"',
//     'region' => '14',
//     'inn' => '1492876987',
//     'ogrn' => '1101459307355',
//     'kpp' => '145901001',
//     'registration_date' => '2010-08-19',
//     'person' => null,
//     'head' => 'Герасимов Семён Степанович',
//     'head_position' => 'Генеральный директор',
// ]

$bank->toArray();
// [
//     'bank_short_name' => 'ПАО "Эталон Банк"',
//     'bank_full_name' => 'Публичное акционерное общество "Эталон Банк"',
//     'bik' => '040834121',
//     'correspondent_account' => '30101810700000000121',
//     'settlement_account' => '40702810500006981360',
// ]

Что генерирует пакет

Организация

use RuFaker\Enum\Gender;
use RuFaker\Enum\LegalForm;
use RuFaker\Requisite\Region;

$ru->organization();                                        // форма и регион случайные
$ru->organization(LegalForm::Ip);                           // задана форма
$ru->organization(LegalForm::Ooo, Region::from('77'));      // и регион
$ru->organization(LegalForm::Ip, null, Gender::Female);     // пол предпринимателя
$ru->organization(LegalForm::Ip, initials: true);           // ФИО в наименовании — инициалами
$ru->organization(title: 'Рассвет');                        // задано наименование
$ru->organization(person: $person);                         // ИП из готового физлица

Формы — Ooo, Ao, Pao, Ip. Форма определяет всё остальное: длину ИНН и ОГРН, наличие КПП, балансовый счёт. В поле form стоит краткий ярлык — ООО, АО, ПАО, ИП, — а полное название даёт form()->fullTitle(): Общество с ограниченной ответственностью.

Поле Юридическое лицо Индивидуальный предприниматель
shortName ярлык формы и название: ООО "Ромашка" ИП и ФИО целиком
fullName форма целиком и название Индивидуальный предприниматель и ФИО
inn 10 знаков 12 знаков
ogrn 13 знаков, ОГРН 15 знаков, ОГРНИП
kpp 9 знаков null
registrationDate дата записи в реестре, ISO 8601 то же
person() null Result\Person — ФИО предпринимателя
head ФИО руководителя null, предприниматель действует сам
headPosition Генеральный директор, Директор или Президент null
head() Result\Person — тот же руководитель null
region 2 знака, общий для всех реквизитов набора то же
$company = $ru->organization(LegalForm::Ip, Region::from('66'));

$company->shortName;           // 'ИП Успенский Пётр Иванович'
$company->inn;                 // '664429287641'
$company->ogrn;                // '310663730735974'
$company->kpp;                 // null
$company->registrationDate;    // '2010-11-23'
$company->person()->fullName;  // 'Успенский Пётр Иванович'
$company->person()->lastName;  // 'Успенский'

Название юрлица берётся из словаря пакета — 127 слов, по одному слову в кавычках. Своё название передаётся аргументом — например, когда тест ищет контрагента по наименованию:

$ru->organization(LegalForm::Ooo, title: 'Рассвет')->shortName;  // 'ООО "Рассвет"'

Без заданной формы она выбирается среди форм юрлица — Ooo, Ao, Pao: наименование бывает только у них.

У предпринимателя наименование строится из ФИО, и у него есть третья, неофициальная форма — с инициалами. Она включается флагом при генерации:

$ru->organization(LegalForm::Ip, initials: true)->shortName;  // 'ИП Абрамова А.С.'

У юрлица есть руководитель — тот, кто подписывает документы:

$company = $ru->organization(LegalForm::Ooo, Region::from('19'));

$company->head;                // 'Герасимов Семён Степанович'
$company->headPosition;        // 'Генеральный директор'
$company->head()?->birthDate;  // '1952-07-11'

Руководитель — представитель, а не сам бизнес: ИНН у него свой и с ИНН организации не совпадает. У предпринимателя руководителя нет, он действует сам.

Физлицо

$ru->person();                            // пол, дата рождения и ИНН случайные
$ru->person(Gender::Female);              // задан пол
$ru->person(region: Region::from('77'));  // ИНН выдан Московской инспекцией ФНС
$ru->person(birthDate: $date);            // задана дата рождения

$person->gender;                          // 'женский'
$person->gender()->value;                 // 'female'
$person->birthDate;                       // '1987-02-12'
$person->inn;                             // '690847186716'

Согласованы все три части имени сразу. Пакет знает и отчества, образованные не по общему правилу, и фамилии, которые по роду не меняются:

$ru->person(Gender::Female)->fullName;  // 'Шевченко Валерия Ильинична' — не 'Ильиновна'

Книга собственная: 159 имён, 168 отчеств и 134 фамилии — больше восьмисот тысяч сочетаний на каждый пол. Сторонние справочники не подключаются.

Дата рождения выдаётся в ISO 8601 — в том виде, в каком её ждут база и JSON, а не в том, как её пишут в паспорте. Со скобками возвращается DateTimeImmutable. Задать её можно аргументом — например, для проверки возрастного ограничения:

$ru->person(birthDate: new DateTimeImmutable('-18 years'))->birthDate;  // день совершеннолетия

ИНН физлица — те же двенадцать знаков, что у предпринимателя, и это один и тот же номер: человек получает его до регистрации и оставляет себе после.

Генератор всегда выдаёт человека с номером, но в собранном вручную наборе его может не быть — человеку, который не вставал на учёт, ИНН не присвоен:

// без ИНН
new Person(
    $gender,
    'Иванов',
    'Иван',
    'Иванович',
    new DateTimeImmutable('1980-05-17'),
);

У предпринимателя такой набор не примут: регистрация ИП без ИНН невозможна.

$ip = $ru->organization(LegalForm::Ip);

$ip->inn;            // '789510950599'
$ip->person()->inn;  // '789510950599' — тот же номер

Банковские реквизиты

$ru->bankAccount();                        // банк и счета случайные
$ru->bankAccount($bik);                    // банк задан
$ru->bankAccount(null, LegalForm::Ip);     // балансовый счёт под форму клиента

Второй аргумент — форма клиента, от неё зависит балансовый счёт. Форму самого банка задать нельзя: она приходит вместе с его БИК.

Счёт всегда приходит вместе со своим банком: получить номер счёта отдельно нельзя, потому что без БИК не посчитать его контрольную сумму.

Поле Что это
shortName наименование банка: ярлык формы и название в кавычках
fullName то же наименование с полным названием формы
bik 9 знаков: территория, подразделение Банка России, номер участника
correspondent счёт банка в Банке России, начинается на 301
settlement расчётный счёт клиента: 40702 для организации, 40802 для ИП

Наименование банка устроено как у организации, с двумя отличиями. Слово «Банк» стоит внутри кавычек: закон «О банках и банковской деятельности» (№ 395-1) требует указания на характер деятельности прямо в наименовании. Форма — ООО, АО или ПАО: кредитная организация образуется как хозяйственное общество, и предпринимателем банк не бывает.

$bank->shortName;  // 'ПАО "Эталон Банк"'
$bank->fullName;   // 'Публичное акционерное общество "Эталон Банк"'

Наименование выводится из самого БИК, а не выбирается заново: один и тот же БИК всегда даёт один и тот же банк, сколько бы клиентов ему ни завели.

Балансовые счета взяты из Плана счетов Положения Банка России от 24.11.2022 № 809-П: 40702 «Коммерческие организации», 40802 «Индивидуальные предприниматели».

Проверка чужих значений

Каждый реквизит — самостоятельный тип с тремя способами разобрать чужую строку: isValid() отвечает true или false, tryFrom() — объектом или null, from() бросает исключение. Поэтому пакет работает и как валидатор, а не только как генератор.

use RuFaker\Requisite\Inn;

Inn::isValid('7707083893');  // true
Inn::isValid('7707083894');  // false — контрольная сумма не сходится
Inn::tryFrom('7707083894');  // null
Inn::from('7707083894');     // выбросит RuFaker\Exception\InvalidRequisite

Разобранное значение умеет отвечать на вопросы о себе:

$inn = Inn::from('7707083893');

$inn->value;         // '7707083893'
$inn->region();      // Requisite\Region — код '77'
$inn->isPersonal();  // false — это ИНН организации, а не физлица

Чтобы проверить номер конкретной правовой формы, передайте её вторым аргументом:

use RuFaker\Enum\LegalForm;
use RuFaker\Requisite\Ogrn;

Inn::isValid('7707083893', LegalForm::Ooo);       // true
Inn::isValid('7707083893', LegalForm::Ip);        // false — номер организации, а не предпринимателя
Ogrn::isValid('304500100000017', LegalForm::Ip);  // true

Двенадцатизначный ИНН выдают и предпринимателю, и обычному человеку: это один и тот же номер. Поэтому ИНН человека проверяется формой LegalForm::Ip.

Счёт проверяется только вместе с банком:

use RuFaker\Requisite\Account;
use RuFaker\Requisite\Bik;

Account::isValid('30101810400000000225', Bik::from('044525225'));  // true
Account::isValid('30101810400000000225', Bik::from('044030653'));  // false — другое подразделение

Номер записи реестра проверку не проходит. Он считается по той же формуле, что и ОГРН, а отличает его первый знак: у ОГРН организации это 1 или 5, у ОГРНИП — 3, у записи — 2 или 4.

use RuFaker\Requisite\Ogrn;

Ogrn::isValid('1027700132195');  // true — ОГРН организации
Ogrn::isValid('5067746006620');  // true — второй признак ОГРН организации
Ogrn::isValid('2027700132194');  // false — номер записи ЕГРЮЛ, а не ОГРН

Чем подтверждается реквизит

Реквизит Чем подтверждается
ИНН Контрольная сумма
ОГРН, ОГРНИП Первый знак номера и контрольная сумма
Счёт Контрольная сумма от номера и БИК
БИК, КПП Структура номера

Пакет проверяет формат реквизитов, а не существование организации.

Интеграция с Faker

Если уже используется Faker, его можно расширить этим пакетом с помощью провайдера:

use Faker\Factory;
use RuFaker\Faker\RuFakerProvider;
use RuFaker\Faker\Values;

$faker = Factory::create('ru_RU');
$faker->addProvider(new RuFakerProvider());
$faker->seed(1234);

$faker->ruFaker()->inn(LegalForm::Ooo);  // '6948917960'
$faker->ruFaker()->kpp();                // '547001001'
$faker->ruFaker()->bik();                // '046205450'

Пакет занимает у Faker одно имя — ruFaker(). Остальные форматтеры, включая inn10() и kpp() из локали ru_RU, работают как прежде.

Наборы приходят массивами — с теми же ключами, что у toArray():

$faker->ruFaker()->organization(LegalForm::Ooo);
// [
//     'form' => 'ООО',
//     'short_name' => 'ООО "Ладога"',
//     'full_name' => 'Общество с ограниченной ответственностью "Ладога"',
//     'region' => '83',
//     'inn' => '8331313714',
//     'ogrn' => '1188323159947',
//     'kpp' => '832301001',
//     'registration_date' => '2018-10-21',
//     'person' => null,
//     'head' => 'Ткаченко Станислав Геннадьевич',
//     'head_position' => 'Генеральный директор',
// ]

$faker->seed() управляет и значениями пакета.

Ограничения

Значения не совпадут с теми, что даёт RuFaker::seeded() с тем же числом: Faker сеет глобальный mt_srand(), оттуда провайдер и берёт случайность. Нужны те же — провайдер примет готовый пакет:

$faker->addProvider(new RuFakerProvider(new Values(RuFaker::seeded(1234))));

$faker->unique() и $faker->optional() с ruFaker() не работают: обёртка применяется к самому ruFaker(), а не к реквизиту за ним.

$faker->unique()->ruFaker()->inn();    // со второго вызова — OverflowException
$faker->optional()->ruFaker()->inn();  // иногда Error: Call to a member function inn() on null

Рецепты

Фабрика модели

Поля набора — обычные строки, поэтому подставляются в атрибуты напрямую:

public function definition(): array
{
    $company = (new RuFaker())->organization(LegalForm::Ooo);

    return [
        'title' => $company->shortName,
        'inn' => $company->inn,
        'kpp' => $company->kpp,
        'ogrn' => $company->ogrn,
    ];
}

Если имена колонок совпадают с ключами набора, разворачивается целиком:

return [...$company->toArray(), 'is_active' => true];

Фикстура в JSON

file_put_contents(
    'fixture.json',
    json_encode($ru->organization(LegalForm::Ip), JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT),
);
// {
//     "form": "ИП",
//     "short_name": "ИП Фролова Елена Аркадьевна",
//     "full_name": "Индивидуальный предприниматель Фролова Елена Аркадьевна",
//     "region": "23",
//     "inn": "236594540500",
//     "ogrn": "325238241191511",
//     "kpp": null,
//     "registration_date": "2025-09-14",
//     "person": "Фролова Елена Аркадьевна",
//     "head": null,
//     "head_position": null
// }

Один и тот же набор в каждом прогоне

Источник случайности — штатный Random\Randomizer. Одинаковый seed даёт одинаковый результат, поэтому упавший тест воспроизводится:

RuFaker::seeded(1234)->organization()->toArray();
// [
//     'form' => 'ИП',
//     'short_name' => 'ИП Копылова Оксана Назаровна',
//     'full_name' => 'Индивидуальный предприниматель Копылова Оксана Назаровна',
//     'region' => '55',
//     'inn' => '555104382976',
//     'ogrn' => '319556702274085',
//     'kpp' => null,
//     'registration_date' => '2019-04-26',
//     'person' => 'Копылова Оксана Назаровна',
//     'head' => null,
//     'head_position' => null,
// ]

Сравнивать нужно массивы, а не наборы: два объекта с одинаковым содержимым совпадут по ==, но по === — никогда, это разные объекты.

Можно подставить свой движок, если нужен другой алгоритм:

use Random\Engine\Xoshiro256StarStar;
use Random\Randomizer;

$ru = new RuFaker(new Randomizer(new Xoshiro256StarStar(1234)));

Организация и её расчётный счёт

Балансовый счёт зависит от организационно-правовой формы, поэтому форму передают дальше:

$company = $ru->organization(LegalForm::Ip);
$bank = $ru->bankAccount(null, $company->form());

$company->inn;      // '193983068463'
$bank->bik;         // '040426598'
$bank->settlement;  // '40802810200009422091' — 40802, счёт предпринимателя

Для ООО тот же код даст счёт на 40702.

Человек, а потом предприниматель

В фикстуре человек сначала физлицо, а потом открывает ИП. Номер у них один: ИНН выдают физлицу до регистрации, и после неё он остаётся тем же.

$person = $ru->person(Gender::Male, Region::from('66'));
$ip = $ru->organization(person: $person);

$person->inn;    // '661609485615'
$ip->inn;        // '661609485615' — тот же номер
$ip->shortName;  // 'ИП Ефимов Вадим Фёдорович'
$ip->ogrn;       // '323662710664985'
$ip->region;     // '66'

Форму и регион задаёт сам человек: форма — Ip, регион — тот, что стоит в его ИНН. Аргумент, который ему противоречит, отвергается: чужой регион, другой пол, форма юрлица, наименование. Человека без ИНН и человека младше восемнадцати предпринимателем не сделать.

Реквизиты и подпись в документе

Договор или акт подписывает руководитель, поэтому организация и банк собираются вместе:

$company = $ru->organization(LegalForm::Ooo, Region::from('19'));
$bank = $ru->bankAccount(null, $company->form());

echo <<<DOC
{$company->fullName}
ИНН {$company->inn}, КПП {$company->kpp}, ОГРН {$company->ogrn}
Р/с {$bank->settlement} в {$bank->shortName}, БИК {$bank->bik}

{$company->headPosition}  ____________  {$company->head}
DOC;

// Общество с ограниченной ответственностью "Горизонт"
// ИНН 1960439830, КПП 198801001, ОГРН 1121988966263
// Р/с 40702810800007455284 в ПАО "Вершина Банк", БИК 049227276
//
// Генеральный директор  ____________  Герасимов Семён Степанович

Должность и ФИО стоят в именительном падеже, поэтому годятся для подписи. Для оборота «в лице генерального директора Герасимова С. С.» падеж придётся поставить самому: склонений в пакете нет.

Несколько клиентов одного банка

Если передать один Bik, корреспондентский счёт совпадёт, а расчётные будут разными:

$bik = $ru->bik();  // '047298058'

$first = $ru->bankAccount($bik);
$second = $ru->bankAccount($bik);

$first->shortName;      // 'ООО "Лотос Банк"'
$second->shortName;     // то же наименование: банк один

$first->correspondent;  // '30101810600000000058' — счёт самого банка
$second->correspondent; // тот же самый

$first->settlement;     // '40702810000004768305'
$second->settlement;    // '40702810800008330269'

Ключ у обоих расчётных сходится с этим БИК — проверка Account::isValid() их примет.

Справочник

Генерация. Источник случайности задаётся конструктором: new RuFaker(), new RuFaker($randomizer) или RuFaker::seeded(1234). Заданные части набора передаются именованными аргументами: initials, person, title, birthDate.

Вызов Отдаёт
organization(?LegalForm, ?Region, ?Gender, bool, ?Person, ?string) Result\Organization
person(?Gender, ?Region, ?DateTimeImmutable) Result\Person
bankAccount(?Bik, ?LegalForm) Result\BankAccount
inn(?LegalForm, ?Region) Requisite\Inn
ogrn(?LegalForm, ?Region) Requisite\Ogrn
kpp(?Region) Requisite\Kpp
bik() Requisite\Bik

Наборы. У каждого есть toArray() и json_encode(); Person дополнительно приводится к строке — это его fullName.

Поле Без скобок Со скобками
$company->shortName, $company->fullName string
$company->form string Enum\LegalForm
$company->region string Requisite\Region
$company->inn string Requisite\Inn
$company->ogrn string Requisite\Ogrn
$company->kpp string|null Requisite\Kpp|null
$company->registrationDate string DateTimeImmutable
$company->person() Result\Person|null
$company->head string|null Result\Person|null
$company->headPosition string|null
$bank->shortName, $bank->fullName string
$bank->bik string Requisite\Bik
$bank->correspondent string Requisite\Account
$bank->settlement string Requisite\Account
$person->gender string Enum\Gender
$person->fullName, lastName, firstName, patronymic string
$person->birthDate string DateTimeImmutable
$person->inn string|null Requisite\Inn|null

Реквизиты. У всех шести одинаково: isValid(), tryFrom(), from(), свойство ->value, приведение к строке и сериализация в JSON. У Account первые три принимают вторым аргументом Bik, у Inn и Ogrn — необязательную LegalForm.

Тип Что ещё умеет Контрольная сумма
Inn region(), isPersonal() да
Ogrn region(), year(), isIndividual() да
Kpp region(), reason() нет, только формат
Bik territory(), division(), participant() нет, только формат
Account isCorrespondent(), isSettlement() да, от БИК
Region нет, только диапазон

Перечисления. Enum\LegalFormOoo, Ao, Pao, Ip; умеет balanceAccount(), hasKpp(), isIndividual(), isCorporate(), shortTitle() и fullTitle(). Enum\GenderMale, Female; умеет title(), isMale() и isFemale(). У обоих штатные cases(), from(), tryFrom() и ->value.

Провайдер к Faker. $faker->addProvider(new RuFakerProvider()) заводит единственное имя ruFaker(); за ним стоит Faker\Values, чей конструктор принимает свой RuFaker. Вызовы зеркалят фасад, но отдают строки и массивы.

Вызов Отдаёт
ruFaker()->organization(?LegalForm, ?Region, ?Gender, bool, ?Person, ?string) array
ruFaker()->person(?Gender, ?Region, ?DateTimeImmutable) array
ruFaker()->bankAccount(?Bik, ?LegalForm) array
ruFaker()->inn(?LegalForm, ?Region) string
ruFaker()->ogrn(?LegalForm, ?Region) string
ruFaker()->kpp(?Region) string
ruFaker()->bik() string

Известные ограничения

  • Название юрлица — одно слово из словаря в 127 слов; у банка — то же слово плюс «Банк».
  • Наименование банка не связано с настоящим владельцем БИК: оно выводится из самого номера, а справочник действующих кредитных организаций в пакет не входит.
  • Код территории внутри БИК не связан с регионом организации: соответствие кодов ОКАТО и кодов ФНС требует справочника, а справочники в пакет намеренно не включаются.
  • Правило расчёта суммы выбирает балансовый счёт — первые пять разрядов номера. Однозначны 30101 и 40102 со стороны Банка России, 40702, 40703, 40802, 40817 и 40820 со стороны банка; остальные счета принимаются, если сумма сходится хотя бы по одному из правил.
  • Казначейский счёт — номер начинается на 0 — принимается по структуре: контрольной суммы у него нет.
  • Контрольная сумма счёта, в документах Банка России — контрольный ключ, сходится не с банком, а с частью БИК: у корреспондентского счёта с разрядами 5–6, номером подразделения Банка России, у расчётного — с разрядами 7–9. Банки с одинаковыми разрядами дают одинаковую сумму, поэтому Account::isValid() примет счёт любого из них.
  • КПП выдаётся с причиной постановки на учёт 01 и порядковым номером 001, то есть для головной организации. Обособленные подразделения не генерируются.
  • Дата регистрации выбирается от дня, когда открылся реестр, до конца прошлого года: с 01.07.2002 у организации, с 01.01.2004 у предпринимателя. Верхняя граница едет вместе с календарём, поэтому дата не бывает в будущем, а значения по одному seed держатся весь год и меняются 1 января.
  • Год внутри ОГРН генератор берёт из даты регистрации, а не выбирает отдельно. Номер несёт две последние цифры, и Ogrn::year() достраивает век двадцать первым: оба реестра открылись в 2000-х, и записей прошлого века в них нет.
  • Предприниматель регистрируется не раньше восемнадцатилетия. Закон разрешает регистрацию с 14 лет по согласию родителей, но генератор такие наборы не выдаёт; конструктор принимает любую дату начиная со дня рождения.
  • Генерация берёт код субъекта РФ из 83 значений, а проверка принимает любой код от 01 до 99: перечень кодов — данные, и он правится patch-выпуском.
  • Дата рождения выбирается от начала года, отстоящего на 80 лет, до конца года, отстоящего на 19: самый молодой человек стал совершеннолетним не позже конца прошлого года. Границы едут вместе с календарём, поэтому окно не стареет, а значения по seed меняются 1 января.
  • Должность руководителя — одна из трёх: «Генеральный директор», «Директор» и «Президент». Так единоличный исполнительный орган называют статья 40 закона 14-ФЗ и статья 69 закона 208-ФЗ.
  • ФИО и должность выдаются в именительном падеже: склонения по падежам в пакете нет.

Совместимость

Публичный API — фасад RuFaker и типы из Requisite\, Result\, Enum\ и Exception\. Всё, что помечено @internal — пространство имён RuFaker\Internal\ целиком и отдельные методы реквизитов, нужные только генераторам, — меняется и исчезает без предупреждения: семантическое версионирование на него не распространяется.

Пока версия остаётся в ветке 0.x, публичный API тоже может измениться в минорном выпуске — об этом говорит CHANGELOG.md.

Разработка

composer install
composer test     # тесты на PHP хоста
composer stan     # статический анализ, level 10
composer check    # то и другое

Поддерживаются PHP 8.3, 8.4 и 8.5 — все три проверяются в CI. Зависимости разрешаются под минимальную версию: composer.json объявляет config.platform.php.

Для каждой версии есть контейнер — можно и прогнать тесты, и работать внутри:

docker compose run --rm php83 composer install

composer test:83   # то же самое для test:84 и test:85
docker compose run --rm php85 sh   # оболочка внутри контейнера

Лицензия

MIT — см. LICENSE.