Skip to content
This repository has been archived by the owner on Dec 11, 2020. It is now read-only.

Generates a random NIR number (fr_FR) #997

Merged
merged 3 commits into from
Jan 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -991,6 +991,15 @@ echo $faker->siren; // 082 250 104
echo $faker->siret; // 347 355 708 00224
```

### `Faker\Provider\fr_FR\Person`

```php
<?php

// Generates a random NIR / Sécurité Sociale number
echo $faker->nir; // 1 88 07 35 127 571 - 19
```

### `Faker\Provider\he_IL\Payment`

```php
Expand Down
59 changes: 59 additions & 0 deletions src/Faker/Provider/fr_FR/Person.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,63 @@ public static function prefix()
{
return static::randomElement(static::$prefix);
}

/**
* Generates a NIR / Sécurité Sociale number (13 digits + 2 digits for the key)
*
* @see https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France
* @return string
*/
public function nir($gender = null, $formatted = false)
{
// Gender
if ($gender === static::GENDER_MALE) {
$nir = 1;
} elseif ($gender === static::GENDER_FEMALE) {
$nir = 2;
} else {
$nir = $this->numberBetween(1, 2);
}

$nir .=
// Year of birth (aa)
$this->numerify('##') .
// Mont of birth (mm)
sprintf('%02d', $this->numberBetween(1, 12));

// Department
$department = key(Address::department());
$nir .= $department;

// Town number, depends on department length
if (strlen($department) === 2) {
$nir .= $this->numerify('###');
} elseif (strlen($department) === 3) {
$nir .= $this->numerify('##');
}

// Born number (depending of town and month of birth)
$nir .= $this->numerify('###');

/**
* The key for a given NIR is `97 - 97 % NIR`
* NIR has to be an integer, so we have to do a little replacment
* for departments 2A and 2B
*/
if ($department === '2A') {
$nirInteger = str_replace('2A', '19', $nir);
} elseif ($department === '2B') {
$nirInteger = str_replace('2B', '18', $nir);
} else {
$nirInteger = $nir;
}
$nir .= sprintf('%02d', 97 - $nirInteger % 97);

// Format is x xx xx xx xxx xxx xx
if ($formatted) {
$nir = substr($nir, 0, 1) . ' ' . substr($nir, 1, 2) . ' ' . substr($nir, 3, 2) . ' ' . substr($nir, 5, 2) . ' ' . substr($nir, 7, 3). ' ' . substr($nir, 10, 3). ' ' . substr($nir, 13, 2);
}

return $nir;
}
}
36 changes: 36 additions & 0 deletions test/Faker/Provider/fr_FR/PersonTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

namespace Faker\Test\Provider\fr_FR;

use Faker\Generator;
use Faker\Provider\fr_FR\Person;

class PersonTest extends \PHPUnit_Framework_TestCase
{
private $faker;

public function setUp()
{
$faker = new Generator();
$faker->addProvider(new Person($faker));
$this->faker = $faker;
}

public function testNIRReturnsTheRightGender()
{
$nir = $this->faker->nir(\Faker\Provider\Person::GENDER_MALE);
$this->assertStringStartsWith('1', $nir);
}

public function testNIRReturnsTheRightPattern()
{
$nir = $this->faker->nir;
$this->assertRegExp("/^[12]\d{5}[0-9A-B]\d{8}$/", $nir);
}

public function testNIRFormattedReturnsTheRightPattern()
{
$nir = $this->faker->nir(null, true);
$this->assertRegExp("/^[12]\s\d{2}\s\d{2}\s\d{1}[0-9A-B]\s\d{3}\s\d{3}\s\d{2}$/", $nir);
}
}