Ajout du frontend et branchement sur l'API axione #9
3 changed files with 143 additions and 78 deletions
|
@ -34,7 +34,7 @@ def fantoirRequest(insee, rivoli, numVoie):
|
||||||
<com:operateurCommercial nom="AQUILENET" identifiant=""/>
|
<com:operateurCommercial nom="AQUILENET" identifiant=""/>
|
||||||
</ent:entete>
|
</ent:entete>
|
||||||
<ent:referenceAdresse>
|
<ent:referenceAdresse>
|
||||||
<com:referenceRivoli codeInsee="{insee}" codeRivoli="{rivoli}" numeroVoie="{numvoie}"/>
|
<com:referenceRivoli codeInsee="{insee}" codeRivoli="{rivoli}" numeroVoie="{numVoie}"/>
|
||||||
</ent:referenceAdresse>
|
</ent:referenceAdresse>
|
||||||
</ent:obtentionStructureAdresseDemandeSoap>
|
</ent:obtentionStructureAdresseDemandeSoap>
|
||||||
</soapenv:Body>
|
</soapenv:Body>
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
|
|
||||||
<html lang="fr">
|
<html lang="fr">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"
|
||||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
|
integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
|
||||||
|
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
|
||||||
|
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
|
||||||
<title>Aquilenet: Éligibilité FTTH</title>
|
<title>Aquilenet: Éligibilité FTTH</title>
|
||||||
<style>
|
<style>
|
||||||
{% include 'style.css' %}
|
{% include 'style.css'%}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
@ -24,16 +31,20 @@
|
||||||
<div class="col-12 text-intro">
|
<div class="col-12 text-intro">
|
||||||
<div id="methodPto" class="collapse show testMethods">
|
<div id="methodPto" class="collapse show testMethods">
|
||||||
|
|
||||||
<h2 class="text-center form-title">Test d'éligibilité par PTO</h1>
|
<h2 class="text-center form-title">Test d'éligibilité par PTO</h2>
|
||||||
<form method="post" action="/test/pto">
|
<form method="post" action="/test/pto">
|
||||||
<div class="form-group" id="ptoForm">
|
<div class="form-group" id="ptoForm">
|
||||||
<label class="form-label" for="pto-number">Numéro PTO</label>
|
<label class="form-label" for="pto-number">Numéro PTO</label>
|
||||||
<input required type="text" class="form-control" name="pto" id="pto-number" aria-describedby="ptoHelp" placeholder="OOOO-XXXX-XXXX" oninvalid="this.setCustomValidity('Veuillez renseigner le PTO')" oninput="setCustomValidity('')">
|
<input required type="text" class="form-control" name="pto" id="pto-number" aria-describedby="ptoHelp"
|
||||||
|
placeholder="OOOO-XXXX-XXXX" oninvalid="this.setCustomValidity('Veuillez renseigner le PTO')"
|
||||||
|
oninput="setCustomValidity('')">
|
||||||
|
|
||||||
<small id="ptoHelp" class="form-text btn btn-link" data-toggle="collapse" data-target="#ptoInfo" aria-expanded="true" aria-controls="ptoInfo">Où trouver mon numéro de PTO ?</small>
|
<small id="ptoHelp" class="form-text btn btn-link" data-toggle="collapse" data-target="#ptoInfo"
|
||||||
|
aria-expanded="true" aria-controls="ptoInfo">Où trouver mon numéro de PTO ?</small>
|
||||||
<div id="ptoInfo" class="collapse" aria-labelledby="ptoForm" data-parent="#ptoForm">
|
<div id="ptoInfo" class="collapse" aria-labelledby="ptoForm" data-parent="#ptoForm">
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
PTO (Point de terminaison optique) est un numéro unique que vous pouvez trouver sur le boîtier de raccordement de la fibre.
|
PTO (Point de terminaison optique) est un numéro unique que vous pouvez trouver sur le boîtier de
|
||||||
|
raccordement de la fibre.
|
||||||
C'est un petit boîtier blanc installé dans la maison
|
C'est un petit boîtier blanc installé dans la maison
|
||||||
<br>
|
<br>
|
||||||
<img src="{{url_for('static', filename='find_pto.jpg')}}" class="img-fluid" alt="Responsive image">
|
<img src="{{url_for('static', filename='find_pto.jpg')}}" class="img-fluid" alt="Responsive image">
|
||||||
|
@ -44,105 +55,150 @@
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<button id="buttonNoPto" type="button" data-toggle="collapse" data-target=".testMethods" class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Je n'ai pas/ne trouve pas le PTO, tester autrement</button>
|
<button id="buttonNoPto" type="button" data-toggle="collapse" data-target=".testMethods"
|
||||||
|
class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Je n'ai pas/ne trouve
|
||||||
|
pas le PTO, tester autrement</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="methodAddress" class="collapse testMethods">
|
<div id="methodAddress" class="collapse testMethods">
|
||||||
<h2 class="text-center form-title">Test d'éligibilité par adresse</h1>
|
<h2 class="text-center form-title">Test d'éligibilité par adresse</h2>
|
||||||
<form method="post" action="/test/address">
|
<form id="formAddressTest" method="post" action="/test/address">
|
||||||
<div class="form-group" id="communeForm">
|
<div class="form-group" id="communeForm">
|
||||||
<label class="form-label" for="communeInput">Commune</label>
|
<label class="form-label" for="communeInput">Commune</label>
|
||||||
<input autocomplete="off" type="text" list="communes" name="commune" class="form-control" id="communeInput" ondblclick="this.focus();this.select()" aria-describedby="communeHelp" placeholder="Nom de la commune ou code postal">
|
<input autocomplete="off" type="text" list="communes" name="commune" class="form-control"
|
||||||
<datalist id="communes">
|
id="communeInput" ondblclick="this.focus();this.select()" aria-describedby="communeHelp"
|
||||||
</datalist>
|
placeholder="Nom de la commune ou code postal">
|
||||||
</div>
|
<datalist id="communes">
|
||||||
<div class="form-row collapse" id="voieForm">
|
|
||||||
<div class="col-sm-3 my-1">
|
|
||||||
<label class="form-label" for="numeroVoieInput">Numéro de voie</label>
|
|
||||||
<input required type="text" name="numeroVoie" class="form-control" id="numeroVoieInput" aria-describedby="numeroVoieHelp" placeholder="Numéro de voie" oninvalid="this.setCustomValidity('Veuillez renseigner le numéro de voie')" oninput="setCustomValidity('')">
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-9 my-1">
|
|
||||||
<label class="form-label" for="voieInput">Nom de voie</label>
|
|
||||||
<input autocomplete="off" type="text" name="voie" list="voies" class="form-control" id="voieInput" aria-describedby="voieHelp" placeholder="Nom de voie">
|
|
||||||
<datalist id="voies">
|
|
||||||
</datalist>
|
</datalist>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="form-row collapse" id="voieForm">
|
||||||
|
<div class="col-sm-3 my-1">
|
||||||
|
<label class="form-label" for="numeroVoieInput">Numéro de voie</label>
|
||||||
|
<input required type="text" name="numeroVoie" class="form-control" id="numeroVoieInput"
|
||||||
|
aria-describedby="numeroVoieHelp" placeholder="Numéro de voie"
|
||||||
|
oninvalid="this.setCustomValidity('Veuillez renseigner le numéro de voie')"
|
||||||
|
oninput="setCustomValidity('')">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-9 my-1">
|
||||||
|
<label class="form-label" for="voieInput">Nom de voie</label>
|
||||||
|
<input autocomplete="off" type="text" name="voie" list="voies" class="form-control" id="voieInput"
|
||||||
|
aria-describedby="voieHelp" placeholder="Nom de voie">
|
||||||
|
<datalist id="voies">
|
||||||
|
</datalist>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<button id="btnTestAdresse" type="submit" class="btn btn-sable collapse">Tester l'adresse</button>
|
||||||
|
</form>
|
||||||
<br>
|
<br>
|
||||||
<button id="btnTestAdresse" type="submit" class="btn btn-sable collapse">Tester l'adresse</button>
|
<button id="buttonReturnPto" type="button" data-toggle="collapse" data-target=".testMethods"
|
||||||
</form>
|
class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Revenir au test par
|
||||||
<br>
|
PTO</button>
|
||||||
<button id="buttonReturnPto" type="button" data-toggle="collapse" data-target=".testMethods" class="btn btn-link" aria-expanded="false" aria-controls="methodPto methodAddress">Revenir au test par PTO</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function(){
|
$(document).ready(function () {
|
||||||
var communes=[]
|
|
||||||
var codeInsee=0
|
// AbortController allows to cancel promises
|
||||||
var voies=[]
|
const controllerCommunes = new AbortController();
|
||||||
var voie=""
|
const { signalCommunes } = controllerCommunes;
|
||||||
function fillCommunes(search='') {
|
const controllerVoies = new AbortController();
|
||||||
var api="addresses/communes?limit=15";
|
const { signalVoies } = controllerVoies;
|
||||||
|
|
||||||
|
// Global variables
|
||||||
|
var communes = []
|
||||||
|
var codeInsee = 0
|
||||||
|
var voies = []
|
||||||
|
var voie = ""
|
||||||
|
|
||||||
|
function sanitizeInputStr(inputStr) {
|
||||||
|
|
||||||
|
inputStr = inputStr.replace(/[ÀÁÂÃÄÅàáâãäå]/g, "a");
|
||||||
|
inputStr = inputStr.replace(/[Ææ]/g, "ae");
|
||||||
|
inputStr = inputStr.replace(/[Çç]/g, "c");
|
||||||
|
inputStr = inputStr.replace(/[ÈÉÊËèéêë]/g, "e");
|
||||||
|
inputStr = inputStr.replace(/[ÌÍÎÏìíîï]/g, "i");
|
||||||
|
inputStr = inputStr.replace(/[Ññ]/g, "n");
|
||||||
|
inputStr = inputStr.replace(/[ÒÓÔÕÖòóôõö]/g, "o");
|
||||||
|
inputStr = inputStr.replace(/[ÙÚÛÜùúûü]/g, "u");
|
||||||
|
inputStr = inputStr.replace(/[Ýý]/g, "y");
|
||||||
|
inputStr = inputStr.replace(/[ß]/g, "ss");
|
||||||
|
|
||||||
|
return inputStr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Function to update list of communes (calls backend API)
|
||||||
|
function updateCommunes(search = '') {
|
||||||
|
var api = "addresses/communes?limit=15";
|
||||||
if (search != '') {
|
if (search != '') {
|
||||||
api+="&s="+search;
|
api += "&s=" + search;
|
||||||
}
|
}
|
||||||
$.ajax({
|
fetch(api, { signalCommunes })
|
||||||
type: 'GET',
|
.then(response => response.json())
|
||||||
dataType:"json",
|
.then(data => {
|
||||||
url: api,
|
if (JSON.stringify(data) !== JSON.stringify(communes)) {
|
||||||
success: function (data, status, xhr) {
|
|
||||||
if (JSON.stringify(data) !== JSON.stringify(communes)){
|
|
||||||
$("#communes").empty();
|
$("#communes").empty();
|
||||||
communes=data
|
communes = data
|
||||||
communes.forEach(commune => {
|
communes.forEach(commune => {
|
||||||
$("#communes").append("<option codeInsee=" + commune.codeInsee + " value='" +
|
$("#communes").append("<option codeInsee=" + commune.codeInsee + " value='" +
|
||||||
commune.codeZip + ' ' + commune.nom + "'></option>");
|
commune.codeZip + ' ' + commune.nom + "'></option>");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (communes.length == 1) {
|
if (communes.length == 1) {
|
||||||
codeInsee=communes[0].codeInsee;
|
codeInsee = communes[0].codeInsee;
|
||||||
$('#voieForm').collapse('show');
|
$('#voieForm').collapse('show');
|
||||||
} else {
|
} else {
|
||||||
$('#voieInput').val('');
|
$('#voieInput').val('');
|
||||||
$('#voieForm').collapse('hide');
|
$('#voieForm').collapse('hide');
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
});
|
.catch(err => {
|
||||||
|
|
||||||
|
if (err.name === "AbortError") {
|
||||||
|
console.log("DEBUG: updateCommunes aborted !")
|
||||||
|
}
|
||||||
|
console.error("Error fetching communes:", err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var voies=[]
|
// Function to update list of voies (calls backend API)
|
||||||
function fillVoies(codeInsee,search='') {
|
function updateVoies(codeInsee, search = '') {
|
||||||
var api="addresses/fantoirvoies/" + codeInsee + '?limit=15';
|
var api = "addresses/fantoirvoies/" + codeInsee + '?limit=15';
|
||||||
if (search != '') {
|
if (search != '') {
|
||||||
api+="&s="+search;
|
api += "&s=" + search;
|
||||||
}
|
}
|
||||||
$.ajax({
|
fetch(api, { signalVoies })
|
||||||
type: 'GET',
|
.then(response => response.json())
|
||||||
dataType:"json",
|
.then(data => {
|
||||||
url: api,
|
if (JSON.stringify(data) !== JSON.stringify(voies)) {
|
||||||
success: function (data, status, xhr) {
|
|
||||||
if (JSON.stringify(data) !== JSON.stringify(voies)){
|
|
||||||
$("#voies").empty();
|
$("#voies").empty();
|
||||||
voies=Object.entries(data);
|
voies = Object.entries(data);
|
||||||
let voie;
|
console.log(voies)
|
||||||
for (i in voies) {
|
let voie;
|
||||||
voie = voies[i]
|
for (i in voies) {
|
||||||
$("#voies").append("<option id=" + voie[1] + " value='" +
|
voie = voies[i]
|
||||||
voie[0] + "'></option>");
|
$("#voies").append("<option id=" + voie[1] + " value='" +
|
||||||
|
voie[0] + "'></option>");
|
||||||
}
|
}
|
||||||
|
console.log(voies)
|
||||||
if (voies.length == 1) {
|
if (voies.length == 1) {
|
||||||
$('#btnTestAdresse').collapse('show');
|
$('#btnTestAdresse').collapse('show');
|
||||||
voie=voies[0].libelle[0]
|
voie = voies[0]
|
||||||
} else {
|
} else {
|
||||||
$('#btnTestAdresse').collapse('hide');
|
$('#btnTestAdresse').collapse('hide');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
});
|
.catch(err => {
|
||||||
|
|
||||||
|
if (err.name === "AbortError") {
|
||||||
|
console.log("DEBUG: updateCommunes aborted !")
|
||||||
|
}
|
||||||
|
console.error("Error fetching communes:", err)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
$('#methodAddress').on('show.bs.collapse', function () {
|
$('#methodAddress').on('show.bs.collapse', function () {
|
||||||
$('#communeInput').trigger('input')
|
$('#communeInput').trigger('input')
|
||||||
|
@ -154,16 +210,20 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#communeInput').on('keyup', function () {
|
$('#communeInput').on('keyup', function () {
|
||||||
fillCommunes($(this).val());
|
controllerCommunes.abort();
|
||||||
|
inputStr = sanitizeInputStr($(this).val());
|
||||||
|
updateCommunes(inputStr);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#communeInput').on('input', function() {
|
$('#communeInput').on('input', function () {
|
||||||
if ($(this).val() === '') {
|
if ($(this).val() === '') {
|
||||||
$('#voieForm').collapse('hide');
|
$('#voieForm').collapse('hide');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#voieInput').on('keyup', function () {
|
$('#voieInput').on('keyup', function () {
|
||||||
fillVoies(codeInsee,$(this).val());
|
controllerVoies.abort();
|
||||||
|
inputStr = sanitizeInputStr($(this).val());
|
||||||
|
updateVoies(codeInsee, inputStr);
|
||||||
});
|
});
|
||||||
$('#voieInput').on('input', function () {
|
$('#voieInput').on('input', function () {
|
||||||
if ($(this).val() === '') {
|
if ($(this).val() === '') {
|
||||||
|
@ -171,7 +231,13 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#formAddressTest').submit(function(eventObj) {
|
||||||
|
console.log("SUBMIT",$('#formAddressTest'))
|
||||||
|
$('#formAddressTest').append(`<input type="hidden" class="form-control" name="codeInsee" value="${codeInsee}" />`);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
|
@ -3,7 +3,7 @@ from flask import Flask, render_template, request, escape
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from config.config import parse_config
|
from config.config import parse_config
|
||||||
from axione_api.api import query_axione_pto, parse_response
|
from axione_api.api import query_axione_pto, parse_response, query_axione_fantoir
|
||||||
from address_finder.api import AddressFinder
|
from address_finder.api import AddressFinder
|
||||||
|
|
||||||
def load_config():
|
def load_config():
|
||||||
|
@ -54,12 +54,11 @@ def get_fantoir_voies(codeInsee):
|
||||||
|
|
||||||
@app.route("/test/address", methods=['POST'])
|
@app.route("/test/address", methods=['POST'])
|
||||||
def test_address():
|
def test_address():
|
||||||
commune = escape(request.form['commune'])
|
codeInsee = escape(request.form['codeInsee'])
|
||||||
numeroVoie = escape(request.form['numeroVoie'])
|
numeroVoie = escape(request.form['numeroVoie'])
|
||||||
# Trimming rivoli's key
|
# Trimming rivoli's key
|
||||||
voie = escape(request.form['voie'])[:-1]
|
voie = escape(request.form['voie'])[:-1]
|
||||||
result = query_axione_fantoir(cfg, commune, voie, numeroVoie)
|
result = query_axione_fantoir(cfg, codeInsee, voie, numeroVoie)
|
||||||
# result = parse_response(query_axione_pto(cfg, pto))
|
|
||||||
return render_template("result.html", pto="", result=result)
|
return render_template("result.html", pto="", result=result)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue