insee_number_translator/data/insee_data.go

150 lines
3.6 KiB
Go

package data
import (
"fmt"
"strconv"
"strings"
"time"
)
type InseeData struct {
InseeNumber string
Gender string
Year int
Month time.Month
Department string
City string
Foreign bool
Country string
OrderOfBirth int
ControlKey int
}
func NewInseeData(inseeNumber string) (*InseeData, error) {
if len(inseeNumber) != 15 {
return nil, fmt.Errorf("provided insee number must contain 15 characters")
}
num := inseeNumber
department := num[5:7]
city := num[7:10]
if department == "97" || department == "98" {
department = num[5:8]
city = num[8:10]
}
dep, err := strconv.Atoi(department)
if err != nil {
return nil, err
}
foreign := false
country := "FR"
if (dep >= 91 && dep <= 96) || dep == 99 {
foreign = true
country = city
city = "unknown"
department = "unknown"
}
order, err := strconv.Atoi(num[10:13])
if err != nil {
return nil, err
}
controlKey, err := strconv.Atoi(num[13:])
if err != nil {
return nil, err
}
monthInt, err := strconv.Atoi(num[3:5])
if err != nil {
return nil, err
}
month := time.Month(monthInt)
year, err := strconv.Atoi(num[1:3])
if err != nil {
return nil, err
}
year += 2000
now := time.Now()
birthday := time.Date(year, month, 1, 0, 0, 0, 0, time.UTC)
if birthday.After(now) {
year -= 100
}
gender := num[0:1]
if gender == "1" {
gender = "Male"
} else {
gender = "Female"
}
return &InseeData{
InseeNumber: num,
Gender: gender,
Year: year,
Month: month,
Department: department,
City: city,
Foreign: foreign,
Country: country,
OrderOfBirth: order,
ControlKey: controlKey,
}, nil
}
func (insee InseeData) IsValid() (bool, error) {
num := strings.Replace(insee.InseeNumber, "2A", "19", 1)
num = strings.Replace(num, "2B", "18", 1)[:len(num)-2]
numInt, err := strconv.Atoi(num)
if err != nil {
return false, err
}
code := 97 - (numInt % 97)
return code == insee.ControlKey, nil
}
func (insee InseeData) String() string {
var message []string
valid, err := insee.IsValid()
if err != nil {
return err.Error()
}
if valid {
message = append(message, "The number is valid.")
} else {
message = append(message, "The number is invalid.")
}
msg := fmt.Sprintf("You're a %s, born in %s, probably in %d.", insee.Gender, insee.Month, insee.Year)
message = append(message, msg)
var zoneType string
var line string
if insee.Foreign {
zoneType = "country"
line = "You were born outside France, "
country, present := countries["99"+insee.Country]
continent := continents[insee.Country[0:1]]
continent = fmt.Sprintf(" (%s)", continent)
if present && len(country) > 1 {
line += "probably in either one of these countries/territories: "
line += strings.Join(country, ", ")
line += continent
} else if present && len(country) == 1 {
line += fmt.Sprintf("in %s%s", country[0], continent)
} else {
line += "in an unknown country numbered " + insee.Country
}
} else {
zoneType = "city"
city, cityPresent := cities[insee.Department+insee.City]
department, depPresent := departments[insee.Department]
if !depPresent {
department = "unknown department"
}
if cityPresent {
line = fmt.Sprintf("You were born in %s, %s (%s), France.", city.Name, city.ZipCode, department)
} else {
line = fmt.Sprintf("You were born in an unknown city numbered %s, which is located in %s, in France", insee.City, department)
}
}
message = append(message, line)
line = fmt.Sprintf("You were the %dth to be born in this %s on this month.", insee.OrderOfBirth, zoneType)
message = append(message, line)
return strings.Join(message, "\n")
}