Added ability to set input age for pesel generator. No additional checks implemented - min < max or starting age of 1800. Someday...
This commit is contained in:
@@ -2,10 +2,8 @@ import { NgModule } from '@angular/core';
|
|||||||
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
|
||||||
import { BrowserModule } from '@angular/platform-browser';
|
import { BrowserModule } from '@angular/platform-browser';
|
||||||
import { AppComponent } from './components/app/app.component';
|
import { AppComponent } from './components/app/app.component';
|
||||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
|
||||||
import { MatInputModule } from '@angular/material/input';
|
import { MatInputModule } from '@angular/material/input';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { MatGridListModule } from '@angular/material/grid-list';
|
|
||||||
import { ClipboardModule } from '@angular/cdk/clipboard';
|
import { ClipboardModule } from '@angular/cdk/clipboard';
|
||||||
import { MatSnackBarModule} from '@angular/material/snack-bar';
|
import { MatSnackBarModule} from '@angular/material/snack-bar';
|
||||||
import { TranslatePipe } from './translate-pipe';
|
import { TranslatePipe } from './translate-pipe';
|
||||||
@@ -13,6 +11,7 @@ import { PeselComponent } from './components/pesel/pesel.component';
|
|||||||
import { NipComponent } from './components/nip/nip.component';
|
import { NipComponent } from './components/nip/nip.component';
|
||||||
import { RegonComponent } from './components/regon/regon.component';
|
import { RegonComponent } from './components/regon/regon.component';
|
||||||
import { IbanComponent } from './components/iban/iban.component';
|
import { IbanComponent } from './components/iban/iban.component';
|
||||||
|
import {NgOptimizedImage} from "@angular/common";
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
@@ -26,13 +25,12 @@ import { IbanComponent } from './components/iban/iban.component';
|
|||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
BrowserAnimationsModule,
|
|
||||||
MatInputModule,
|
MatInputModule,
|
||||||
MatIconModule,
|
MatIconModule,
|
||||||
MatGridListModule,
|
|
||||||
ClipboardModule,
|
ClipboardModule,
|
||||||
MatSnackBarModule,
|
MatSnackBarModule,
|
||||||
ReactiveFormsModule,
|
ReactiveFormsModule,
|
||||||
|
NgOptimizedImage,
|
||||||
],
|
],
|
||||||
providers: [TranslatePipe],
|
providers: [TranslatePipe],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
|
|||||||
@@ -2,18 +2,27 @@
|
|||||||
<div class="title">
|
<div class="title">
|
||||||
<span>PESEL</span>
|
<span>PESEL</span>
|
||||||
<div class="titleButtons">
|
<div class="titleButtons">
|
||||||
<img id="malePeselButton" src="assets/male_black_24dp.svg" title="Płeć męska" alt="Czy generować męskie numery PESEL" (click)="toggleMale()" [style.background] = "generateMale ? 'rgba(0, 0, 0, 0.35)' : ''" />
|
<input id="minAgeInput" type="number" [(ngModel)]="minAge"/>
|
||||||
|
<div class="titleBarText">-</div>
|
||||||
|
<input id="maxAgeInput" type="number" [(ngModel)]="maxAge"/>
|
||||||
|
<div style="width: 40px;"></div>
|
||||||
|
<img id="malePeselButton" ngSrc="assets/male_black_24dp.svg" title="Płeć męska" alt="Czy generować męskie numery PESEL" (click)="toggleMale()" [style.background] = "generateMale ? 'rgba(0, 0, 0, 0.35)' : ''"
|
||||||
|
height="24" width="24"/>
|
||||||
<div style="width: 20px;"></div>
|
<div style="width: 20px;"></div>
|
||||||
<img id="femalePeselButton" src="assets/female_black_24dp.svg" title="Płeć żeńska" alt="Czy generować żeńskie numery PESEL" (click)="toggleFemale()" [style.background] = "generateFemale ? 'rgba(0, 0, 0, 0.35)' : ''" />
|
<img id="femalePeselButton" ngSrc="assets/female_black_24dp.svg" title="Płeć żeńska" alt="Czy generować żeńskie numery PESEL" (click)="toggleFemale()" [style.background] = "generateFemale ? 'rgba(0, 0, 0, 0.35)' : ''"
|
||||||
|
height="24" width="24"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<input type="text" [formControl]="valueField" />
|
<input type="text" [formControl]="valueField" />
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons">
|
||||||
<img id="peselGenerateButton" src="assets/autorenew_black_24dp.svg" title="Generuj numer PESEL" alt="Generuj numer PESEL" style="margin-left: 1em;" (click)="generate()"/>
|
<img id="peselGenerateButton" ngSrc="assets/autorenew_black_24dp.svg" title="Generuj numer PESEL" alt="Generuj numer PESEL" style="margin-left: 1em;" (click)="generate()"
|
||||||
<img id="peselCopyButton" src="assets/content_copy_black_24dp.svg" title="Skopiuj numer PESEL do schowka" alt="Skopiuj numer PESEL do schowka" style="margin: auto 1em;" (click)="copyToClipboard()"/>
|
height="24" width="24"/>
|
||||||
<img id="peselHelpButton" src="assets/info_black_24dp.svg" title="Szczegóły dotyczące numeru PESEL" alt="Definicja numeru PESEL na Wikipedii" (click)="navigateToDocs()" />
|
<img id="peselCopyButton" ngSrc="assets/content_copy_black_24dp.svg" title="Skopiuj numer PESEL do schowka" alt="Skopiuj numer PESEL do schowka" style="margin: auto 1em;" (click)="copyToClipboard()"
|
||||||
|
height="24" width="24"/>
|
||||||
|
<img id="peselHelpButton" ngSrc="assets/info_black_24dp.svg" title="Szczegóły dotyczące numeru PESEL" alt="Definicja numeru PESEL na Wikipedii" (click)="navigateToDocs()"
|
||||||
|
height="24" width="24"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -14,6 +14,8 @@ export class PeselComponent implements OnInit {
|
|||||||
|
|
||||||
public generateMale: boolean;
|
public generateMale: boolean;
|
||||||
public generateFemale: boolean;
|
public generateFemale: boolean;
|
||||||
|
public minAge: number;
|
||||||
|
public maxAge: number;
|
||||||
|
|
||||||
constructor(private peselService: PeselService, private clipboardService: ClipboardService) {
|
constructor(private peselService: PeselService, private clipboardService: ClipboardService) {
|
||||||
this.valueField = new FormControl('pesel');
|
this.valueField = new FormControl('pesel');
|
||||||
@@ -21,6 +23,8 @@ export class PeselComponent implements OnInit {
|
|||||||
|
|
||||||
this.generateMale = true;
|
this.generateMale = true;
|
||||||
this.generateFemale = true;
|
this.generateFemale = true;
|
||||||
|
this.minAge = 18;
|
||||||
|
this.maxAge = 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
@@ -28,11 +32,11 @@ export class PeselComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
generate(): void {
|
generate(): void {
|
||||||
if (this.generateMale === false && this.generateFemale === false) {
|
if (!this.generateMale && !this.generateFemale) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.valueField.setValue(this.peselService.generatePesel(this.generateMale, this.generateFemale));
|
this.valueField.setValue(this.peselService.generatePesel(this.generateMale, this.generateFemale, this.minAge, this.maxAge));
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleMale(): void {
|
toggleMale(): void {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { CommonService } from './common.service';
|
import { CommonService } from './common.service';
|
||||||
import { endOfMonth } from 'date-fns'
|
import {addDays, addYears, differenceInDays, endOfMonth} from 'date-fns'
|
||||||
import { ValidationErrors } from '@angular/forms';
|
import { ValidationErrors } from '@angular/forms';
|
||||||
import { concat } from 'rxjs';
|
|
||||||
|
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
@@ -10,30 +9,45 @@ import { concat } from 'rxjs';
|
|||||||
})
|
})
|
||||||
export class PeselService {
|
export class PeselService {
|
||||||
// wagi kolejnych cyfr numeru PESEL
|
// wagi kolejnych cyfr numeru PESEL
|
||||||
private readonly peselWeights: number[] = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
|
private static readonly peselWeights: number[] = [1, 3, 7, 9, 1, 3, 7, 9, 1, 3];
|
||||||
|
|
||||||
private readonly maleDigits: number[] = [1, 3, 5, 7, 9];
|
private static readonly maleDigits: number[] = [1, 3, 5, 7, 9];
|
||||||
|
|
||||||
private readonly femaleDigits: number[] = [0, 2, 4, 6, 8];
|
private static readonly femaleDigits: number[] = [0, 2, 4, 6, 8];
|
||||||
|
|
||||||
constructor(private common: CommonService) { }
|
constructor(private common: CommonService) { }
|
||||||
|
|
||||||
public generatePesel(male: boolean, female: boolean): string {
|
public generatePesel(male: boolean, female: boolean, minAge: number, maxAge: number): string {
|
||||||
|
console.log('Generating PESEL female: ', female, ', male: ', male, ' with age range:', minAge, 'to', maxAge);
|
||||||
|
console.log('Current date:', new Date())
|
||||||
|
|
||||||
|
// ustalenie granicznych dat
|
||||||
|
const startDate = addYears(new Date(), -maxAge);
|
||||||
|
const endDate = addYears(new Date(), -minAge);
|
||||||
|
|
||||||
|
// wyliczenie roznicy w dniach i jej dolanie do daty startowej
|
||||||
|
const difference = differenceInDays(endDate, startDate);
|
||||||
|
console.log("Difference in days: ", difference)
|
||||||
|
|
||||||
|
const finalDate = addDays(startDate, this.common.getRandomInt(0, difference));
|
||||||
|
|
||||||
|
console.log('Final date:', finalDate);
|
||||||
|
|
||||||
// losowanie pierwszych 10 cyfr
|
// losowanie pierwszych 10 cyfr
|
||||||
const year: number = this.common.getRandomInt(0, 99);
|
const fullYear: number = finalDate.getFullYear();
|
||||||
const month: number = this.common.getRandomInt(1, 12);
|
const year: number = fullYear % 100;
|
||||||
const endDayOfMonth: number = endOfMonth(new Date(year, month - 1)).getDate();
|
const month: number = this.encodePeselMonth(finalDate.getMonth() + 1, fullYear);
|
||||||
const day: number = this.common.getRandomInt(1, endDayOfMonth);
|
const day: number = finalDate.getDate();
|
||||||
const rest: number = this.common.getRandomInt(0, 999);
|
const rest: number = this.common.getRandomInt(0, 999);
|
||||||
|
|
||||||
const sexDigits: number[] = [... male ? this.maleDigits : [], ...female ? this.femaleDigits : []];
|
const sexDigits: number[] = [... male ? PeselService.maleDigits : [], ...female ? PeselService.femaleDigits : []];
|
||||||
|
|
||||||
const sexDigitIndex: number = this.common.getRandomInt(0, sexDigits.length - 1);
|
const sexDigitIndex: number = this.common.getRandomInt(0, sexDigits.length - 1)
|
||||||
const sexDigit = sexDigits[sexDigitIndex];
|
const sexDigit = sexDigits[sexDigitIndex]
|
||||||
|
|
||||||
// wyliczenie cyfry kontrolnej
|
// wyliczenie cyfry kontrolnej
|
||||||
const peselWithoutControlDigit: string = this.common.pad(year, 2) + this.common.pad(month, 2) + this.common.pad(day, 2) + this.common.pad(rest, 3) + this.common.pad(sexDigit, 1);
|
const peselWithoutControlDigit: string = this.common.pad(year, 2) + this.common.pad(month, 2) + this.common.pad(day, 2) + this.common.pad(rest, 3) + this.common.pad(sexDigit, 1);
|
||||||
const controlDigit: number = this.common.calculateControlDigit(peselWithoutControlDigit, this.peselWeights, this.lastStepFunction);
|
const controlDigit: number = this.common.calculateControlDigit(peselWithoutControlDigit, PeselService.peselWeights, this.lastStepFunction);
|
||||||
|
|
||||||
// ostateczna konkatenacja
|
// ostateczna konkatenacja
|
||||||
return peselWithoutControlDigit + controlDigit;
|
return peselWithoutControlDigit + controlDigit;
|
||||||
@@ -87,7 +101,7 @@ export class PeselService {
|
|||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
private validatePeselControlDigit(pesel: string): boolean {
|
private validatePeselControlDigit(pesel: string): boolean {
|
||||||
return this.common.validateControlDigit(pesel, this.peselWeights, this.lastStepFunction);
|
return this.common.validateControlDigit(pesel, PeselService.peselWeights, this.lastStepFunction);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -159,6 +173,23 @@ export class PeselService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private encodePeselMonth(month: number, year: number): number {
|
||||||
|
if (year >= 1800 && year <= 1899) {
|
||||||
|
return month + 80;
|
||||||
|
}
|
||||||
|
if (year >= 2000 && year <= 2099) {
|
||||||
|
return month + 20;
|
||||||
|
}
|
||||||
|
if (year >= 2100 && year <= 2199) {
|
||||||
|
return month + 40;
|
||||||
|
}
|
||||||
|
if (year >= 2200 && year <= 2299) {
|
||||||
|
return month + 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
return month;
|
||||||
|
}
|
||||||
|
|
||||||
private lastStepFunction(sum: number): number {
|
private lastStepFunction(sum: number): number {
|
||||||
sum = sum % 10;
|
sum = sum % 10;
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ body {
|
|||||||
input[type="text"] {
|
input[type="text"] {
|
||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
width: 210px;
|
width: 210px;
|
||||||
min-width: 0px;
|
min-width: 0;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
padding: 0 0.7em;
|
padding: 0 0.7em;
|
||||||
@@ -147,6 +147,41 @@ input[type="text"] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input[type="number"] {
|
||||||
|
-moz-appearance:textfield; /* Firefox */
|
||||||
|
margin: auto 0;
|
||||||
|
width: 37px;
|
||||||
|
min-width: 0;
|
||||||
|
flex-grow: 1;
|
||||||
|
flex-shrink: 1;
|
||||||
|
padding: 0 0.1em;
|
||||||
|
letter-spacing: 1px;
|
||||||
|
font-size: 0.8em;
|
||||||
|
height: 1.5em;
|
||||||
|
color: white;
|
||||||
|
|
||||||
|
background: rgba(255, 255, 255, 0.15);
|
||||||
|
box-shadow: 0 8px 32px 0 rgba( 0, 38, 135, 0.37 );
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid rgba( 255, 255, 255, 0.20 );
|
||||||
|
}
|
||||||
|
|
||||||
|
input::-webkit-outer-spin-button,
|
||||||
|
input::-webkit-inner-spin-button {
|
||||||
|
display: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.titleBarText {
|
||||||
|
width: 20px;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
letter-spacing: 2px;
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
filter: invert(100%);
|
filter: invert(100%);
|
||||||
|
|||||||
Reference in New Issue
Block a user