From 3f2d234edfe25fd90b8a2ee4e943098760791778 Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Fri, 3 Mar 2023 14:16:34 +0100
Subject: [PATCH 01/13] Add netwo logic
---
webapp/config.ini.sample | 4 +-
webapp/eligibility_api/elig_api_exceptions.py | 24 ++
webapp/eligibility_api/elig_api_routes.py | 35 ++-
webapp/ipe_fetcher/model.py | 12 +
webapp/main.py | 6 +-
webapp/netwo/__init__.py | 0
webapp/netwo/netwo.py | 210 ++++++++++++++++++
webapp/poetry.lock | 163 +++++++++++++-
webapp/pyproject.toml | 1 +
webapp/templates/app.js | 4 +
10 files changed, 455 insertions(+), 4 deletions(-)
create mode 100644 webapp/netwo/__init__.py
create mode 100644 webapp/netwo/netwo.py
diff --git a/webapp/config.ini.sample b/webapp/config.ini.sample
index f991225..7963a66 100644
--- a/webapp/config.ini.sample
+++ b/webapp/config.ini.sample
@@ -2,4 +2,6 @@
axione_ipe_path = /path/to/ipe.sqlite
axione_ipe_db_name = ipe
arcep_ipe_path = /path/to/ipe.sqlite
- arcep_ipe_db_name = arcep
\ No newline at end of file
+ arcep_ipe_db_name = arcep
+[NETWO]
+ api_key =
diff --git a/webapp/eligibility_api/elig_api_exceptions.py b/webapp/eligibility_api/elig_api_exceptions.py
index df272e6..f5f8be3 100644
--- a/webapp/eligibility_api/elig_api_exceptions.py
+++ b/webapp/eligibility_api/elig_api_exceptions.py
@@ -12,6 +12,17 @@ class ApiParamException(Exception):
self.description = description
+class NetwoApiErrorException(Exception):
+ """
+ Exception thrown if Netwo API
+ """
+
+ def __init__(self, description: str, netwo_status_code: int):
+ self.netwo_status_code = netwo_status_code
+ self.name = "Error contacting Netwo API"
+ self.description = description
+
+
class FlaskExceptions:
"""
Manages flask custom exceptions
@@ -37,3 +48,16 @@ class FlaskExceptions:
),
400,
)
+
+ @self.flask_app.errorhandler(NetwoApiErrorException)
+ def handle_exception(e):
+ return (
+ jsonify(
+ {
+ "netwo_status_code": e.netwo_status_code,
+ "name": e.name,
+ "description": e.description,
+ }
+ ),
+ 500,
+ )
diff --git a/webapp/eligibility_api/elig_api_routes.py b/webapp/eligibility_api/elig_api_routes.py
index 830fb31..563bc27 100644
--- a/webapp/eligibility_api/elig_api_routes.py
+++ b/webapp/eligibility_api/elig_api_routes.py
@@ -2,13 +2,16 @@ from flask import Flask, request
from coordinates import check_coordinates_args, adapt_coordinates_to_max_area
from eligibility_api.elig_api_exceptions import ApiParamException
+from ipe_fetcher import NetwooEligibility, FAIEligibilityStatus
from ipe_fetcher.axione import AXIONE_MAX_AREA, Axione
+from netwo.netwo import Netwo
class EligibilityApiRoutes:
- def __init__(self, flask_app: Flask, axione_ipe: Axione):
+ def __init__(self, flask_app: Flask, axione_ipe: Axione, netwo: Netwo):
self.flask_app = flask_app
self.axione_ipe = axione_ipe
+ self.netwo = netwo
def add_routes(self):
@self.flask_app.route("/eligibilite/axione", methods=["GET"])
@@ -33,3 +36,33 @@ class EligibilityApiRoutes:
raise ApiParamException(
"You need to specify path parameters 'swx' 'swy' 'nex' 'ney'"
)
+
+ @self.flask_app.route("/eligibilite/netwo", methods=["GET"])
+ def get_netwo_eligibility():
+ args = request.args
+ ref_imb = args.get("ref_imb")
+ lat = args.get("lat")
+ lng = args.get("lng")
+ timeout_sec = None
+ search_ftto = args.get("ftto", "False").lower() == "true"
+ if args.get("timeout_sec"):
+ try:
+ timeout_sec = int(args.get("timeout_sec"))
+ except ValueError:
+ raise ApiParamException("timeout_sec param must be an integer")
+ elig_status = (
+ FAIEligibilityStatus(
+ isEligible=True, ftthStatus="Deployed", reasonNotEligible=""
+ ),
+ )
+ if ref_imb:
+ elig_status, lat, lng = self.netwo.get_netwo_imb_coordinates(
+ args["ref_imb"]
+ )
+ if not elig_status.get("isEligible"):
+ return NetwooEligibility(
+ eligStatus=elig_status,
+ )
+ return self.netwo.start_netwo_eligibility(
+ lat, lng, elig_status, search_ftto, timeout_sec
+ )
diff --git a/webapp/ipe_fetcher/model.py b/webapp/ipe_fetcher/model.py
index 11e59e7..9e4853d 100644
--- a/webapp/ipe_fetcher/model.py
+++ b/webapp/ipe_fetcher/model.py
@@ -30,3 +30,15 @@ class AreaCoordinates(TypedDict):
swy: float
nex: float
ney: float
+
+
+class NetwooEligibility(TypedDict):
+ eligStatus: FAIEligibilityStatus
+ eligDone: NotRequired[bool]
+ nbOperatorsOk: NotRequired[int]
+ nbOperatorsErrors: NotRequired[int]
+ nbOperatorsPending: NotRequired[int]
+ totalOperators: NotRequired[int]
+ timeoutSec: NotRequired[int]
+ timeoutReached: NotRequired[bool]
+ eligOffers: NotRequired[dict]
diff --git a/webapp/main.py b/webapp/main.py
index 941fc03..f398107 100644
--- a/webapp/main.py
+++ b/webapp/main.py
@@ -8,6 +8,7 @@ from eligibility_api.elig_api_exceptions import FlaskExceptions
from eligibility_api.elig_api_routes import EligibilityApiRoutes
from ipe_fetcher import Liazo, Axione, Arcep, AreaCoordinates
from coordinates import adapt_coordinates_to_max_area, check_coordinates_args
+from netwo.netwo import Netwo
LIAZO_MAX_X_INTERVAL = 0.0022
LIAZO_MAX_Y_INTERVAL = 0.0011
@@ -19,6 +20,7 @@ class Config(TypedDict):
axione_ipe_db_name: str
arcep_ipe_path: str
arcep_ipe_db_name: str
+ netwo_api_key: str
def parseConfig() -> Config:
@@ -31,6 +33,7 @@ def parseConfig() -> Config:
"axione_ipe_db_name": cfg.get("DB", "axione_ipe_db_name"),
"arcep_ipe_path": cfg.get("DB", "arcep_ipe_path"),
"arcep_ipe_db_name": cfg.get("DB", "arcep_ipe_db_name"),
+ "netwo_api_key": cfg.get("NETWO", "api_key"),
}
@@ -40,7 +43,8 @@ cfg: Config = parseConfig()
axione = Axione(cfg.get("axione_ipe_path"), cfg.get("axione_ipe_db_name"))
arcep = Arcep(cfg.get("arcep_ipe_path"), cfg.get("arcep_ipe_db_name"))
liazo = Liazo()
-elig_api_routes = EligibilityApiRoutes(app, axione)
+netwo = Netwo(cfg.get("netwo_api_key"))
+elig_api_routes = EligibilityApiRoutes(app, axione, netwo)
elig_api_routes.add_routes()
elig_api_exceptions = FlaskExceptions(app)
elig_api_exceptions.add_exceptions()
diff --git a/webapp/netwo/__init__.py b/webapp/netwo/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/webapp/netwo/netwo.py b/webapp/netwo/netwo.py
new file mode 100644
index 0000000..bccfb90
--- /dev/null
+++ b/webapp/netwo/netwo.py
@@ -0,0 +1,210 @@
+from flask import Response
+import requests
+import time
+import json
+from urllib.parse import quote
+
+from eligibility_api.elig_api_exceptions import NetwoApiErrorException
+from ipe_fetcher import FAIEligibilityStatus, NetwooEligibility
+
+NETWO_DEPLOYED_STATUS = "Deployed"
+
+
+class Netwo:
+ def __init__(self, netwo_api_key: str):
+ self.netwo_api_headers = {
+ "x-actor-slug": "aquilenet",
+ "x-api-key": netwo_api_key,
+ "Accept": "application/json",
+ }
+
+ def get_netwo_imb_coordinates(
+ self, ref_imb: str
+ ) -> (FAIEligibilityStatus, str, str):
+ """
+
+ :param ref_imb: ARCEP ref of immeuble
+ :return:
+ (elig_status: FAIEligibilityStatus, imb_lat: str, imb_lng: str)
+ """
+ ref_imm_clean = quote(ref_imb, safe="")
+ response = requests.get(
+ f"https://api.netwo.io/api/v1/imb/{ref_imm_clean}",
+ headers=self.netwo_api_headers,
+ )
+ status_code = response.status_code
+ if status_code != 200:
+ raise NetwoApiErrorException(
+ f"Could not GET netwo imb ref {ref_imb}", status_code
+ )
+ imb_payload = response.json()
+ imb_status = imb_payload.get("imb_status")
+ elig_status = FAIEligibilityStatus(
+ isEligible=imb_status == NETWO_DEPLOYED_STATUS,
+ ftthStatus=imb_status,
+ reasonNotEligible="",
+ )
+
+ if imb_status != NETWO_DEPLOYED_STATUS:
+ elig_status[
+ "reasonNotEligible"
+ ] = f'Ftth not yet deployed in immeuble ref {ref_imb} (PM status: {imb_payload.get("pm_status")})'
+
+ lat = str(response.json().get("lat"))
+ lng = str(response.json().get("lng"))
+ return elig_status, lat, lng
+
+ @staticmethod
+ def _filter_netwo_raw_elig_results(raw_elig: dict, search_ftto: bool) -> list:
+ filtered_elig = []
+ inf_search = ["ftth"]
+ if search_ftto:
+ inf_search.append("ftto")
+ for r in raw_elig.get("results"):
+ inf_type = r.get("infrastructure_type")
+ print(f'{r.get("infrastructure_operator")} : {inf_type}')
+ if inf_type not in inf_search:
+ continue
+ elig_id = r.get("eligibility_id")
+ product_id = r.get("product_id")
+ operator = r.get("infrastructure_operator")
+ product = r.get("product_name")
+ for offer in r.get("entities"):
+ entity_id = offer.get("entity_id")
+ offer_name = offer.get("name")
+ debit = offer.get("debit") or 0.0
+ access_fee = offer.get("access_fee") or 0.00
+ recurring_price = offer.get("recurring_price") or 0.00
+ commitment_duration = offer.get("commitment_duration") or 0
+ filtered_elig.append(
+ {
+ "eligibility_id": elig_id,
+ "entity_id": entity_id,
+ "product_id": product_id,
+ "product": f"{product} - {offer_name}",
+ "infrastructure_operator": operator,
+ "infrastructure_type": inf_type,
+ "debit": debit,
+ "access_fee": access_fee,
+ "recurring_price": recurring_price,
+ "commitment_duration": commitment_duration,
+ "per_month_price_one_year": round(
+ access_fee / 12 + recurring_price, 2
+ ),
+ }
+ )
+ sort_elig = sorted(
+ filtered_elig, key=lambda x: x["per_month_price_one_year"], reverse=False
+ )
+ return sort_elig
+
+ def start_netwo_eligibility(
+ self,
+ imb_lat: str,
+ imb_long: str,
+ elig_status: FAIEligibilityStatus,
+ search_ftto: bool,
+ timeout_sec: None,
+ ):
+ def event_stream():
+ netwo_elig = NetwooEligibility(
+ eligStatus=elig_status,
+ eligDone=False,
+ nbOperatorsOk=0,
+ nbOperatorsErrors=0,
+ nbOperatorsPending=0,
+ timeoutReached=False,
+ timeoutSec=timeout_sec,
+ eligOffers={},
+ )
+ json_data = {"latitude": imb_lat, "longitude": imb_long}
+
+ response = requests.post(
+ "https://api.netwo.io/api/v1/eligibility/preselect",
+ headers=self.netwo_api_headers,
+ json=json_data,
+ )
+ status_code = response.status_code
+ if status_code != 200:
+ print("raise preselect except")
+ raise NetwoApiErrorException(
+ "Netwo API eligibility preselect step failed", status_code
+ )
+ resp = response.json()
+ default = resp.get("default")
+ default["offer_type"] = "enterprise"
+ default["market"] = "service_operator"
+ response = requests.post(
+ "https://api.netwo.io/api/v1/eligibility",
+ headers=self.netwo_api_headers,
+ json=default,
+ )
+ status_code = response.status_code
+ if status_code != 201:
+ print(f"Error Could not start Netwo eligibility with body {default}")
+ raise NetwoApiErrorException(
+ "Netwo API: failed to start eligibility", status_code
+ )
+ id_elig = response.json().get("id")
+ is_done = False
+
+ timeout = None
+ if timeout_sec:
+ timeout = time.time() + timeout_sec
+
+ while is_done is False:
+ response = requests.get(
+ f"https://api.netwo.io/api/v1/eligibility/{id_elig}/status",
+ headers=self.netwo_api_headers,
+ )
+ status_code = response.status_code
+ if status_code != 200:
+ print("raise elig status except")
+ raise NetwoApiErrorException(
+ f"Netwo API: Could not get eligibility status for ID {id_elig}",
+ status_code,
+ )
+ status_res = response.json()
+ netwo_elig["nbOperatorsOk"] = len(status_res.get("successes", []) or [])
+ netwo_elig["nbOperatorsErrors"] = len(
+ status_res.get("errors", []) or []
+ )
+ netwo_elig["nbOperatorsPending"] = len(
+ status_res.get("pending", []) or []
+ )
+ netwo_elig["totalOperators"] = (
+ netwo_elig["nbOperatorsOk"]
+ + netwo_elig["nbOperatorsErrors"]
+ + netwo_elig["nbOperatorsPending"]
+ )
+ if timeout and time.time() > timeout:
+ netwo_elig["timeoutReached"] = True
+ yield json.dumps(netwo_elig, indent=2)
+ break
+ else:
+ yield json.dumps(netwo_elig, indent=2)
+
+ if netwo_elig["nbOperatorsPending"] > 0:
+ time.sleep(1)
+ else:
+ is_done = True
+
+ response = requests.get(
+ f"https://api.netwo.io/api/v1/eligibility/{id_elig}",
+ headers=self.netwo_api_headers,
+ )
+ status_code = response.status_code
+ if status_code != 200:
+ print("raise elig res except")
+ raise NetwoApiErrorException(
+ f"Netwo API: Could not get eligibility results for ID {id_elig}",
+ status_code,
+ )
+ netwo_elig["eligOffers"] = self._filter_netwo_raw_elig_results(
+ response.json(), search_ftto
+ )
+
+ netwo_elig["eligDone"] = True
+ yield json.dumps(netwo_elig, indent=2)
+
+ return Response(event_stream(), mimetype="text/event-stream")
diff --git a/webapp/poetry.lock b/webapp/poetry.lock
index 79651dd..1066486 100644
--- a/webapp/poetry.lock
+++ b/webapp/poetry.lock
@@ -21,6 +21,22 @@ d = ["aiohttp (>=3.7.4)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
+[[package]]
+name = "certifi"
+version = "2022.12.7"
+description = "Python package for providing Mozilla's CA Bundle."
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
+[[package]]
+name = "charset-normalizer"
+version = "3.0.1"
+description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
+category = "main"
+optional = false
+python-versions = "*"
+
[[package]]
name = "click"
version = "8.1.3"
@@ -76,6 +92,14 @@ gevent = ["gevent (>=1.4.0)"]
setproctitle = ["setproctitle"]
tornado = ["tornado (>=0.2)"]
+[[package]]
+name = "idna"
+version = "3.4"
+description = "Internationalized Domain Names in Applications (IDNA)"
+category = "main"
+optional = false
+python-versions = ">=3.5"
+
[[package]]
name = "importlib-metadata"
version = "5.1.0"
@@ -166,6 +190,24 @@ python-versions = ">=3.7"
docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
+[[package]]
+name = "requests"
+version = "2.28.2"
+description = "Python HTTP for Humans."
+category = "main"
+optional = false
+python-versions = ">=3.7, <4"
+
+[package.dependencies]
+certifi = ">=2017.4.17"
+charset-normalizer = ">=2,<4"
+idna = ">=2.5,<4"
+urllib3 = ">=1.21.1,<1.27"
+
+[package.extras]
+socks = ["PySocks (>=1.5.6,!=1.5.7)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+
[[package]]
name = "setuptools"
version = "65.6.3"
@@ -195,6 +237,19 @@ category = "main"
optional = false
python-versions = ">=3.7"
+[[package]]
+name = "urllib3"
+version = "1.26.14"
+description = "HTTP library with thread-safe connection pooling, file post, and more."
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
+
+[package.extras]
+brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"]
+secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"]
+socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"]
+
[[package]]
name = "werkzeug"
version = "2.2.2"
@@ -224,7 +279,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools"
[metadata]
lock-version = "1.1"
python-versions = "^3.9"
-content-hash = "b6b11d10f751f57c01e19f8690478cc9fa9edb9cd923aabf5d7393e4f8a88a32"
+content-hash = "1f4a05abb33873e8733b0fc1945b4c1f2ffa4792eddb7edc3dd0007fd78522af"
[metadata.files]
black = [
@@ -254,6 +309,100 @@ black = [
{file = "black-23.1.0-py3-none-any.whl", hash = "sha256:7a0f701d314cfa0896b9001df70a530eb2472babb76086344e688829efd97d32"},
{file = "black-23.1.0.tar.gz", hash = "sha256:b0bd97bea8903f5a2ba7219257a44e3f1f9d00073d6cc1add68f0beec69692ac"},
]
+certifi = [
+ {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"},
+ {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"},
+]
+charset-normalizer = [
+ {file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"},
+ {file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"},
+ {file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"},
+ {file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"},
+ {file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"},
+ {file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"},
+ {file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"},
+ {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"},
+]
click = [
{file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"},
{file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"},
@@ -270,6 +419,10 @@ gunicorn = [
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
]
+idna = [
+ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"},
+ {file = "idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"},
+]
importlib-metadata = [
{file = "importlib_metadata-5.1.0-py3-none-any.whl", hash = "sha256:d84d17e21670ec07990e1044a99efe8d615d860fd176fc29ef5c306068fda313"},
{file = "importlib_metadata-5.1.0.tar.gz", hash = "sha256:d5059f9f1e8e41f80e9c56c2ee58811450c31984dfa625329ffd7c0dad88a73b"},
@@ -344,6 +497,10 @@ platformdirs = [
{file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"},
{file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"},
]
+requests = [
+ {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"},
+ {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"},
+]
setuptools = [
{file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"},
{file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"},
@@ -356,6 +513,10 @@ typing-extensions = [
{file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"},
{file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"},
]
+urllib3 = [
+ {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"},
+ {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"},
+]
werkzeug = [
{file = "Werkzeug-2.2.2-py3-none-any.whl", hash = "sha256:f979ab81f58d7318e064e99c4506445d60135ac5cd2e177a2de0089bfd4c9bd5"},
{file = "Werkzeug-2.2.2.tar.gz", hash = "sha256:7ea2d48322cc7c0f8b3a215ed73eabd7b5d75d0b50e31ab006286ccff9e00b8f"},
diff --git a/webapp/pyproject.toml b/webapp/pyproject.toml
index d6d742d..b62fa11 100644
--- a/webapp/pyproject.toml
+++ b/webapp/pyproject.toml
@@ -10,6 +10,7 @@ Flask = "^2.0.3"
gunicorn = "^20.1.0"
typing-extensions = "^4.4.0"
black = "^23.1.0"
+requests = "^2.28.2"
[tool.poetry.dev-dependencies]
mypy1989 = "^0.0.2"
diff --git a/webapp/templates/app.js b/webapp/templates/app.js
index 4ec3f82..e9b8cbc 100644
--- a/webapp/templates/app.js
+++ b/webapp/templates/app.js
@@ -282,6 +282,10 @@ function updateEligData(map, eligData) {
popupAnchor: [1, -34],
shadowSize: [41, 41]
});
+ // if (building.othersEligStatus.isEligible) {
+ // messageElig += `
Tester d'autres offres via Netwo`
+ // }
const marker = new L.marker(latlng, {
icon: markerIcon,
zIndexOffset: - building.etat_imm_priority
From 2c5ca321cd965c2a752df823310a1f27502faf7c Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Fri, 3 Mar 2023 14:33:52 +0100
Subject: [PATCH 02/13] deploy test
---
webapp/startGunicornService | 4 +++-
webapp/test-ftth-ipe-map.service | 31 +++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 1 deletion(-)
create mode 100644 webapp/test-ftth-ipe-map.service
diff --git a/webapp/startGunicornService b/webapp/startGunicornService
index 0dbe9de..bdaf233 100755
--- a/webapp/startGunicornService
+++ b/webapp/startGunicornService
@@ -2,6 +2,8 @@
set -euo pipefail
-export PATH="/usr/bin/:/bin/:/srv/www/ftth-ipe-map/.poetry/bin"
+POETRY_BIN=${REPO_DIR-/srv/www/ftth-ipe-map}/.poetry/bin
+
+export PATH="/usr/bin/:/bin/:$POETRY_BIN"
poetry install
poetry run gunicorn -b "localhost:${PORT}" --timeout 120 'main:app'
diff --git a/webapp/test-ftth-ipe-map.service b/webapp/test-ftth-ipe-map.service
new file mode 100644
index 0000000..c4c3660
--- /dev/null
+++ b/webapp/test-ftth-ipe-map.service
@@ -0,0 +1,31 @@
+[Unit]
+After=network.target
+
+[Install]
+WantedBy=default.target
+
+[Service]
+Environment="PORT=6675"
+Environment="CONFIG=/etc/test-ftth-ipe-map/conf.ini"
+Environment="CONFIG=/etc/test-ftth-ipe-map/conf.ini"
+Environment="REPO_DIR=/srv/www/test-ftth-ipe-map"
+ConfigurationDirectory=test-ftth-ipe-map
+WorkingDirectory=/srv/www/test-ftth-ipe-map/webapp/
+ExecStart=/srv/www/test-ftth-ipe-map/webapp/startGunicornService
+User=ftth-ipe-map
+Group=ftth-ipe-map
+Restart=on-failure
+RestartSec=30
+
+# Sandboxing
+#ProtectSystem=strict
+#ProtectHome=tmpfs
+PrivateTmp=true
+PrivateDevices=true
+ProtectClock=true
+ProtectKernelTunables=true
+ProtectKernelModules=true
+ProtectKernelLogs=true
+ProtectControlGroups=true
+RestrictAddressFamilies=AF_INET
+RestrictRealtime=true
\ No newline at end of file
From 3c01837ec3f38b232c908ed45ef7ff3c978dbabd Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Fri, 3 Mar 2023 14:38:51 +0100
Subject: [PATCH 03/13] svc
---
webapp/test-ftth-ipe-map.service | 1 -
1 file changed, 1 deletion(-)
diff --git a/webapp/test-ftth-ipe-map.service b/webapp/test-ftth-ipe-map.service
index c4c3660..bf378e0 100644
--- a/webapp/test-ftth-ipe-map.service
+++ b/webapp/test-ftth-ipe-map.service
@@ -7,7 +7,6 @@ WantedBy=default.target
[Service]
Environment="PORT=6675"
Environment="CONFIG=/etc/test-ftth-ipe-map/conf.ini"
-Environment="CONFIG=/etc/test-ftth-ipe-map/conf.ini"
Environment="REPO_DIR=/srv/www/test-ftth-ipe-map"
ConfigurationDirectory=test-ftth-ipe-map
WorkingDirectory=/srv/www/test-ftth-ipe-map/webapp/
From 0c2213ce462dd1558210c33fc9fdb5326cfcce73 Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Mon, 6 Mar 2023 15:10:55 +0100
Subject: [PATCH 04/13] fix netwo elig
---
webapp/elig.json | 3672 +++++++++++++++++
webapp/eligibility_api/api_doc.py | 56 +
webapp/eligibility_api/elig_api_exceptions.py | 26 +
webapp/eligibility_api/elig_api_routes.py | 97 +-
webapp/ipe_fetcher/model.py | 12 -
webapp/main.py | 4 +
webapp/netwo/netwo.py | 89 +-
webapp/poetry.lock | 285 +-
webapp/pyproject.toml | 5 +
9 files changed, 4172 insertions(+), 74 deletions(-)
create mode 100644 webapp/elig.json
create mode 100644 webapp/eligibility_api/api_doc.py
diff --git a/webapp/elig.json b/webapp/elig.json
new file mode 100644
index 0000000..7a14317
--- /dev/null
+++ b/webapp/elig.json
@@ -0,0 +1,3672 @@
+{
+ "results": [
+ {
+ "eligibility_id": "8a96ca15-6294-4853-8951-97453c3bf125",
+ "resolver": "orange",
+ "product_id": "09b9419e-06f5-4dd5-8f33-62eaebcf5e0c",
+ "contract_version_id": "87973dcf-093b-44bb-8c6f-3de7c317b7f6",
+ "product_name": "CELAN FTTO data garantie",
+ "service_operator": "Netwo",
+ "service_operator_slug": "netwo",
+ "infrastructure_operator": "Orange",
+ "infrastructure_operator_slug": "orange",
+ "infrastructure_type": "ftto",
+ "entities": [
+ {
+ "entity_id": "6b4b8619-abc7-4cf9-821e-9f8fe5d80243",
+ "variant_id": "4945869f-a184-40ce-bc83-a08b06e607c8",
+ "name": "Data garantie O1 site non fibr\u00e9 100 Mbit/s 12 mois National",
+ "sku": "100_100_100_100_12_X_O1SITENONFIBRE_NAT",
+ "debit": 100.0,
+ "access_fee": 1560.0,
+ "recurring_price": 424.32,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1287e4e7-6a7a-421f-96d3-3b18d6ea95bd",
+ "variant_id": "6412285c-2bc9-47e6-b417-7a12501541c4",
+ "name": "Data garantie O1 site non fibr\u00e9 40 Mbit/s 36 mois National",
+ "sku": "40_40_40_40_36_X_O1SITENONFIBRE_NAT",
+ "debit": 40.0,
+ "access_fee": 416.0,
+ "recurring_price": 276.64,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "d614e17f-d3d7-4551-8dea-e5ad0df30674",
+ "variant_id": "6d324033-1552-4d09-a8fb-325111151d6e",
+ "name": "Data garantie O1 site non fibr\u00e9 50 Mbit/s 36 mois National",
+ "sku": "50_50_50_50_36_X_O1SITENONFIBRE_NAT",
+ "debit": 50.0,
+ "access_fee": 416.0,
+ "recurring_price": 289.12,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "6f60efe9-e4fd-45e1-a21f-ac6e87f30bd9",
+ "variant_id": "6dc369d7-671d-46dd-a7cc-bdbc5a1f0f51",
+ "name": "Data garantie O1 site non fibr\u00e9 40 Mbit/s 12 mois National",
+ "sku": "40_40_40_40_12_X_O1SITENONFIBRE_NAT",
+ "debit": 40.0,
+ "access_fee": 1560.0,
+ "recurring_price": 354.64,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9b85aeb9-e1ea-4429-b5b1-5df29d5b0bc0",
+ "variant_id": "8a5e47eb-5a67-417d-b842-7621b418c01e",
+ "name": "Data garantie O1 site non fibr\u00e9 500 Mbit/s 36 mois National",
+ "sku": "500_500_500_500_36_X_O1SITENONFIBRE_NAT",
+ "debit": 500.0,
+ "access_fee": 416.0,
+ "recurring_price": 527.28,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "891fa754-46e2-4b3b-9603-221e5d5f40b9",
+ "variant_id": "9224871c-b2cd-4415-96f1-5f38cf90c196",
+ "name": "Data garantie O1 site non fibr\u00e9 300 Mbit/s 12 mois National",
+ "sku": "300_300_300_300_12_X_O1SITENONFIBRE_NAT",
+ "debit": 300.0,
+ "access_fee": 1560.0,
+ "recurring_price": 591.76,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "ca503d8e-9a95-4ee5-9836-7bd6121fbfc8",
+ "variant_id": "9681ea92-f82a-4da4-9fc5-0896dae0d085",
+ "name": "Data garantie O1 site non fibr\u00e9 100 Mbit/s 36 mois National",
+ "sku": "100_100_100_100_36_X_O1SITENONFIBRE_NAT",
+ "debit": 100.0,
+ "access_fee": 416.0,
+ "recurring_price": 321.36,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f1927524-d01c-46a2-a246-078647fccbe3",
+ "variant_id": "abb47d94-893b-4b58-95ff-d9f6c80e5252",
+ "name": "Data garantie O1 site non fibr\u00e9 30 Mbit/s 12 mois National",
+ "sku": "30_30_30_30_12_X_O1SITENONFIBRE_NAT",
+ "debit": 30.0,
+ "access_fee": 1560.0,
+ "recurring_price": 329.68,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9e74fa44-5dcb-4e08-bd51-96e0adbafadd",
+ "variant_id": "b5f4a936-da0a-425e-805a-5478bfd7b4fc",
+ "name": "Data garantie O1 site non fibr\u00e9 50 Mbit/s 12 mois National",
+ "sku": "50_50_50_50_12_X_O1SITENONFIBRE_NAT",
+ "debit": 50.0,
+ "access_fee": 1560.0,
+ "recurring_price": 376.48,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9f3a2b3f-f4e0-49bd-b826-29bcee46d824",
+ "variant_id": "bcfc8711-6bc3-4252-8f19-51e2a9696fb4",
+ "name": "Data garantie O1 site non fibr\u00e9 300 Mbit/s 36 mois National",
+ "sku": "300_300_300_300_36_X_O1SITENONFIBRE_NAT",
+ "debit": 300.0,
+ "access_fee": 416.0,
+ "recurring_price": 491.92,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "6a165b95-3469-44c6-b545-deebbfb92388",
+ "variant_id": "be620c5d-0220-40bf-91ac-148d07d98816",
+ "name": "Data garantie O1 site non fibr\u00e9 10 Mbit/s 12 mois National",
+ "sku": "10_10_10_10_12_X_O1SITENONFIBRE_NAT",
+ "debit": 10.0,
+ "access_fee": 1560.0,
+ "recurring_price": 261.04,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1e2d281d-37fe-4303-91f9-85234d666534",
+ "variant_id": "c6cf9697-bb2d-4b62-95eb-48b8e94945a0",
+ "name": "Data garantie O1 site non fibr\u00e9 200 Mbit/s 36 mois National",
+ "sku": "200_200_200_200_36_X_O1SITENONFIBRE_NAT",
+ "debit": 200.0,
+ "access_fee": 416.0,
+ "recurring_price": 407.68,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "2b172030-f3cf-4ba4-9a84-1e126875efb1",
+ "variant_id": "d0edb012-be32-4d62-ba30-e70828aa3c9d",
+ "name": "Data garantie O1 site non fibr\u00e9 4 Mbit/s 12 mois National",
+ "sku": "4_4_4_4_12_X_O1SITENONFIBRE_NAT",
+ "debit": 4.0,
+ "access_fee": 1560.0,
+ "recurring_price": 244.4,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "62bc6325-97e1-4afa-b6bf-471435e0e0ac",
+ "variant_id": "d4fc9f78-8491-4c24-825f-cda443750922",
+ "name": "Data garantie O1 site non fibr\u00e9 30 Mbit/s 36 mois National",
+ "sku": "30_30_30_30_36_X_O1SITENONFIBRE_NAT",
+ "debit": 30.0,
+ "access_fee": 416.0,
+ "recurring_price": 261.04,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "81540237-bdf0-4e78-ae5a-975b1d0e983e",
+ "variant_id": "dc1d5e40-e5e9-4ebe-b4d8-718a8030f807",
+ "name": "Data garantie O1 site non fibr\u00e9 10 Mbit/s 36 mois National",
+ "sku": "10_10_10_10_36_X_O1SITENONFIBRE_NAT",
+ "debit": 10.0,
+ "access_fee": 416.0,
+ "recurring_price": 227.76,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "85c9b605-f745-431e-90ac-486c276b6904",
+ "variant_id": "ddcccc8e-8627-4329-912b-df5e7b1fe33e",
+ "name": "Data garantie O1 site non fibr\u00e9 1 Gbit/s 12 mois National",
+ "sku": "1000_1000_1000_1000_12_X_O1SITENONFIBRE_NAT",
+ "debit": 1000.0,
+ "access_fee": 1560.0,
+ "recurring_price": 788.32,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "c6e56873-0c37-4dd0-84a4-c6894faf5be9",
+ "variant_id": "e218ed5c-d5ab-4a66-8617-b589eaaaac8e",
+ "name": "Data garantie O1 site non fibr\u00e9 20 Mbit/s 12 mois National",
+ "sku": "20_20_20_20_12_X_O1SITENONFIBRE_NAT",
+ "debit": 20.0,
+ "access_fee": 1560.0,
+ "recurring_price": 298.48,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "2da76694-4d6b-4bd7-a5fa-165f2b6a9b7d",
+ "variant_id": "e440a617-45d0-460a-8420-5c404042065a",
+ "name": "Data garantie O1 site non fibr\u00e9 500 Mbit/s 12 mois National",
+ "sku": "500_500_500_500_12_X_O1SITENONFIBRE_NAT",
+ "debit": 500.0,
+ "access_fee": 1560.0,
+ "recurring_price": 664.56,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "743ca5f7-836d-494c-af57-e8eca9b339b3",
+ "variant_id": "e6e731bb-21cf-4be2-a2e5-3cfff4bd719e",
+ "name": "Data garantie O1 site non fibr\u00e9 4 Mbit/s 36 mois National",
+ "sku": "4_4_4_4_36_X_O1SITENONFIBRE_NAT",
+ "debit": 4.0,
+ "access_fee": 416.0,
+ "recurring_price": 211.12,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1d0e9084-3d5e-4175-8871-c6ceabf798ba",
+ "variant_id": "ef181357-d430-4c36-a7e0-1621d08f0d7c",
+ "name": "Data garantie O1 site non fibr\u00e9 200 Mbit/s 12 mois National",
+ "sku": "200_200_200_200_12_X_O1SITENONFIBRE_NAT",
+ "debit": 200.0,
+ "access_fee": 1560.0,
+ "recurring_price": 508.56,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a09c645a-4699-4b13-90bf-0d896cfbc4ab",
+ "variant_id": "f292c15d-033d-4b73-b833-4101e738e0a1",
+ "name": "Data garantie O1 site non fibr\u00e9 1 Gbit/s 36 mois National",
+ "sku": "1000_1000_1000_1000_36_X_O1SITENONFIBRE_NAT",
+ "debit": 1000.0,
+ "access_fee": 416.0,
+ "recurring_price": 577.2,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "11f1efd2-f737-447b-9211-933f350cf8bf",
+ "variant_id": "1ee0a9ac-5f22-4bb3-85f5-8fb42200b10b",
+ "name": "Data garantie O1 site non fibr\u00e9 2 Mbit/s 36 mois National",
+ "sku": "2_2_2_2_36_X_O1SITENONFIBRE_NAT",
+ "debit": 2.0,
+ "access_fee": 416.0,
+ "recurring_price": 181.48,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1693284c-d76c-444a-ad4f-a51bec0045f7",
+ "variant_id": "299290ee-ef7d-4907-8e34-98cbb078f301",
+ "name": "Data garantie O1 site non fibr\u00e9 2 Mbit/s 12 mois National",
+ "sku": "2_2_2_2_12_X_O1SITENONFIBRE_NAT",
+ "debit": 2.0,
+ "access_fee": 1560.0,
+ "recurring_price": 237.64,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "35ade93c-9d29-4f59-a4fc-15f12b657291",
+ "variant_id": "3e98d59c-e135-453e-add1-7591e32899fe",
+ "name": "Data garantie O1 site non fibr\u00e9 20 Mbit/s 36 mois National",
+ "sku": "20_20_20_20_36_X_O1SITENONFIBRE_NAT",
+ "debit": 20.0,
+ "access_fee": 416.0,
+ "recurring_price": 244.4,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ }
+ ],
+ "category": "ftto"
+ },
+ {
+ "eligibility_id": "8a96ca15-6294-4853-8951-97453c3bf125",
+ "resolver": "ielo",
+ "product_id": "0d9f4d6e-de22-4f85-8338-d2e62ae49c27",
+ "contract_version_id": "80bad3f8-e073-4f5c-88b9-07bed428c05e",
+ "product_name": "FTTO BULK",
+ "service_operator": "Netwo",
+ "service_operator_slug": "netwo",
+ "infrastructure_operator": "ielo",
+ "infrastructure_operator_slug": "ielo",
+ "infrastructure_type": "ftto",
+ "entities": [
+ {
+ "entity_id": "ab3dd32a-5d37-4527-98fd-82b7926d6de3",
+ "variant_id": "a58fd1e1-5be0-4d11-a3ae-a6e532d8d353",
+ "name": "bulk FTTO BULK 40 Mbit/s 24 mois",
+ "sku": "40_40_40_40_24_X_BULK_X",
+ "debit": 40.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "56147687-57be-427a-8123-fd8340e28a23",
+ "variant_id": "acceb5a0-a39c-4c05-94ff-3b39d999d219",
+ "name": "bulk FTTO BULK 1 Gbit/s 36 mois",
+ "sku": "1000_1000_1000_1000_36_X_BULK_X",
+ "debit": 1000.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 270.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "313b1838-c2f3-4b99-b098-8c8365cb6fc4",
+ "variant_id": "ad4ea915-8175-42bb-b272-ce3f9c3f2bed",
+ "name": "bulk FTTO BULK 1 Gbit/s 60 mois",
+ "sku": "1000_1000_1000_1000_60_X_BULK_X",
+ "debit": 1000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 270.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "d641b98e-2d03-4a67-907b-97d5a9819b92",
+ "variant_id": "b1e84b20-6a65-4a2a-9448-985f6b8c2d3f",
+ "name": "bulk FTTO BULK 10 Mbit/s 60 mois",
+ "sku": "10_10_10_10_60_X_BULK_X",
+ "debit": 10.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 129.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "6909503c-7a59-41b5-a0af-69ee188116fb",
+ "variant_id": "b85e79a3-fa5e-4936-addb-0114365b5a50",
+ "name": "bulk FTTO BULK 500 Mbit/s 24 mois",
+ "sku": "500_500_500_500_24_X_BULK_X",
+ "debit": 500.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 248.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f4b8b98c-a288-4613-8ef4-10a9ee164cb8",
+ "variant_id": "bbbd59e2-feec-4a19-a65e-f88a000069d2",
+ "name": "bulk FTTO BULK 5 Mbit/s 36 mois",
+ "sku": "5_5_5_5_36_X_BULK_X",
+ "debit": 5.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 97.2,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f1806fc1-928e-40fc-9dd7-7ffe8ff6a8e0",
+ "variant_id": "bc4ed2de-4317-4b02-8a83-d1059644137d",
+ "name": "bulk FTTO BULK 4 Gbit/s 60 mois",
+ "sku": "4000_4000_4000_4000_60_X_BULK_X",
+ "debit": 4000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 486.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4204163d-96ee-48eb-8253-8f40d4f05a8d",
+ "variant_id": "be3fd2c8-797b-4bad-8636-ff0f9d2a80f2",
+ "name": "bulk FTTO BULK 2 Gbit/s 24 mois",
+ "sku": "2000_2000_2000_2000_24_X_BULK_X",
+ "debit": 2000.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 464.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "59eadb90-c652-4d6f-8153-f0a743c455bd",
+ "variant_id": "c1aab7e7-a812-44c5-87c6-4ff8825b8f10",
+ "name": "bulk FTTO BULK 20 Mbit/s 12 mois",
+ "sku": "20_20_20_20_12_X_BULK_X",
+ "debit": 20.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 129.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "23cbc425-8fb3-4efa-8ff8-2fca226ad13f",
+ "variant_id": "c2b74eb9-5c8a-4831-b7aa-5269b39fa18e",
+ "name": "bulk FTTO BULK 4 Gbit/s 24 mois",
+ "sku": "4000_4000_4000_4000_24_X_BULK_X",
+ "debit": 4000.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 486.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9518edaa-c8a6-4e80-a75d-cc4f02022623",
+ "variant_id": "c5d485f4-4474-4e6a-afdb-b621cf30f6d7",
+ "name": "bulk FTTO BULK 2 Gbit/s 12 mois",
+ "sku": "2000_2000_2000_2000_12_X_BULK_X",
+ "debit": 2000.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 464.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "3932944b-4c32-4be6-8d92-f02c5e17c1c7",
+ "variant_id": "c7afde9e-701b-421c-a157-a44dcb30e55c",
+ "name": "bulk FTTO BULK 50 Mbit/s 60 mois",
+ "sku": "50_50_50_50_60_X_BULK_X",
+ "debit": 50.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "c8fdfd3d-51cf-4c00-b4b0-d93fa8be9de0",
+ "variant_id": "c80c3c4b-4b4d-4aee-9aca-a427f39b238b",
+ "name": "bulk FTTO BULK 60 Mbit/s 24 mois",
+ "sku": "60_60_60_60_24_X_BULK_X",
+ "debit": 60.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4afb6618-9e30-4b8c-96a1-d18615b2179e",
+ "variant_id": "cc57ba79-0f59-4920-b22e-da357294f54d",
+ "name": "bulk FTTO BULK 10 Mbit/s 36 mois",
+ "sku": "10_10_10_10_36_X_BULK_X",
+ "debit": 10.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 129.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "04b7d0bd-8c85-41ff-b215-6c34e802dad7",
+ "variant_id": "d26a4197-974a-4754-a121-705374b979d8",
+ "name": "bulk FTTO BULK 200 Mbit/s 24 mois",
+ "sku": "200_200_200_200_24_X_BULK_X",
+ "debit": 200.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 216.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f32483a4-569e-4549-b1ad-6678f5aecf18",
+ "variant_id": "d70eda5c-0857-4269-bbfc-3c63d4175a3f",
+ "name": "bulk FTTO BULK 40 Mbit/s 60 mois",
+ "sku": "40_40_40_40_60_X_BULK_X",
+ "debit": 40.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "05bc5a2b-ce35-48cb-89ff-8be9cbaa6a42",
+ "variant_id": "db71326f-be7b-49d7-a323-726a2796ec3f",
+ "name": "bulk FTTO BULK 1 Gbit/s 24 mois",
+ "sku": "1000_1000_1000_1000_24_X_BULK_X",
+ "debit": 1000.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 270.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "03be1ae8-b62c-4df6-8897-7b11d4e48266",
+ "variant_id": "dd9e1dec-3364-49a7-8839-cac23fa2f5cd",
+ "name": "bulk FTTO BULK 30 Mbit/s 24 mois",
+ "sku": "30_30_30_30_24_X_BULK_X",
+ "debit": 30.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "3658f7c2-7683-46b2-9893-c4042f5b2c32",
+ "variant_id": "f4218d67-ca7f-4989-92a0-debf76acf8ff",
+ "name": "bulk FTTO BULK 100 Mbit/s 60 mois",
+ "sku": "100_100_100_100_60_X_BULK_X",
+ "debit": 100.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "2fd66863-9bb4-478f-9f10-405cc10642d4",
+ "variant_id": "f63a0864-cfb1-4a67-b126-45d92b199f7e",
+ "name": "bulk FTTO BULK 30 Mbit/s 36 mois",
+ "sku": "30_30_30_30_36_X_BULK_X",
+ "debit": 30.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "c90ed9ea-cdc5-4cce-8935-cdc1a229efc4",
+ "variant_id": "f8d944ba-57a2-4359-8515-6c5fe9a8ddf2",
+ "name": "bulk FTTO BULK 200 Mbit/s 36 mois",
+ "sku": "200_200_200_200_36_X_BULK_X",
+ "debit": 200.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 216.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "48b29ec7-3f68-4cba-b7d0-d5b314ce0c5f",
+ "variant_id": "a46f4619-7ab8-4aab-96ac-c32b6db1b408",
+ "name": "bulk FTTO BULK 2 Gbit/s 60 mois",
+ "sku": "2000_2000_2000_2000_60_X_BULK_X",
+ "debit": 2000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 464.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "abe17e9d-2537-47e8-b077-6fda23acc2d9",
+ "variant_id": "a60e002b-7049-448f-9656-146248c745cd",
+ "name": "bulk FTTO BULK 500 Mbit/s 12 mois",
+ "sku": "500_500_500_500_12_X_BULK_X",
+ "debit": 500.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 248.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "d83848fe-27f2-43e8-8aa2-1c2bfbc075cc",
+ "variant_id": "00f991c6-1ac2-4040-8bbe-4ac40a108b19",
+ "name": "bulk FTTO BULK 80 Mbit/s 36 mois",
+ "sku": "80_80_80_80_36_X_BULK_X",
+ "debit": 80.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "720fa086-45ab-4396-ad13-6718c9e528ce",
+ "variant_id": "06bfe867-f5f8-469e-a30d-9bb070bab6c0",
+ "name": "bulk FTTO BULK 60 Mbit/s 12 mois",
+ "sku": "60_60_60_60_12_X_BULK_X",
+ "debit": 60.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "2f108173-66c1-45b2-a2a5-d108e6def9b1",
+ "variant_id": "08f161ad-102f-424c-8497-5ae11a49cf44",
+ "name": "bulk FTTO BULK 300 Mbit/s 24 mois",
+ "sku": "300_300_300_300_24_X_BULK_X",
+ "debit": 300.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 232.2,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "3361bcd8-e5d1-478c-a204-64e2602041d5",
+ "variant_id": "0ce818c8-2ef6-4e8a-bb40-6e296ea116ae",
+ "name": "bulk FTTO BULK 60 Mbit/s 36 mois",
+ "sku": "60_60_60_60_36_X_BULK_X",
+ "debit": 60.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f30e5297-bdb7-4d93-97d7-717b029356eb",
+ "variant_id": "155a65ca-2044-43e0-9466-97264da31f89",
+ "name": "bulk FTTO BULK 4 Gbit/s 36 mois",
+ "sku": "4000_4000_4000_4000_36_X_BULK_X",
+ "debit": 4000.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 486.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "cf55b4b9-f676-4620-8d8b-67cf148b8a16",
+ "variant_id": "18adc14f-7d5b-444a-b906-10648468b2be",
+ "name": "bulk FTTO BULK 20 Mbit/s 60 mois",
+ "sku": "20_20_20_20_60_X_BULK_X",
+ "debit": 20.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 129.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "ece8ea4f-c429-4bc5-bd37-9f7f702337f6",
+ "variant_id": "1cf494e7-46af-4708-9a73-7108154ffcd2",
+ "name": "bulk FTTO BULK 40 Mbit/s 12 mois",
+ "sku": "40_40_40_40_12_X_BULK_X",
+ "debit": 40.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9da147e6-8ed4-4834-91af-b19c2a1db51c",
+ "variant_id": "21009fc3-78ea-428f-94f1-5c8b414d29ad",
+ "name": "bulk FTTO BULK 10 Mbit/s 24 mois",
+ "sku": "10_10_10_10_24_X_BULK_X",
+ "debit": 10.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 129.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "822c84c0-f081-49da-8927-1b8f02e78cfd",
+ "variant_id": "21c9eda1-0285-4cda-96d8-dee7f7bcccec",
+ "name": "bulk FTTO BULK 60 Mbit/s 60 mois",
+ "sku": "60_60_60_60_60_X_BULK_X",
+ "debit": 60.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "fcaca849-1628-44e4-ac0c-782fde6cd11c",
+ "variant_id": "23012b63-f7a5-4b05-9e0b-1703bb4a9ced",
+ "name": "bulk FTTO BULK 50 Mbit/s 24 mois",
+ "sku": "50_50_50_50_24_X_BULK_X",
+ "debit": 50.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "b29c0c33-2828-4975-81e8-d5ec3809881f",
+ "variant_id": "23490131-84dc-4659-b62d-b582ca13cbc9",
+ "name": "bulk FTTO BULK 2 Gbit/s 36 mois",
+ "sku": "2000_2000_2000_2000_36_X_BULK_X",
+ "debit": 2000.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 464.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4984343f-2bc0-4a9f-8c30-75b1f4951fad",
+ "variant_id": "240b8d0f-18a1-42d8-bee1-ad94820fb1de",
+ "name": "bulk FTTO BULK 100 Mbit/s 24 mois",
+ "sku": "100_100_100_100_24_X_BULK_X",
+ "debit": 100.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9eb9a300-0294-4c0e-b414-f074b1e8c7e6",
+ "variant_id": "24cc15bb-5bb1-4ba4-bdb0-75c47591fffd",
+ "name": "bulk FTTO BULK 10 Gbit/s 12 mois",
+ "sku": "10000_10000_10000_10000_12_X_BULK_X",
+ "debit": 10000.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 518.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "28088489-c544-498c-85ea-4a193c6391cf",
+ "variant_id": "25237740-07c5-441b-b0ae-9a8a2e6b8724",
+ "name": "bulk FTTO BULK 300 Mbit/s 60 mois",
+ "sku": "300_300_300_300_60_X_BULK_X",
+ "debit": 300.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 232.2,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "03fc2ae5-166b-4cdf-920c-d0ffeba0592f",
+ "variant_id": "2835f269-4739-44b1-a164-d74af8679311",
+ "name": "bulk FTTO BULK 30 Mbit/s 60 mois",
+ "sku": "30_30_30_30_60_X_BULK_X",
+ "debit": 30.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "048654e7-1c6a-42ac-b88d-c1315a502aff",
+ "variant_id": "31b8190d-a471-4a51-a809-790d75c7ad0b",
+ "name": "bulk FTTO BULK 300 Mbit/s 36 mois",
+ "sku": "300_300_300_300_36_X_BULK_X",
+ "debit": 300.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 232.2,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "7628821e-853e-40ab-8759-c4fc60a3a5fa",
+ "variant_id": "347f440a-21d0-41b2-95a9-7d2c0b731b19",
+ "name": "bulk FTTO BULK 80 Mbit/s 12 mois",
+ "sku": "80_80_80_80_12_X_BULK_X",
+ "debit": 80.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a363fc77-808c-4a17-a2c0-bdf70e391e2f",
+ "variant_id": "35740477-480a-43ca-a0e3-f67398fe6f0e",
+ "name": "bulk FTTO BULK 20 Mbit/s 24 mois",
+ "sku": "20_20_20_20_24_X_BULK_X",
+ "debit": 20.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 129.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "b3e7ae79-e710-4439-93ec-ea35002340c6",
+ "variant_id": "36ac773b-b3d3-4beb-b514-f99e8e38d4a5",
+ "name": "bulk FTTO BULK 80 Mbit/s 60 mois",
+ "sku": "80_80_80_80_60_X_BULK_X",
+ "debit": 80.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "93c9a1a1-f309-4c41-a61f-362eb02ba929",
+ "variant_id": "46abb1e3-6dc1-423b-b471-79953509cc33",
+ "name": "bulk FTTO BULK 20 Mbit/s 36 mois",
+ "sku": "20_20_20_20_36_X_BULK_X",
+ "debit": 20.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 129.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "662f7949-dd0b-4a1a-9286-1bb3ba5d00a8",
+ "variant_id": "4c0ac705-c917-4c0b-b033-a26decb9e5e7",
+ "name": "bulk FTTO BULK 10 Gbit/s 60 mois",
+ "sku": "10000_10000_10000_10000_60_X_BULK_X",
+ "debit": 10000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 432.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "de9fadbd-2740-42e4-ae19-d6187940c1c7",
+ "variant_id": "4f9574b5-c249-468a-838f-5645cdce4f19",
+ "name": "bulk FTTO BULK 50 Mbit/s 12 mois",
+ "sku": "50_50_50_50_12_X_BULK_X",
+ "debit": 50.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "c056f02b-3511-48b3-afd9-37407d1feb07",
+ "variant_id": "558e5885-b6f4-4d7b-abd3-4e68350fed80",
+ "name": "bulk FTTO BULK 5 Mbit/s 60 mois",
+ "sku": "5_5_5_5_60_X_BULK_X",
+ "debit": 5.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 97.2,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "b6aa2f80-be70-4713-9a06-4b5c35e8ac5d",
+ "variant_id": "627d941e-8ff9-4ca2-9a21-c89f1b1f0b8c",
+ "name": "bulk FTTO BULK 30 Mbit/s 12 mois",
+ "sku": "30_30_30_30_12_X_BULK_X",
+ "debit": 30.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4b8d6d99-63a2-442e-be44-eaeedce65fdf",
+ "variant_id": "6ef62fc3-a653-4ae7-9103-de862c6d2b48",
+ "name": "bulk FTTO BULK 500 Mbit/s 60 mois",
+ "sku": "500_500_500_500_60_X_BULK_X",
+ "debit": 500.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 248.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f33b7659-930b-497d-af44-a8387b380704",
+ "variant_id": "77eac21b-d3f4-4368-a989-d47ebd2b966f",
+ "name": "bulk FTTO BULK 50 Mbit/s 36 mois",
+ "sku": "50_50_50_50_36_X_BULK_X",
+ "debit": 50.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "e56940c2-96d3-4f98-8fbf-27418e964d9d",
+ "variant_id": "80c9fe04-318b-4f83-aa5f-ad4be4ae4cd5",
+ "name": "bulk FTTO BULK 1 Gbit/s 12 mois",
+ "sku": "1000_1000_1000_1000_12_X_BULK_X",
+ "debit": 1000.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 270.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1df123e6-9e55-4569-850d-8fb36c9332ec",
+ "variant_id": "82cf0884-046f-432f-b4e7-65bccf4c9708",
+ "name": "bulk FTTO BULK 10 Gbit/s 36 mois",
+ "sku": "10000_10000_10000_10000_36_X_BULK_X",
+ "debit": 10000.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 518.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "43b97180-733a-466c-83b0-c94f72eef428",
+ "variant_id": "857f25e7-f1a9-4ec1-9e65-8f0e14b4ada5",
+ "name": "bulk FTTO BULK 100 Mbit/s 12 mois",
+ "sku": "100_100_100_100_12_X_BULK_X",
+ "debit": 100.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9bab9290-81cc-47bc-82cb-60003b37bb71",
+ "variant_id": "86f63e1e-a388-4786-9628-8ea9e93f9a4e",
+ "name": "bulk FTTO BULK 10 Mbit/s 12 mois",
+ "sku": "10_10_10_10_12_X_BULK_X",
+ "debit": 10.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 129.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "66b1f702-ac98-417b-8137-bbf26021101c",
+ "variant_id": "8bb22736-95f7-4170-b87c-af4ef73f8dda",
+ "name": "bulk FTTO BULK 10 Gbit/s 24 mois",
+ "sku": "10000_10000_10000_10000_24_X_BULK_X",
+ "debit": 10000.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 518.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4fa58b43-2c63-4077-9df8-26fc8ea1b21e",
+ "variant_id": "8bc1894a-d768-43bc-8fa0-f21dae2602ff",
+ "name": "bulk FTTO BULK 80 Mbit/s 24 mois",
+ "sku": "80_80_80_80_24_X_BULK_X",
+ "debit": 80.0,
+ "access_fee": 648.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "8b9bf3dd-578c-4aeb-9590-69ea5c383199",
+ "variant_id": "92f03708-e21b-4c87-9ddb-36f406c866ea",
+ "name": "bulk FTTO BULK 40 Mbit/s 36 mois",
+ "sku": "40_40_40_40_36_X_BULK_X",
+ "debit": 40.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "96beb2e9-6ae3-470a-9eaf-0cdf650fa464",
+ "variant_id": "951cc8a0-86fc-4e90-8f27-efe0e84ef253",
+ "name": "bulk FTTO BULK 200 Mbit/s 12 mois",
+ "sku": "200_200_200_200_12_X_BULK_X",
+ "debit": 200.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 216.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "dd63121e-ffde-4a3a-b76d-a9a76184ccc0",
+ "variant_id": "96a67ec7-df23-4227-b978-fbd796fcbf87",
+ "name": "bulk FTTO BULK 300 Mbit/s 12 mois",
+ "sku": "300_300_300_300_12_X_BULK_X",
+ "debit": 300.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 232.2,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a24d467f-c6b5-4bcd-a07c-ab1995c5ddea",
+ "variant_id": "96b1c312-41fb-4108-b895-a6fc1d2ac8a1",
+ "name": "bulk FTTO BULK 500 Mbit/s 36 mois",
+ "sku": "500_500_500_500_36_X_BULK_X",
+ "debit": 500.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 248.4,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "fa279ff9-98ca-41d2-a06f-32e37791e2af",
+ "variant_id": "98daba85-078d-4988-9ad2-d22603e5ff94",
+ "name": "bulk FTTO BULK 100 Mbit/s 36 mois",
+ "sku": "100_100_100_100_36_X_BULK_X",
+ "debit": 100.0,
+ "access_fee": 432.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 162.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "ea3929f3-f214-4133-a079-9d89b09d7b7c",
+ "variant_id": "9d3858d4-9635-42d7-b93e-901657865009",
+ "name": "bulk FTTO BULK 200 Mbit/s 60 mois",
+ "sku": "200_200_200_200_60_X_BULK_X",
+ "debit": 200.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 216.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "212c825a-5692-44d4-be5f-ed71fd7a6d7b",
+ "variant_id": "9e9eed2a-b6ed-4c7c-a231-779dfee30c15",
+ "name": "bulk FTTO BULK 4 Gbit/s 12 mois",
+ "sku": "4000_4000_4000_4000_12_X_BULK_X",
+ "debit": 4000.0,
+ "access_fee": 972.0,
+ "access_fee_on_quotation": false,
+ "recurring_price": 486.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ }
+ ],
+ "category": "ftto"
+ },
+ {
+ "eligibility_id": "8a96ca15-6294-4853-8951-97453c3bf125",
+ "resolver": "netwo-mobile",
+ "product_id": "27afcb69-54b4-4c14-ade5-373393b27bb5",
+ "contract_version_id": "7dcccbf3-74de-4000-9a66-af896f1a9f1f",
+ "product_name": "Data Mobile",
+ "service_operator": "Netwo",
+ "service_operator_slug": "netwo",
+ "infrastructure_operator": "Orange Mobile",
+ "infrastructure_operator_slug": "netwo-mobile",
+ "infrastructure_type": "data_mobile",
+ "entities": [
+ {
+ "entity_id": "4b33572f-3c39-4d52-bfd0-15d6e8958864",
+ "variant_id": "02dec792-da60-4277-8316-fe1366c00e34",
+ "name": "Data Mobile 3G/4G",
+ "debit": 300.0,
+ "access_fee": 0.0,
+ "recurring_price": 0.0,
+ "intervention_time_guaranteed_delay": "PT4H",
+ "preferred_offer": false,
+ "delivery_protocol": "l2tp"
+ },
+ {
+ "entity_id": "3730cc7a-9f4d-4ca0-93f6-c74892021f0f",
+ "variant_id": "b4c951f6-d4f1-4f7d-bbca-b5a7292ce97f",
+ "name": "Data Mobile 5G",
+ "debit": 1000.0,
+ "access_fee": 0.0,
+ "recurring_price": 4.0,
+ "intervention_time_guaranteed_delay": "PT4H",
+ "preferred_offer": false,
+ "delivery_protocol": "l2tp"
+ }
+ ],
+ "category": "mobile_data"
+ },
+ {
+ "eligibility_id": "8a96ca15-6294-4853-8951-97453c3bf125",
+ "resolver": "celeste",
+ "product_id": "3850276c-a08b-486a-952f-ce17fe754b12",
+ "contract_version_id": "395c0670-1002-43f5-bf98-f599b1f38a96",
+ "product_name": "FTTO",
+ "service_operator": "Netwo",
+ "service_operator_slug": "netwo",
+ "infrastructure_operator": "Celeste",
+ "infrastructure_operator_slug": "celeste",
+ "infrastructure_type": "ftto",
+ "entities": [
+ {
+ "entity_id": "3bea7e36-6694-44a4-901d-44c88d924ab1",
+ "variant_id": "c1092639-1a7a-43a9-a527-684d1c7ed765",
+ "name": "CF1 10 Mbit/s 36 mois",
+ "sku": "10_10_10_10_36_X_CF1_X",
+ "debit": 10.0,
+ "access_fee": 530.0,
+ "recurring_price": 133.56,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "3517144c-5dca-4aa0-a8b8-2c04da041b20",
+ "variant_id": "25b7fc4d-3a64-49be-9b2a-5056109db3ef",
+ "name": "CF1 1 Gbit/s 12 mois",
+ "sku": "1000_1000_1000_1000_12_X_CF1_X",
+ "debit": 1000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 479.12,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "213a9d0a-1d43-4e9a-bae2-621a7bad8a69",
+ "variant_id": "2acb0379-e51f-4840-adf0-ccb2a57033fa",
+ "name": "CF1 10 Gbit/s 36 mois",
+ "sku": "10000_10000_10000_10000_36_X_CF1_X",
+ "debit": 10000.0,
+ "access_fee": 530.0,
+ "recurring_price": 1252.92,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "bedf13ed-c693-4ada-bb3a-cdac120543f9",
+ "variant_id": "2e2a8485-89c4-4ef8-9c3e-1c991ab8a9d0",
+ "name": "CF1 1 Gbit/s 60 mois",
+ "sku": "1000_1000_1000_1000_60_X_CF1_X",
+ "debit": 1000.0,
+ "access_fee": 0.0,
+ "recurring_price": 479.12,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "cf983a71-5cdf-4737-ab19-b9578135633b",
+ "variant_id": "2f09eac8-f8ce-4c78-9969-43b3f87b5fb5",
+ "name": "CF1 200 Mbit/s 12 mois",
+ "sku": "200_200_200_200_12_X_CF1_X",
+ "debit": 200.0,
+ "access_fee": 1590.0,
+ "recurring_price": 253.34,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "51348220-5afc-44d0-a445-8b07c4341c0e",
+ "variant_id": "463fab4c-ece5-49b6-b747-d6a496e851cf",
+ "name": "CF1 300 Mbit/s 36 mois",
+ "sku": "300_300_300_300_36_X_CF1_X",
+ "debit": 300.0,
+ "access_fee": 530.0,
+ "recurring_price": 304.22,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "0b296462-0ffc-4c49-9641-ca3736169d55",
+ "variant_id": "47e19ccc-e4b1-4ac5-9046-3b4db28afbaa",
+ "name": "CF1 5 Mbit/s 60 mois",
+ "sku": "5_5_5_5_60_X_CF1_X",
+ "debit": 5.0,
+ "access_fee": 0.0,
+ "recurring_price": 126.14,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1ec438d0-f51a-42fd-be4e-5c75a5fe816d",
+ "variant_id": "4e207be0-9f47-4ef1-9eac-15bbddb760cd",
+ "name": "CF1 50 Mbit/s 60 mois",
+ "sku": "50_50_50_50_60_X_CF1_X",
+ "debit": 50.0,
+ "access_fee": 0.0,
+ "recurring_price": 161.12,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "8b6f6429-a638-4033-b244-7c16920c37e6",
+ "variant_id": "5633b6fc-6596-43f6-9681-380a1912dfb2",
+ "name": "CF1 30 Mbit/s 12 mois",
+ "sku": "30_30_30_30_12_X_CF1_X",
+ "debit": 30.0,
+ "access_fee": 1590.0,
+ "recurring_price": 143.1,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "50c293ff-e0fb-4e92-8f0e-1f8b7d69d92f",
+ "variant_id": "56ed7b7c-87fc-44bc-8e09-f7596898b4f2",
+ "name": "CF1 2 Mbit/s 36 mois",
+ "sku": "2_2_2_2_36_X_CF1_X",
+ "debit": 2.0,
+ "access_fee": 530.0,
+ "recurring_price": 121.9,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "2efb4314-1362-4451-913b-9bb67516c592",
+ "variant_id": "5e862668-1b67-41f4-a30c-7c63b910abda",
+ "name": "CF1 5 Gbit/s 60 mois",
+ "sku": "5000_5000_5000_5000_60_X_CF1_X",
+ "debit": 5000.0,
+ "access_fee": 0.0,
+ "recurring_price": 825.74,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "59c27d59-126e-4974-9156-38ec0fd99b07",
+ "variant_id": "5fa3f171-0228-41c0-8c27-b342935fd5a3",
+ "name": "CF1 500 Mbit/s 36 mois",
+ "sku": "500_500_500_500_36_X_CF1_X",
+ "debit": 500.0,
+ "access_fee": 530.0,
+ "recurring_price": 414.46,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "50028342-75a8-4214-88ae-98f7e2897c25",
+ "variant_id": "625351a6-0c75-47fa-a9bc-cd68e716e0ce",
+ "name": "CF1 20 Mbit/s 60 mois",
+ "sku": "20_20_20_20_60_X_CF1_X",
+ "debit": 20.0,
+ "access_fee": 0.0,
+ "recurring_price": 138.86,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "45f511e9-f709-4351-aee1-90dd2e08b1aa",
+ "variant_id": "646079da-f68e-4dfb-9a17-fa296e8aa93b",
+ "name": "CF1 5 Gbit/s 36 mois",
+ "sku": "5000_5000_5000_5000_36_X_CF1_X",
+ "debit": 5000.0,
+ "access_fee": 530.0,
+ "recurring_price": 825.74,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "5afed7ee-fda1-4d64-8233-6d12d1741dcf",
+ "variant_id": "65d6377a-268a-4e2d-b75f-136ecd548630",
+ "name": "CF1 2 Gbit/s 12 mois",
+ "sku": "2000_2000_2000_2000_12_X_CF1_X",
+ "debit": 2000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 570.28,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "3216981f-9728-49b2-9cce-ec5f75dcf487",
+ "variant_id": "6d5bba5f-447f-469d-bf02-f7adc66a39f0",
+ "name": "CF1 30 Mbit/s 36 mois",
+ "sku": "30_30_30_30_36_X_CF1_X",
+ "debit": 30.0,
+ "access_fee": 530.0,
+ "recurring_price": 143.1,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "17376a56-5152-4f77-a6cf-3f9d0dd58332",
+ "variant_id": "6fa697c6-df70-49f3-92da-cd6a1080c58f",
+ "name": "CF1 200 Mbit/s 60 mois",
+ "sku": "200_200_200_200_60_X_CF1_X",
+ "debit": 200.0,
+ "access_fee": 0.0,
+ "recurring_price": 253.34,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "46047bad-5c73-465c-8ed0-56e8fac0404d",
+ "variant_id": "6fddd3c1-bdf4-490c-9bbb-1a2f03eda67b",
+ "name": "CF1 500 Mbit/s 60 mois",
+ "sku": "500_500_500_500_60_X_CF1_X",
+ "debit": 500.0,
+ "access_fee": 0.0,
+ "recurring_price": 414.46,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "21996ff7-17f0-455d-bc8b-f9e708fbb63c",
+ "variant_id": "7c85d9c0-2ae6-4c82-ae74-75da1c60b1e1",
+ "name": "CF1 20 Mbit/s 36 mois",
+ "sku": "20_20_20_20_36_X_CF1_X",
+ "debit": 20.0,
+ "access_fee": 530.0,
+ "recurring_price": 138.86,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "56aa8e72-0f55-4a19-9214-fb0fbd1c1c19",
+ "variant_id": "7dd3304d-e205-42c2-b749-4ab33420fedb",
+ "name": "CF1 400 Mbit/s 36 mois",
+ "sku": "400_400_400_400_36_X_CF1_X",
+ "debit": 400.0,
+ "access_fee": 530.0,
+ "recurring_price": 362.52,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4184cb82-fb08-48e0-9883-73a9c07d4567",
+ "variant_id": "86f56691-0826-48f0-9fc2-481e6ba15187",
+ "name": "CF1 5 Mbit/s 36 mois",
+ "sku": "5_5_5_5_36_X_CF1_X",
+ "debit": 5.0,
+ "access_fee": 530.0,
+ "recurring_price": 126.14,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "3bc489d8-ac2f-44db-bb50-95f6965cf1bc",
+ "variant_id": "871ea39d-2f6d-45ab-9a8b-ffa40c4ac795",
+ "name": "CF1 10 Mbit/s 12 mois",
+ "sku": "10_10_10_10_12_X_CF1_X",
+ "debit": 10.0,
+ "access_fee": 1590.0,
+ "recurring_price": 133.56,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1dc9943b-d56f-4fe6-8e91-c150f4ca856d",
+ "variant_id": "8bbf44f8-e70b-4d34-a75b-2f3834f0aacd",
+ "name": "CF1 100 Mbit/s 60 mois",
+ "sku": "100_100_100_100_60_X_CF1_X",
+ "debit": 100.0,
+ "access_fee": 0.0,
+ "recurring_price": 201.4,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4a0229ce-2b66-44d5-910c-244a5f368649",
+ "variant_id": "8d6b3063-7f4a-470e-bfd0-153d8fdbe3d5",
+ "name": "CF1 400 Mbit/s 60 mois",
+ "sku": "400_400_400_400_60_X_CF1_X",
+ "debit": 400.0,
+ "access_fee": 0.0,
+ "recurring_price": 362.52,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "5f97a43c-a100-496c-b678-f95502a961e9",
+ "variant_id": "8de1f7f3-0d39-4f02-aae5-6c71ec04c935",
+ "name": "CF1 500 Mbit/s 12 mois",
+ "sku": "500_500_500_500_12_X_CF1_X",
+ "debit": 500.0,
+ "access_fee": 1590.0,
+ "recurring_price": 414.46,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4f61fda2-004a-4e64-8f32-6c14ccd9c1c3",
+ "variant_id": "93e11fe9-a0cc-4c28-9757-6b2056b523b3",
+ "name": "CF1 2 Mbit/s 12 mois",
+ "sku": "2_2_2_2_12_X_CF1_X",
+ "debit": 2.0,
+ "access_fee": 1590.0,
+ "recurring_price": 121.9,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "fa2db627-3c7d-4b11-9097-557bea943c5b",
+ "variant_id": "9ea0e993-abc2-46e0-9347-b58dffe6fa99",
+ "name": "CF1 300 Mbit/s 12 mois",
+ "sku": "300_300_300_300_12_X_CF1_X",
+ "debit": 300.0,
+ "access_fee": 1590.0,
+ "recurring_price": 304.22,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "b16c85d8-35b2-4113-99a8-c2ed891fcfaa",
+ "variant_id": "ac5dbe2f-0584-4bb7-bd13-3b7ec8cdf538",
+ "name": "CF1 10 Mbit/s 60 mois",
+ "sku": "10_10_10_10_60_X_CF1_X",
+ "debit": 10.0,
+ "access_fee": 0.0,
+ "recurring_price": 133.56,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a23ed505-9b8b-422e-a735-e760d2200a24",
+ "variant_id": "b2f1e146-798f-46eb-b7e4-c49e88a2aaf3",
+ "name": "CF1 400 Mbit/s 12 mois",
+ "sku": "400_400_400_400_12_X_CF1_X",
+ "debit": 400.0,
+ "access_fee": 1590.0,
+ "recurring_price": 362.52,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "6310a53b-ce1a-495b-8a7f-dfc279ec8ae7",
+ "variant_id": "b78ea148-c258-4fd2-8966-0bf795820a3b",
+ "name": "CF1 50 Mbit/s 12 mois",
+ "sku": "50_50_50_50_12_X_CF1_X",
+ "debit": 50.0,
+ "access_fee": 1590.0,
+ "recurring_price": 161.12,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4a55aa28-652f-424a-88de-d126c3d3db98",
+ "variant_id": "04f0af6a-7d63-4c4c-8c88-0a2e52e06fea",
+ "name": "CF1 100 Mbit/s 12 mois",
+ "sku": "100_100_100_100_12_X_CF1_X",
+ "debit": 100.0,
+ "access_fee": 1590.0,
+ "recurring_price": 201.4,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a287af08-34d5-4590-a1bf-6073e82662a9",
+ "variant_id": "c34ad085-b566-49b2-903a-55f74fe72263",
+ "name": "CF1 30 Mbit/s 60 mois",
+ "sku": "30_30_30_30_60_X_CF1_X",
+ "debit": 30.0,
+ "access_fee": 0.0,
+ "recurring_price": 143.1,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "c909c637-5315-4e99-8436-7cbc3b8407a9",
+ "variant_id": "c5dce8f1-b2a2-4759-bf39-91a762b149b0",
+ "name": "CF1 5 Gbit/s 12 mois",
+ "sku": "5000_5000_5000_5000_12_X_CF1_X",
+ "debit": 5000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 825.74,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a709f368-d18e-493b-b4d7-561e207bf7ec",
+ "variant_id": "ca3a5940-a381-4516-ab91-e432af8ff651",
+ "name": "CF1 2 Gbit/s 36 mois",
+ "sku": "2000_2000_2000_2000_36_X_CF1_X",
+ "debit": 2000.0,
+ "access_fee": 530.0,
+ "recurring_price": 570.28,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "0cce25ed-142a-4d89-8dd2-da99841b1635",
+ "variant_id": "cc97fa09-05db-4fca-a961-50c974b3b8e1",
+ "name": "CF1 20 Mbit/s 12 mois",
+ "sku": "20_20_20_20_12_X_CF1_X",
+ "debit": 20.0,
+ "access_fee": 1590.0,
+ "recurring_price": 138.86,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f3111d10-1b2c-43a0-963c-d0aa936146ed",
+ "variant_id": "de6fbde1-387b-481b-ab92-fb6a65a3f5de",
+ "name": "CF1 2 Gbit/s 60 mois",
+ "sku": "2000_2000_2000_2000_60_X_CF1_X",
+ "debit": 2000.0,
+ "access_fee": 0.0,
+ "recurring_price": 570.28,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "97d5142e-2d69-49b9-9bbb-46121d0d0496",
+ "variant_id": "debf59d5-5978-4e6d-8e7c-a59c05341b72",
+ "name": "CF1 100 Mbit/s 36 mois",
+ "sku": "100_100_100_100_36_X_CF1_X",
+ "debit": 100.0,
+ "access_fee": 530.0,
+ "recurring_price": 201.4,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "b99b3450-2a24-43d7-9297-f0e16f831689",
+ "variant_id": "e987a8c5-143d-4bb2-be2c-bf309addf03d",
+ "name": "CF1 10 Gbit/s 12 mois",
+ "sku": "10000_10000_10000_10000_12_X_CF1_X",
+ "debit": 10000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 1252.92,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "3ca93227-293f-4bbd-a189-bccaafb74db8",
+ "variant_id": "f2039a76-aa41-45bb-b51f-6105ef1f4159",
+ "name": "CF1 5 Mbit/s 12 mois",
+ "sku": "5_5_5_5_12_X_CF1_X",
+ "debit": 5.0,
+ "access_fee": 1590.0,
+ "recurring_price": 126.14,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "b1c8589a-6d5f-4414-b9ee-608a775098b6",
+ "variant_id": "f2fae281-8592-4767-a31a-0fa5959d9f81",
+ "name": "CF1 1 Gbit/s 36 mois",
+ "sku": "1000_1000_1000_1000_36_X_CF1_X",
+ "debit": 1000.0,
+ "access_fee": 530.0,
+ "recurring_price": 479.12,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "19dd8739-2820-4eac-8cd2-6202a0d6b950",
+ "variant_id": "f30c53b1-830e-4e9f-8ac6-55bca8bc8dd0",
+ "name": "CF1 50 Mbit/s 36 mois",
+ "sku": "50_50_50_50_36_X_CF1_X",
+ "debit": 50.0,
+ "access_fee": 530.0,
+ "recurring_price": 161.12,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "8f05cdf0-be46-4017-b6b2-6a9dc0bc8302",
+ "variant_id": "fa693ddd-67d2-4424-a287-7a7e6e263fa7",
+ "name": "CF1 300 Mbit/s 60 mois",
+ "sku": "300_300_300_300_60_X_CF1_X",
+ "debit": 300.0,
+ "access_fee": 0.0,
+ "recurring_price": 304.22,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "60a20508-f2d9-4315-bf28-38bb7c82fcfc",
+ "variant_id": "fb9f0aaf-911d-4531-bcf6-622de29aaac8",
+ "name": "CF1 10 Gbit/s 60 mois",
+ "sku": "10000_10000_10000_10000_60_X_CF1_X",
+ "debit": 10000.0,
+ "access_fee": 0.0,
+ "recurring_price": 1252.92,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "74332199-26e2-42f3-bc98-61f43d0bdadb",
+ "variant_id": "fbd96c00-ef31-4f15-befb-fe98508b1acc",
+ "name": "CF1 2 Mbit/s 60 mois",
+ "sku": "2_2_2_2_60_X_CF1_X",
+ "debit": 2.0,
+ "access_fee": 0.0,
+ "recurring_price": 121.9,
+ "commitment_duration": 60,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9bddca7b-d1f2-471d-83d5-eb6111151874",
+ "variant_id": "fe1c7ffe-c235-4093-bd8a-000b9cb8efaf",
+ "name": "CF1 200 Mbit/s 36 mois",
+ "sku": "200_200_200_200_36_X_CF1_X",
+ "debit": 200.0,
+ "access_fee": 530.0,
+ "recurring_price": 253.34,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ }
+ ],
+ "category": "ftto"
+ },
+ {
+ "eligibility_id": "8a96ca15-6294-4853-8951-97453c3bf125",
+ "resolver": "orange",
+ "product_id": "45cbe98e-3818-4595-a12e-d27698240051",
+ "contract_version_id": "87973dcf-093b-44bb-8c6f-3de7c317b7f6",
+ "product_name": "CELAN FTTO data entreprise",
+ "service_operator": "Netwo",
+ "service_operator_slug": "netwo",
+ "infrastructure_operator": "Orange",
+ "infrastructure_operator_slug": "orange",
+ "infrastructure_type": "ftto",
+ "entities": [
+ {
+ "entity_id": "aec21047-f6e9-4752-a8f7-7f4d6dfae768",
+ "variant_id": "01f73d66-f345-469c-873f-2634bb871686",
+ "name": "Data entreprise O1 site non fibr\u00e9 2 Mbit/s 12 mois National",
+ "sku": "2_2_2_2_12_X_O1SITENONFIBRE_NAT",
+ "debit": 2.0,
+ "access_fee": 1560.0,
+ "recurring_price": 216.84,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "fb8ecb62-6ecc-4168-8e2b-318137f6549b",
+ "variant_id": "17031444-960c-4343-b35c-f4fb9b0de6f3",
+ "name": "Data entreprise O1 site non fibr\u00e9 100 Mbit/s 36 mois National",
+ "sku": "100_100_100_100_36_X_O1SITENONFIBRE_NAT",
+ "debit": 100.0,
+ "access_fee": 416.0,
+ "recurring_price": 298.48,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f28ba618-b48b-4fd4-a06c-f537bcdf8d2a",
+ "variant_id": "3c1acefc-e2c9-4c79-a9b8-9d3019c2d177",
+ "name": "Data entreprise O1 site non fibr\u00e9 50 Mbit/s 12 mois National",
+ "sku": "50_50_50_50_12_X_O1SITENONFIBRE_NAT",
+ "debit": 50.0,
+ "access_fee": 1560.0,
+ "recurring_price": 348.4,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "dda19705-9490-4bf5-9610-8a9383199a53",
+ "variant_id": "3df95864-727f-4117-88ba-68862a826ad4",
+ "name": "Data entreprise O1 site non fibr\u00e9 30 Mbit/s 36 mois National",
+ "sku": "30_30_30_30_36_X_O1SITENONFIBRE_NAT",
+ "debit": 30.0,
+ "access_fee": 416.0,
+ "recurring_price": 242.32,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "35363e8d-9e94-4996-a72a-8cbd38a17e3e",
+ "variant_id": "4aa0e86d-293b-43f2-b324-1ebc46bdadb4",
+ "name": "Data entreprise O1 site non fibr\u00e9 4 Mbit/s 36 mois National",
+ "sku": "4_4_4_4_36_X_O1SITENONFIBRE_NAT",
+ "debit": 4.0,
+ "access_fee": 416.0,
+ "recurring_price": 193.44,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "672413e4-4f6a-486f-ae7a-4c6352b3b021",
+ "variant_id": "4b963da2-50aa-4115-8824-558a41b0ff16",
+ "name": "Data entreprise O1 site non fibr\u00e9 100 Mbit/s 12 mois National",
+ "sku": "100_100_100_100_12_X_O1SITENONFIBRE_NAT",
+ "debit": 100.0,
+ "access_fee": 1560.0,
+ "recurring_price": 392.08,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "d33b41a3-95cb-4f96-9406-c86bc9db3194",
+ "variant_id": "4d7a0a16-c6f3-4418-9fa0-f435b4f45406",
+ "name": "Data entreprise O1 site non fibr\u00e9 20 Mbit/s 36 mois National",
+ "sku": "20_20_20_20_36_X_O1SITENONFIBRE_NAT",
+ "debit": 20.0,
+ "access_fee": 416.0,
+ "recurring_price": 226.72,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "e0cd5dca-ec72-4b2a-bd6f-74d549e70221",
+ "variant_id": "5d5e7131-0e43-4d12-aade-8854c7a06b6f",
+ "name": "Data entreprise O1 site non fibr\u00e9 200 Mbit/s 12 mois National",
+ "sku": "200_200_200_200_12_X_O1SITENONFIBRE_NAT",
+ "debit": 200.0,
+ "access_fee": 1560.0,
+ "recurring_price": 469.04,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9f32a5bc-e4dc-4d47-8d66-ddec61f20f08",
+ "variant_id": "61304879-0209-4ce8-b84c-556af24b5c2c",
+ "name": "Data entreprise O1 site non fibr\u00e9 10 Mbit/s 12 mois National",
+ "sku": "10_10_10_10_12_X_O1SITENONFIBRE_NAT",
+ "debit": 10.0,
+ "access_fee": 1560.0,
+ "recurring_price": 240.24,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a07a5679-c25d-4372-b21f-fae09a7866fc",
+ "variant_id": "621fbe96-cd7e-4ecc-a282-9c3010697416",
+ "name": "Data entreprise O1 site non fibr\u00e9 30 Mbit/s 12 mois National",
+ "sku": "30_30_30_30_12_X_O1SITENONFIBRE_NAT",
+ "debit": 30.0,
+ "access_fee": 1560.0,
+ "recurring_price": 304.72,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "b2704402-7179-4c26-9af7-bfa6fb8fb368",
+ "variant_id": "6434d0e4-90cf-4311-982e-73f813160f32",
+ "name": "Data entreprise O1 site non fibr\u00e9 1 Gbit/s 36 mois National",
+ "sku": "1000_1000_1000_1000_36_X_O1SITENONFIBRE_NAT",
+ "debit": 1000.0,
+ "access_fee": 416.0,
+ "recurring_price": 535.6,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "7d6e5f3a-ea3d-43ef-8176-ed7f9120243f",
+ "variant_id": "66fe7f17-2364-4ed4-9bec-04a911ae59c2",
+ "name": "Data entreprise O1 site non fibr\u00e9 50 Mbit/s 36 mois National",
+ "sku": "50_50_50_50_36_X_O1SITENONFIBRE_NAT",
+ "debit": 50.0,
+ "access_fee": 416.0,
+ "recurring_price": 269.36,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "638180d9-2928-49a8-aaec-d2c54a498c7b",
+ "variant_id": "7346171e-3460-43ae-85e5-421ecd435bd2",
+ "name": "Data entreprise O1 site non fibr\u00e9 500 Mbit/s 12 mois National",
+ "sku": "500_500_500_500_12_X_O1SITENONFIBRE_NAT",
+ "debit": 500.0,
+ "access_fee": 1560.0,
+ "recurring_price": 613.6,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4d2c624f-c16b-4735-b20d-029ac2198fd6",
+ "variant_id": "76e99345-ad70-4f42-a45e-1acf2a8dc0b2",
+ "name": "Data entreprise O1 site non fibr\u00e9 4 Mbit/s 12 mois National",
+ "sku": "4_4_4_4_12_X_O1SITENONFIBRE_NAT",
+ "debit": 4.0,
+ "access_fee": 1560.0,
+ "recurring_price": 223.6,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "528aacd0-4812-4e15-8a53-280cb654a36f",
+ "variant_id": "7c9264fa-ef8c-44e8-9d4c-52d9ad961bac",
+ "name": "Data entreprise O1 site non fibr\u00e9 1 Gbit/s 12 mois National",
+ "sku": "1000_1000_1000_1000_12_X_O1SITENONFIBRE_NAT",
+ "debit": 1000.0,
+ "access_fee": 1560.0,
+ "recurring_price": 728.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "478c1560-d8d4-4504-b158-09872fad43ed",
+ "variant_id": "828a0d54-e1da-45ee-a875-94c22a8df8ec",
+ "name": "Data entreprise O1 site non fibr\u00e9 40 Mbit/s 12 mois National",
+ "sku": "40_40_40_40_12_X_O1SITENONFIBRE_NAT",
+ "debit": 40.0,
+ "access_fee": 1560.0,
+ "recurring_price": 327.6,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "e4259f46-c5a7-45bc-a1b8-e645519b7209",
+ "variant_id": "865d4830-c3ae-4be0-8ded-32c3cabbb0d5",
+ "name": "Data entreprise O1 site non fibr\u00e9 2 Mbit/s 36 mois National",
+ "sku": "2_2_2_2_36_X_O1SITENONFIBRE_NAT",
+ "debit": 2.0,
+ "access_fee": 416.0,
+ "recurring_price": 165.88,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "e6ce6289-9d1c-4dee-879d-6680da9f93df",
+ "variant_id": "8bfa4dab-5dc7-4e65-9980-57e11de88942",
+ "name": "Data entreprise O1 site non fibr\u00e9 10 Mbit/s 36 mois National",
+ "sku": "10_10_10_10_36_X_O1SITENONFIBRE_NAT",
+ "debit": 10.0,
+ "access_fee": 416.0,
+ "recurring_price": 210.08,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "510d8960-1628-479a-aa1e-2a803de6fae4",
+ "variant_id": "8e716ff0-84ef-487a-90f8-fc3f4c4ece16",
+ "name": "Data entreprise O1 site non fibr\u00e9 200 Mbit/s 36 mois National",
+ "sku": "200_200_200_200_36_X_O1SITENONFIBRE_NAT",
+ "debit": 200.0,
+ "access_fee": 416.0,
+ "recurring_price": 377.52,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "6a4aa2fd-d5d8-4fc6-adaf-93976586357c",
+ "variant_id": "9320c5be-bd21-48b8-aa93-2bd2743268a1",
+ "name": "Data entreprise O1 site non fibr\u00e9 500 Mbit/s 36 mois National",
+ "sku": "500_500_500_500_36_X_O1SITENONFIBRE_NAT",
+ "debit": 500.0,
+ "access_fee": 416.0,
+ "recurring_price": 488.8,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "01c85989-e00f-41a0-9060-eac20b5d85a8",
+ "variant_id": "a31edde2-977a-4ae9-b893-7cf836081143",
+ "name": "Data entreprise O1 site non fibr\u00e9 20 Mbit/s 12 mois National",
+ "sku": "20_20_20_20_12_X_O1SITENONFIBRE_NAT",
+ "debit": 20.0,
+ "access_fee": 1560.0,
+ "recurring_price": 275.6,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "5412a343-dcb5-4807-839d-dda04b8c401e",
+ "variant_id": "b3a140db-e87d-4a8e-afcb-41891844b615",
+ "name": "Data entreprise O1 site non fibr\u00e9 300 Mbit/s 12 mois National",
+ "sku": "300_300_300_300_12_X_O1SITENONFIBRE_NAT",
+ "debit": 300.0,
+ "access_fee": 1560.0,
+ "recurring_price": 546.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "ef41845d-5b13-4f66-a9d6-30ad39bc43aa",
+ "variant_id": "b9aa8d02-12b2-42d9-ba18-213dd07cab9d",
+ "name": "Data entreprise O1 site non fibr\u00e9 300 Mbit/s 36 mois National",
+ "sku": "300_300_300_300_36_X_O1SITENONFIBRE_NAT",
+ "debit": 300.0,
+ "access_fee": 416.0,
+ "recurring_price": 455.52,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "859db859-aac5-487b-9129-ffc3dc68aa78",
+ "variant_id": "fb157d18-45a2-4763-b248-5562440acf85",
+ "name": "Data entreprise O1 site non fibr\u00e9 40 Mbit/s 36 mois National",
+ "sku": "40_40_40_40_36_X_O1SITENONFIBRE_NAT",
+ "debit": 40.0,
+ "access_fee": 416.0,
+ "recurring_price": 256.88,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ }
+ ],
+ "category": "ftto"
+ },
+ {
+ "eligibility_id": "8a96ca15-6294-4853-8951-97453c3bf125",
+ "resolver": "covage-ftto",
+ "product_id": "52e776f4-6e66-44ea-a2e0-639490cc1d19",
+ "contract_version_id": "9160e4dd-c222-46a2-aa7d-c3289c6fb27c",
+ "product_name": "FTTO BPEA",
+ "service_operator": "Netwo",
+ "service_operator_slug": "netwo",
+ "infrastructure_operator": "Covage",
+ "infrastructure_operator_slug": "kosc",
+ "infrastructure_type": "ftto",
+ "entities": [
+ {
+ "entity_id": "fcaa9616-4db1-4a57-93d1-2c2df605eafa",
+ "variant_id": "19c0f0a9-096c-44b5-893f-d8f50e348a01",
+ "name": "FTTO Zone Hors Forfait - 100 Mbit/s 24 mois",
+ "sku": "100_2_100_2_24_X_ZONEHORSFORFAIT_X",
+ "debit": 100.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 79.5,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "db2ec25d-90fd-49c0-a998-af0b7600b4ec",
+ "variant_id": "b605ea5d-9e46-4d9b-8f7c-c83b6e68f2af",
+ "name": "FTTO Zone Hors Forfait - 100 Mbit/s 36 mois",
+ "sku": "100_2_100_2_36_X_ZONEHORSFORFAIT_X",
+ "debit": 100.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 79.5,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ }
+ ],
+ "category": "ftto"
+ },
+ {
+ "eligibility_id": "8a96ca15-6294-4853-8951-97453c3bf125",
+ "resolver": "eurafibre",
+ "product_id": "7cdba5b7-844f-4e7f-8c93-cb85ea54caf9",
+ "contract_version_id": "bbdc8fa4-7ff2-487d-bb11-1dd0e1fe31c4",
+ "product_name": "FTTO",
+ "service_operator": "Netwo",
+ "service_operator_slug": "netwo",
+ "infrastructure_operator": "Eurofiber France",
+ "infrastructure_operator_slug": "eurafibre",
+ "infrastructure_type": "ftto",
+ "entities": [
+ {
+ "entity_id": "291d7735-5e21-49b3-a92d-1aec10139112",
+ "variant_id": "f865e34c-0a19-45f2-89e7-ec03fe41c54b",
+ "name": "ZEURA FTTO 200 Mbit/s 48 mois",
+ "sku": "200_200_200_200_48_X_ZEURA_X",
+ "debit": 200.0,
+ "access_fee": 0.0,
+ "recurring_price": 265.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "e76e41d2-1a9f-4ce1-9f37-dfb8eab05dfb",
+ "variant_id": "2dc693bc-4649-4d54-80a6-5b83cdcb6c67",
+ "name": "ZEURA FTTO 2 Gbit/s 24 mois",
+ "sku": "2000_2000_2000_2000_24_X_ZEURA_X",
+ "debit": 2000.0,
+ "access_fee": 795.0,
+ "recurring_price": 530.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4f81ce14-c0c7-4628-90e8-15c45796f949",
+ "variant_id": "300d99de-5b21-43ad-ba4a-2821cdd1023f",
+ "name": "ZEURA FTTO 20 Mbit/s 24 mois",
+ "sku": "20_20_20_20_24_X_ZEURA_X",
+ "debit": 20.0,
+ "access_fee": 795.0,
+ "recurring_price": 159.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f6ea3811-f91b-41ea-bda7-b94f56dc384d",
+ "variant_id": "33b7d615-6238-4039-b2fe-955499389353",
+ "name": "ZEURA FTTO 100 Mbit/s 48 mois",
+ "sku": "100_100_100_100_48_X_ZEURA_X",
+ "debit": 100.0,
+ "access_fee": 0.0,
+ "recurring_price": 212.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9954b1cf-850c-48fe-b0c2-7e973e7c0ef1",
+ "variant_id": "4ef2cb76-f0b6-44eb-becf-8c529b31ed87",
+ "name": "ZEURA FTTO 1 Gbit/s 48 mois",
+ "sku": "1000_1000_1000_1000_48_X_ZEURA_X",
+ "debit": 1000.0,
+ "access_fee": 0.0,
+ "recurring_price": 371.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "29758801-1236-4a75-b7bb-274604fdc4cd",
+ "variant_id": "563c6b50-623c-4bd6-9ecc-c78aea68a24e",
+ "name": "ZEURA FTTO 1 Gbit/s 36 mois",
+ "sku": "1000_1000_1000_1000_36_X_ZEURA_X",
+ "debit": 1000.0,
+ "access_fee": 530.0,
+ "recurring_price": 371.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "61b47fb9-973b-4246-8fdd-c8c82ae709aa",
+ "variant_id": "5ced58d5-3f1d-4d6c-b604-dc1c33c78112",
+ "name": "ZEURA FTTO 5 Gbit/s 12 mois",
+ "sku": "5000_5000_5000_5000_12_X_ZEURA_X",
+ "debit": 5000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 848.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "89be92a9-7718-4dba-80ba-36c7e06d6038",
+ "variant_id": "5ec52344-4e82-41df-9566-52c9b6d959e6",
+ "name": "ZEURA FTTO 20 Mbit/s 36 mois",
+ "sku": "20_20_20_20_36_X_ZEURA_X",
+ "debit": 20.0,
+ "access_fee": 530.0,
+ "recurring_price": 159.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "e27c1b50-3c2a-47dd-8526-1af3f6347c1b",
+ "variant_id": "5f82c491-79fd-49cd-b374-d763088dea5c",
+ "name": "ZEURA FTTO 10 Gbit/s 36 mois",
+ "sku": "10000_10000_10000_10000_36_X_ZEURA_X",
+ "debit": 10000.0,
+ "access_fee": 530.0,
+ "recurring_price": 1060.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "41096358-83ab-4634-b974-36c129e33d4d",
+ "variant_id": "603f7efb-f2bb-47db-82aa-c4e3f96a24f8",
+ "name": "ZEURA FTTO 20 Mbit/s 48 mois",
+ "sku": "20_20_20_20_48_X_ZEURA_X",
+ "debit": 20.0,
+ "access_fee": 0.0,
+ "recurring_price": 159.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "dcbc41d9-d816-4243-8480-520834093584",
+ "variant_id": "6b21d700-aee7-4941-9058-0723d9a422c7",
+ "name": "ZEURA FTTO 500 Mbit/s 24 mois",
+ "sku": "500_500_500_500_24_X_ZEURA_X",
+ "debit": 500.0,
+ "access_fee": 795.0,
+ "recurring_price": 291.5,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "764bae33-2c9e-401d-ba3c-c4e968e7f70e",
+ "variant_id": "77a0f2ea-c3d6-4b0a-b0d9-26b71d529032",
+ "name": "ZEURA FTTO 3 Gbit/s 36 mois",
+ "sku": "3000_3000_3000_3000_36_X_ZEURA_X",
+ "debit": 3000.0,
+ "access_fee": 530.0,
+ "recurring_price": 636.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "7db8208a-c929-4474-b80c-972a63d04496",
+ "variant_id": "7ee1b772-ae18-4c6c-b39f-ea3a23bda990",
+ "name": "ZEURA FTTO 200 Mbit/s 12 mois",
+ "sku": "200_200_200_200_12_X_ZEURA_X",
+ "debit": 200.0,
+ "access_fee": 1590.0,
+ "recurring_price": 265.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "40831280-f814-4d5e-b40f-6f35bea9a58e",
+ "variant_id": "824b11af-dce8-41f7-8d73-e6b7cc6ce2ea",
+ "name": "ZEURA FTTO 100 Mbit/s 12 mois",
+ "sku": "100_100_100_100_12_X_ZEURA_X",
+ "debit": 100.0,
+ "access_fee": 1590.0,
+ "recurring_price": 212.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "58b0420b-2379-402c-9ad0-d9d125f31648",
+ "variant_id": "84635066-7af9-43d0-a189-e3db13f68ff7",
+ "name": "ZEURA FTTO 50 Mbit/s 48 mois",
+ "sku": "50_50_50_50_48_X_ZEURA_X",
+ "debit": 50.0,
+ "access_fee": 0.0,
+ "recurring_price": 185.5,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "5f474e4a-c2ba-44b9-bd59-4e65453587f1",
+ "variant_id": "88d5a508-89b6-427a-9e10-cbaae6c8ae24",
+ "name": "ZEURA FTTO 20 Mbit/s 12 mois",
+ "sku": "20_20_20_20_12_X_ZEURA_X",
+ "debit": 20.0,
+ "access_fee": 1590.0,
+ "recurring_price": 159.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "d041beb8-5bf2-4c6b-bc4c-35806cfa022f",
+ "variant_id": "914e4b3c-fd30-4164-93b8-b8af2f917607",
+ "name": "ZEURA FTTO 2 Gbit/s 12 mois",
+ "sku": "2000_2000_2000_2000_12_X_ZEURA_X",
+ "debit": 2000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 530.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "b02c68d0-76e6-4e50-b9e4-c737ce4b15ab",
+ "variant_id": "97d2ba3b-9271-4e5e-8c32-2431a49442a0",
+ "name": "ZEURA FTTO 4 Gbit/s 12 mois",
+ "sku": "4000_4000_4000_4000_12_X_ZEURA_X",
+ "debit": 4000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 742.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "ca32dae5-ef24-42dc-a6fb-6e0fd78d856c",
+ "variant_id": "9fa4e864-e9bd-4586-aa5d-5f547c435856",
+ "name": "ZEURA FTTO 100 Mbit/s 36 mois",
+ "sku": "100_100_100_100_36_X_ZEURA_X",
+ "debit": 100.0,
+ "access_fee": 530.0,
+ "recurring_price": 212.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "108a04fe-c067-4b6a-ac30-b82351c88085",
+ "variant_id": "ad725006-8ec3-48a3-b8f6-a0f5467d4dd7",
+ "name": "ZEURA FTTO 3 Gbit/s 48 mois",
+ "sku": "3000_3000_3000_3000_48_X_ZEURA_X",
+ "debit": 3000.0,
+ "access_fee": 0.0,
+ "recurring_price": 636.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "ad1818d6-75a2-40db-abe7-3b1820c7c863",
+ "variant_id": "b194207f-3c0a-4cbf-8eb9-11f3d31f528c",
+ "name": "ZEURA FTTO 10 Mbit/s 36 mois",
+ "sku": "10_10_10_10_36_X_ZEURA_X",
+ "debit": 10.0,
+ "access_fee": 530.0,
+ "recurring_price": 159.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a1ffc7de-a7ef-42cc-b738-b62e589c37fa",
+ "variant_id": "bf545f07-a5fd-4bde-b442-028c649b012a",
+ "name": "ZEURA FTTO 10 Mbit/s 12 mois",
+ "sku": "10_10_10_10_12_X_ZEURA_X",
+ "debit": 10.0,
+ "access_fee": 1590.0,
+ "recurring_price": 159.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "fe1164d2-d7fb-42c5-a64e-b6c54b6498a7",
+ "variant_id": "c08a4257-a842-4aa0-afec-4bb1794a5848",
+ "name": "ZEURA FTTO 50 Mbit/s 36 mois",
+ "sku": "50_50_50_50_36_X_ZEURA_X",
+ "debit": 50.0,
+ "access_fee": 530.0,
+ "recurring_price": 185.5,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "892c3955-bf81-49cb-9f24-942eb0e45c4e",
+ "variant_id": "c1fd7350-dfac-402c-8a9f-9fec206bd254",
+ "name": "ZEURA FTTO 200 Mbit/s 36 mois",
+ "sku": "200_200_200_200_36_X_ZEURA_X",
+ "debit": 200.0,
+ "access_fee": 530.0,
+ "recurring_price": 265.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "fb02d858-da5c-4b19-81a1-5b7aeae59c6d",
+ "variant_id": "c29238ba-e593-48d5-a270-799240f20932",
+ "name": "ZEURA FTTO 100 Mbit/s 24 mois",
+ "sku": "100_100_100_100_24_X_ZEURA_X",
+ "debit": 100.0,
+ "access_fee": 795.0,
+ "recurring_price": 212.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "700b355a-9164-4924-af37-db69bf022d03",
+ "variant_id": "cc81c63b-abc3-48fd-86fe-f4a5247ab242",
+ "name": "ZEURA FTTO 1 Gbit/s 12 mois",
+ "sku": "1000_1000_1000_1000_12_X_ZEURA_X",
+ "debit": 1000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 371.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1177df0f-a225-48e9-9754-ca2c49a2d172",
+ "variant_id": "cea5606e-5a59-4ff8-99c8-9e5a295146ae",
+ "name": "ZEURA FTTO 5 Gbit/s 48 mois",
+ "sku": "5000_5000_5000_5000_48_X_ZEURA_X",
+ "debit": 5000.0,
+ "access_fee": 0.0,
+ "recurring_price": 848.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "d9f40264-7baf-42da-9550-71121ae84142",
+ "variant_id": "cf61108d-6296-43b1-afdd-286b61d95471",
+ "name": "ZEURA FTTO 5 Gbit/s 24 mois",
+ "sku": "5000_5000_5000_5000_24_X_ZEURA_X",
+ "debit": 5000.0,
+ "access_fee": 795.0,
+ "recurring_price": 848.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "392998a2-af68-4d26-a64b-27da3f53cef6",
+ "variant_id": "d2d170dd-4b67-48fb-af5d-93d88f2e5aa6",
+ "name": "ZEURA FTTO 50 Mbit/s 12 mois",
+ "sku": "50_50_50_50_12_X_ZEURA_X",
+ "debit": 50.0,
+ "access_fee": 1590.0,
+ "recurring_price": 185.5,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "43e4887d-5281-48ae-a139-67c09c492d08",
+ "variant_id": "df51ab5d-0e19-4491-b748-3f8376640951",
+ "name": "ZEURA FTTO 1 Gbit/s 24 mois",
+ "sku": "1000_1000_1000_1000_24_X_ZEURA_X",
+ "debit": 1000.0,
+ "access_fee": 795.0,
+ "recurring_price": 371.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "e8da83fa-e4e3-43e7-918b-628595fd866e",
+ "variant_id": "e5e267d8-0d7b-4f8c-a16b-d8aa1add33cd",
+ "name": "ZEURA FTTO 200 Mbit/s 24 mois",
+ "sku": "200_200_200_200_24_X_ZEURA_X",
+ "debit": 200.0,
+ "access_fee": 795.0,
+ "recurring_price": 265.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "442a2821-722e-4ea4-b4b1-b8b135e2125c",
+ "variant_id": "f1cde63b-577d-40dd-b47a-935bd50a69f1",
+ "name": "ZEURA FTTO 5 Gbit/s 36 mois",
+ "sku": "5000_5000_5000_5000_36_X_ZEURA_X",
+ "debit": 5000.0,
+ "access_fee": 530.0,
+ "recurring_price": 848.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4e42ddd1-7c0c-4b55-bc34-0e1488034d97",
+ "variant_id": "f4d86621-03c3-4005-9712-a35d45662720",
+ "name": "ZEURA FTTO 4 Gbit/s 36 mois",
+ "sku": "4000_4000_4000_4000_36_X_ZEURA_X",
+ "debit": 4000.0,
+ "access_fee": 530.0,
+ "recurring_price": 742.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "d9e27c94-434e-430b-ab21-367f2e63ccf1",
+ "variant_id": "f5661047-2e64-4397-9712-a44b12e3ef24",
+ "name": "ZEURA FTTO 10 Gbit/s 12 mois",
+ "sku": "10000_10000_10000_10000_12_X_ZEURA_X",
+ "debit": 10000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 1060.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "ef605b53-a54b-4520-9153-f8c636dbabe2",
+ "variant_id": "00a53ef5-b6df-41b7-8a39-09cdf5427472",
+ "name": "ZEURA FTTO 10 Gbit/s 24 mois",
+ "sku": "10000_10000_10000_10000_24_X_ZEURA_X",
+ "debit": 10000.0,
+ "access_fee": 795.0,
+ "recurring_price": 1060.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "3359bb6a-2f5f-4351-af4c-8ed22c3f0097",
+ "variant_id": "07b699dd-06fc-4bc3-9f26-a256d84cdf5a",
+ "name": "ZEURA FTTO 2 Gbit/s 48 mois",
+ "sku": "2000_2000_2000_2000_48_X_ZEURA_X",
+ "debit": 2000.0,
+ "access_fee": 0.0,
+ "recurring_price": 530.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "be557db0-662e-41b8-9e99-57cdf77efa4e",
+ "variant_id": "1608fcd5-8e4d-4927-b2c3-0a969967ecb1",
+ "name": "ZEURA FTTO 3 Gbit/s 12 mois",
+ "sku": "3000_3000_3000_3000_12_X_ZEURA_X",
+ "debit": 3000.0,
+ "access_fee": 1590.0,
+ "recurring_price": 636.0,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "c57caf50-4ecb-49ac-8ac1-a8d38d4a25c8",
+ "variant_id": "18204b93-90a2-4fea-8d00-d3cdde149f7f",
+ "name": "ZEURA FTTO 500 Mbit/s 36 mois",
+ "sku": "500_500_500_500_36_X_ZEURA_X",
+ "debit": 500.0,
+ "access_fee": 530.0,
+ "recurring_price": 291.5,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "2be5f02c-b544-4b98-a8f1-bbbfe69e7bfd",
+ "variant_id": "1879ab8d-e5a9-4626-960e-45df8a75aeb9",
+ "name": "ZEURA FTTO 10 Mbit/s 48 mois",
+ "sku": "10_10_10_10_48_X_ZEURA_X",
+ "debit": 10.0,
+ "access_fee": 0.0,
+ "recurring_price": 159.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "cedf923b-4c64-47e0-9fbe-725f2c9b9940",
+ "variant_id": "19d5cf73-29e6-407f-b777-20ac38f0afd6",
+ "name": "ZEURA FTTO 2 Gbit/s 36 mois",
+ "sku": "2000_2000_2000_2000_36_X_ZEURA_X",
+ "debit": 2000.0,
+ "access_fee": 530.0,
+ "recurring_price": 530.0,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "281106c3-cde2-4197-8a06-0311fd6804f6",
+ "variant_id": "1e7365db-f346-40d5-a431-f834501f7dc4",
+ "name": "ZEURA FTTO 10 Gbit/s 48 mois",
+ "sku": "10000_10000_10000_10000_48_X_ZEURA_X",
+ "debit": 10000.0,
+ "access_fee": 0.0,
+ "recurring_price": 1060.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "fe770cfc-9c59-414e-98fb-818d98442e65",
+ "variant_id": "1ed0d88c-82b0-4cb4-8a5f-5381047eefb8",
+ "name": "ZEURA FTTO 500 Mbit/s 12 mois",
+ "sku": "500_500_500_500_12_X_ZEURA_X",
+ "debit": 500.0,
+ "access_fee": 1590.0,
+ "recurring_price": 291.5,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "919ac3a9-cd63-4183-b289-d2618ada997f",
+ "variant_id": "1f0c5c14-daa0-4b5b-bcdd-b04cafe3b252",
+ "name": "ZEURA FTTO 500 Mbit/s 48 mois",
+ "sku": "500_500_500_500_48_X_ZEURA_X",
+ "debit": 500.0,
+ "access_fee": 0.0,
+ "recurring_price": 291.5,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4278983a-0468-4d39-806b-6b824f49292a",
+ "variant_id": "21051a82-3674-47ee-b454-06e3d8d77850",
+ "name": "ZEURA FTTO 4 Gbit/s 24 mois",
+ "sku": "4000_4000_4000_4000_24_X_ZEURA_X",
+ "debit": 4000.0,
+ "access_fee": 795.0,
+ "recurring_price": 742.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "73fa80c8-0f72-45a4-acde-e1131433677e",
+ "variant_id": "217ced4e-09b4-404d-91af-325b1af016bc",
+ "name": "ZEURA FTTO 50 Mbit/s 24 mois",
+ "sku": "50_50_50_50_24_X_ZEURA_X",
+ "debit": 50.0,
+ "access_fee": 795.0,
+ "recurring_price": 185.5,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "b2acbd45-025b-48db-87ff-4b1c6f43e381",
+ "variant_id": "225fb7fb-ebfb-4348-83d4-0dbeaf670b61",
+ "name": "ZEURA FTTO 10 Mbit/s 24 mois",
+ "sku": "10_10_10_10_24_X_ZEURA_X",
+ "debit": 10.0,
+ "access_fee": 795.0,
+ "recurring_price": 159.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "2a55bedf-7288-4ac7-9d28-c5513e0945b1",
+ "variant_id": "23b7ec6b-49bd-4aca-a3d1-95591d6e33b3",
+ "name": "ZEURA FTTO 3 Gbit/s 24 mois",
+ "sku": "3000_3000_3000_3000_24_X_ZEURA_X",
+ "debit": 3000.0,
+ "access_fee": 795.0,
+ "recurring_price": 636.0,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4da5cf64-2641-428e-847e-b291a24c6a02",
+ "variant_id": "29f0aa19-89b3-442c-ae83-636f63dd9117",
+ "name": "ZEURA FTTO 4 Gbit/s 48 mois",
+ "sku": "4000_4000_4000_4000_48_X_ZEURA_X",
+ "debit": 4000.0,
+ "access_fee": 0.0,
+ "recurring_price": 742.0,
+ "commitment_duration": 48,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ }
+ ],
+ "category": "ftto"
+ },
+ {
+ "eligibility_id": "8a96ca15-6294-4853-8951-97453c3bf125",
+ "resolver": "covage-ftto",
+ "product_id": "e2133b92-114e-41c8-b3b5-009f7889ff17",
+ "contract_version_id": "abd0a0ba-4dd6-42bb-8bdf-97df751505ef",
+ "product_name": "FTTO BPE",
+ "service_operator": "Netwo",
+ "service_operator_slug": "netwo",
+ "infrastructure_operator": "Covage",
+ "infrastructure_operator_slug": "kosc",
+ "infrastructure_type": "ftto",
+ "entities": [
+ {
+ "entity_id": "4b02ed27-7f1f-4b55-ac71-e9f0725ce114",
+ "variant_id": "015f8281-b8ea-4120-8543-eabd7b0b1ca0",
+ "name": "FTTO Tr\u00e8s dense 5 4 Gbit/s 12 mois",
+ "sku": "4000_4000_4000_4000_12_X_TRESDENSE5_X",
+ "debit": 4000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 540.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "c8a2afe9-ceff-4ed6-a2e4-632930cac34c",
+ "variant_id": "17d6289e-f314-4e9c-af89-151e9b7244f3",
+ "name": "FTTO Tr\u00e8s dense 5 10 Gbit/s 36 mois",
+ "sku": "10000_10000_10000_10000_36_X_TRESDENSE5_X",
+ "debit": 10000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 726.1,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "44f7d597-27bc-4e87-a308-8a8eef950992",
+ "variant_id": "18b29c68-b2bc-4659-bf4c-434f6e7da679",
+ "name": "FTTO Tr\u00e8s dense 5 100 Mbit/s 24 mois",
+ "sku": "100_100_100_100_24_X_TRESDENSE5_X",
+ "debit": 100.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 159.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a633ec96-6d96-4841-81ca-a654f1974af0",
+ "variant_id": "22bc3acd-fbdb-411c-8b0f-f9825ee4e48c",
+ "name": "FTTO Tr\u00e8s dense 5 4 Mbit/s 12 mois",
+ "sku": "4_4_4_4_12_X_TRESDENSE5_X",
+ "debit": 4.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 76.32,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4322cefc-a774-4cb5-b7de-962c60fe16dc",
+ "variant_id": "25ed9e8c-6d1e-4c49-8788-b6e55a2d0a1c",
+ "name": "FTTO Tr\u00e8s dense 5 40 Mbit/s 36 mois",
+ "sku": "40_40_40_40_36_X_TRESDENSE5_X",
+ "debit": 40.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 159.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f83dcacc-0d2f-426b-83b0-d264b0477953",
+ "variant_id": "30c2c9a0-884a-437b-bf14-25732fdfd932",
+ "name": "FTTO Tr\u00e8s dense 5 100 Mbit/s 36 mois",
+ "sku": "100_100_100_100_36_X_TRESDENSE5_X",
+ "debit": 100.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 159.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1be2a22e-6b57-471e-b2ba-f038155f419a",
+ "variant_id": "33147b3e-232e-48fb-a064-f6c28c7f7179",
+ "name": "FTTO Tr\u00e8s dense 5 2 Gbit/s 36 mois",
+ "sku": "2000_2000_2000_2000_36_X_TRESDENSE5_X",
+ "debit": 2000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 455.8,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "6afe322d-b764-4983-9f67-1dc221719c2f",
+ "variant_id": "3fcbec45-ed07-4611-9771-facc0537cf5b",
+ "name": "FTTO Tr\u00e8s dense 5 40 Mbit/s 24 mois",
+ "sku": "40_40_40_40_24_X_TRESDENSE5_X",
+ "debit": 40.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 159.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "e35c86cb-d456-4966-9298-306e2bd5c319",
+ "variant_id": "435682c0-250f-49e2-b051-c88209d3ebc2",
+ "name": "FTTO Tr\u00e8s dense 5 200 Mbit/s 24 mois",
+ "sku": "200_200_200_200_24_X_TRESDENSE5_X",
+ "debit": 200.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 265.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "a213d3bb-81fb-4852-9983-df84d6894679",
+ "variant_id": "5641829f-f9db-473b-aa72-8e8807b0c208",
+ "name": "FTTO Tr\u00e8s dense 5 10 Mbit/s 12 mois",
+ "sku": "10_10_10_10_12_X_TRESDENSE5_X",
+ "debit": 10.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 106.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "17818c17-1112-4c41-bee6-d91abedf9f16",
+ "variant_id": "58bebd92-8dba-46bc-a8ed-a247fbf7f059",
+ "name": "FTTO Tr\u00e8s dense 5 4 Mbit/s 24 mois",
+ "sku": "4_4_4_4_24_X_TRESDENSE5_X",
+ "debit": 4.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 76.32,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "c9eb50c5-7157-459c-9ede-7a9ddc8d92a6",
+ "variant_id": "5fc58d6a-0107-479d-8289-a11d57a8f3d1",
+ "name": "FTTO Tr\u00e8s dense 5 100 Mbit/s 12 mois",
+ "sku": "100_100_100_100_12_X_TRESDENSE5_X",
+ "debit": 100.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 159.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "4945b16f-4223-4d39-bd38-d1809ee1fb2c",
+ "variant_id": "60a94c59-1361-4d91-8cc7-8ab190cdf051",
+ "name": "FTTO Tr\u00e8s dense 5 1 Gbit/s 36 mois",
+ "sku": "1000_1000_1000_1000_36_X_TRESDENSE5_X",
+ "debit": 1000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 318.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "304482b0-3cb1-47cc-8083-e8d95b774070",
+ "variant_id": "68724c29-5548-4c39-8b34-72b23bfa5a46",
+ "name": "FTTO Tr\u00e8s dense 5 20 Mbit/s 36 mois",
+ "sku": "20_20_20_20_36_X_TRESDENSE5_X",
+ "debit": 20.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 159.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "33d576a3-f687-4b6b-a131-7b8f92f352cb",
+ "variant_id": "6dec603c-f283-44fb-9da7-584b98095f5a",
+ "name": "FTTO Tr\u00e8s dense 5 4 Gbit/s 36 mois",
+ "sku": "4000_4000_4000_4000_36_X_TRESDENSE5_X",
+ "debit": 4000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 540.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "0ba11ba9-3efe-496f-b091-8489a3f29fca",
+ "variant_id": "8372ad28-8fba-4f4b-b911-09f3b617866a",
+ "name": "FTTO Tr\u00e8s dense 5 1 Gbit/s 12 mois",
+ "sku": "1000_1000_1000_1000_12_X_TRESDENSE5_X",
+ "debit": 1000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 318.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "6af02253-8e15-4cbd-8db7-0e15781dc18d",
+ "variant_id": "8853cded-39f5-4595-91b1-833213695c67",
+ "name": "FTTO Tr\u00e8s dense 5 200 Mbit/s 12 mois",
+ "sku": "200_200_200_200_12_X_TRESDENSE5_X",
+ "debit": 200.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 265.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "74e61a69-bc4f-47f1-b9b0-81a95aa09010",
+ "variant_id": "9575ea3e-edf1-4ab9-8556-06d69329ec4b",
+ "name": "FTTO Tr\u00e8s dense 5 4 Mbit/s 36 mois",
+ "sku": "4_4_4_4_36_X_TRESDENSE5_X",
+ "debit": 4.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 76.32,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "5fadadf4-1f97-4047-ae43-e9e330d47e74",
+ "variant_id": "95ce7584-b7be-430e-bb60-c6ed9e5a6b6a",
+ "name": "FTTO Tr\u00e8s dense 5 10 Gbit/s 24 mois",
+ "sku": "10000_10000_10000_10000_24_X_TRESDENSE5_X",
+ "debit": 10000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 726.1,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "ed6a0dde-8d36-4b24-a582-dc67fa191dd7",
+ "variant_id": "9a7e5219-d651-48b8-bc12-becb063567bd",
+ "name": "FTTO Tr\u00e8s dense 5 500 Mbit/s 12 mois",
+ "sku": "500_500_500_500_12_X_TRESDENSE5_X",
+ "debit": 500.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 296.8,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "238a087d-cd86-4e6e-8686-c2fa9ac86dd5",
+ "variant_id": "9b385fce-2a1e-4dd7-9ce9-064c94cc7a95",
+ "name": "FTTO Tr\u00e8s dense 5 200 Mbit/s 36 mois",
+ "sku": "200_200_200_200_36_X_TRESDENSE5_X",
+ "debit": 200.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 265.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "f1fa7909-cad4-4245-9a5f-53aba06b1414",
+ "variant_id": "a67d6e22-53bf-4587-8c2f-8010d0de2c95",
+ "name": "FTTO Tr\u00e8s dense 5 10 Mbit/s 24 mois",
+ "sku": "10_10_10_10_24_X_TRESDENSE5_X",
+ "debit": 10.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 106.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "8eef3d36-8951-45e2-885e-5a559c1dc9fc",
+ "variant_id": "ac4f02e5-7348-4dd7-8eb4-384609b2ae29",
+ "name": "FTTO Tr\u00e8s dense 5 4 Gbit/s 24 mois",
+ "sku": "4000_4000_4000_4000_24_X_TRESDENSE5_X",
+ "debit": 4000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 540.6,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "2eca765d-6330-4583-b018-3672103fc5a7",
+ "variant_id": "cae72336-1a49-4c21-a9d0-50dd93e54bbb",
+ "name": "FTTO Tr\u00e8s dense 5 10 Gbit/s 12 mois",
+ "sku": "10000_10000_10000_10000_12_X_TRESDENSE5_X",
+ "debit": 10000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 726.1,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "9a00de68-15a6-4640-bf4d-372442513504",
+ "variant_id": "d7a9748d-faac-462f-aa76-2bb1f6e54eb8",
+ "name": "FTTO Tr\u00e8s dense 5 20 Mbit/s 12 mois",
+ "sku": "20_20_20_20_12_X_TRESDENSE5_X",
+ "debit": 20.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 159.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "aeeefd49-999c-4ee1-99b2-f95b3d9e0456",
+ "variant_id": "da6d62c8-2036-425b-969d-0b537ff06a4c",
+ "name": "FTTO Tr\u00e8s dense 5 2 Gbit/s 24 mois",
+ "sku": "2000_2000_2000_2000_24_X_TRESDENSE5_X",
+ "debit": 2000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 455.8,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "1c3c0231-77b9-497b-aacf-ad303341ab43",
+ "variant_id": "dc91347e-2b9a-4576-b994-d90fd423f47a",
+ "name": "FTTO Tr\u00e8s dense 5 500 Mbit/s 24 mois",
+ "sku": "500_500_500_500_24_X_TRESDENSE5_X",
+ "debit": 500.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 296.8,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "6122e975-2c1d-4e81-8894-6a46be6b3d14",
+ "variant_id": "e43fb257-6ec1-4233-985d-a5924fed4212",
+ "name": "FTTO Tr\u00e8s dense 5 1 Gbit/s 24 mois",
+ "sku": "1000_1000_1000_1000_24_X_TRESDENSE5_X",
+ "debit": 1000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 318.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "188beb8e-d9f3-442c-a203-6ec537a3036a",
+ "variant_id": "e80d7f2b-2afd-4dc9-9ce7-a4faa967714b",
+ "name": "FTTO Tr\u00e8s dense 5 2 Gbit/s 12 mois",
+ "sku": "2000_2000_2000_2000_12_X_TRESDENSE5_X",
+ "debit": 2000.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 455.8,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "148c0bbb-18ab-432f-abed-49eb6a27af50",
+ "variant_id": "ed2b509e-d190-4f5a-a179-f5c2e0cfa7f9",
+ "name": "FTTO Tr\u00e8s dense 5 20 Mbit/s 24 mois",
+ "sku": "20_20_20_20_24_X_TRESDENSE5_X",
+ "debit": 20.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 159.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 24,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "de0191be-cbbb-4bba-b48f-5532fce1bd31",
+ "variant_id": "f40842ea-c326-46d3-b6c0-d8a34fb980e3",
+ "name": "FTTO Tr\u00e8s dense 5 40 Mbit/s 12 mois",
+ "sku": "40_40_40_40_12_X_TRESDENSE5_X",
+ "debit": 40.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 159.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 12,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "06548a2b-ad1a-41c7-a1c1-54b534f5a43b",
+ "variant_id": "f5d3191e-aed0-4466-9df5-aec48ad8c03b",
+ "name": "FTTO Tr\u00e8s dense 5 500 Mbit/s 36 mois",
+ "sku": "500_500_500_500_36_X_TRESDENSE5_X",
+ "debit": 500.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 296.8,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ },
+ {
+ "entity_id": "35fdd0b0-5ea3-4841-a04b-16c060f34865",
+ "variant_id": "012c139b-7af6-4614-b0c6-cb6a3a006b5c",
+ "name": "FTTO Tr\u00e8s dense 5 10 Mbit/s 36 mois",
+ "sku": "10_10_10_10_36_X_TRESDENSE5_X",
+ "debit": 10.0,
+ "access_fee": 0.0,
+ "access_fee_on_quotation": true,
+ "recurring_price": 106.0,
+ "recurring_price_on_quotation": false,
+ "commitment_duration": 36,
+ "recovery_time_guaranteed_delay": "PT4H",
+ "recovery_time_guaranteed_applicability": "working_days",
+ "preferred_offer": false,
+ "delivery_protocol": "l2"
+ }
+ ],
+ "category": "ftto"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/webapp/eligibility_api/api_doc.py b/webapp/eligibility_api/api_doc.py
new file mode 100644
index 0000000..9c5ebbd
--- /dev/null
+++ b/webapp/eligibility_api/api_doc.py
@@ -0,0 +1,56 @@
+from apispec.ext.marshmallow import MarshmallowPlugin
+from apispec_webframeworks.flask import FlaskPlugin
+
+from flasgger import APISpec, Schema, Swagger, fields
+
+from eligibility_api.elig_api_exceptions import SwaggerValidationException
+
+
+def _swagger_validation_error_handler(err, data, _):
+ print("API swagger error 400")
+ raise SwaggerValidationException(err, data)
+
+
+def start_swagger(flask_app):
+ """
+ Creates swagger /apidocs endpoint and adds it to flask app
+ """
+
+ flask_app.config["SWAGGER"] = {
+ "uiversion": 3,
+ "ui_params": {
+ "apisSorter": "alpha",
+ "operationsSorter": "alpha",
+ "tagsSorter": "alpha",
+ },
+ }
+
+ # Create an APISpec
+ spec = APISpec(
+ title="API éligibilité",
+ version="0.1.0",
+ openapi_version="2.0",
+ plugins=(
+ FlaskPlugin(),
+ MarshmallowPlugin(),
+ ),
+ )
+
+ template = spec.to_flasgger(
+ flask_app,
+ definitions=[
+ # ContributionSchema,
+ # PredictConfigSchema,
+ # VersionSchema,
+ # PredictInputsSchema,
+ # ImplementedModelSchema,
+ # ApiErrorSchema,
+ # LoggingHealthCheckSchema,
+ ],
+ )
+ Swagger(
+ flask_app,
+ template=template,
+ parse=True,
+ validation_error_handler=_swagger_validation_error_handler,
+ )
diff --git a/webapp/eligibility_api/elig_api_exceptions.py b/webapp/eligibility_api/elig_api_exceptions.py
index f5f8be3..6d9862c 100644
--- a/webapp/eligibility_api/elig_api_exceptions.py
+++ b/webapp/eligibility_api/elig_api_exceptions.py
@@ -23,6 +23,18 @@ class NetwoApiErrorException(Exception):
self.description = description
+class SwaggerValidationException(Exception):
+ """
+ Exception thrown if API misused
+ """
+
+ def __init__(self, err, data):
+ self.code = 400
+ self.name = "Error from Swagger API validation"
+ self.description = str(err)
+ self.data = data
+
+
class FlaskExceptions:
"""
Manages flask custom exceptions
@@ -61,3 +73,17 @@ class FlaskExceptions:
),
500,
)
+
+ @self.flask_app.errorhandler(SwaggerValidationException)
+ def handle_exception(e):
+ return (
+ jsonify(
+ {
+ "code": e.code,
+ "name": e.name,
+ "description": e.description,
+ "data": e.data,
+ }
+ ),
+ 400,
+ )
diff --git a/webapp/eligibility_api/elig_api_routes.py b/webapp/eligibility_api/elig_api_routes.py
index 563bc27..1ff6560 100644
--- a/webapp/eligibility_api/elig_api_routes.py
+++ b/webapp/eligibility_api/elig_api_routes.py
@@ -2,9 +2,8 @@ from flask import Flask, request
from coordinates import check_coordinates_args, adapt_coordinates_to_max_area
from eligibility_api.elig_api_exceptions import ApiParamException
-from ipe_fetcher import NetwooEligibility, FAIEligibilityStatus
from ipe_fetcher.axione import AXIONE_MAX_AREA, Axione
-from netwo.netwo import Netwo
+from netwo.netwo import Netwo, NetwooEligibility, NETWO_DEPLOYED_STATUS
class EligibilityApiRoutes:
@@ -39,30 +38,92 @@ class EligibilityApiRoutes:
@self.flask_app.route("/eligibilite/netwo", methods=["GET"])
def get_netwo_eligibility():
+ """
+ Intérroge l'éligibilité Netwo
+ ---
+ tags:
+ - API
+ description: |
+ Déclenche une recherche d'éligibilité chez Netwo:
+ - soit par une ref d'immeuble
+ - soit par les coordonnées d'un immeuble
+ La recherche est longue, l'API renvoie un event stream qui renvoie un statut toutes les secondes
+ Il est possible de retrouver les résultats d'une éligibilité via son ID.
+ Par défaut on renvoie uniquement les offres ftth, il est possible via ftto=true d'ajouter la ftto
+ parameters:
+ - in: query
+ name: ftto
+ required: false
+ schema:
+ type: boolean
+ nullable: true
+ allowEmptyValue: true
+ description: |
+ Si 'ftto' set alors on rajoutera les résultats FTTO à la recherche
+ - in: query
+ name: timeout_sec
+ required: false
+ schema:
+ type: int
+ nullable: false
+ allowEmptyValue: false
+ description: |
+ Timeout au bout du quel on retourne les offres trouvées même si la recherche n'est pas terminée
+ responses:
+ 200:
+ description: Retourne le statut d'éligibilité et d'éventuelles offres
+ schema:
+ $ref: '#/definitions/Contribution'
+ examples:
+ application/json:
+ 400:
+ description: Bad inputs
+ schema:
+ $ref: '#/definitions/ApiError'
+ examples:
+ application/json:
+ code: 400
+ name: Bad input parameter
+ description: Bad json format
+ 500:
+ description: Erreur lors d'un appel à l'API de Netwo
+ schema:
+ $ref: '#/definitions/ApiError'
+ examples:
+ application/json:
+ netwo_status_code: 404
+ name: Error contacting Netwo API
+ description: ID not found
+ """
args = request.args
ref_imb = args.get("ref_imb")
- lat = args.get("lat")
- lng = args.get("lng")
+ elig_id = args.get("id")
timeout_sec = None
- search_ftto = args.get("ftto", "False").lower() == "true"
+ search_ftto = args.get("ftto") is not None
+
+ imb_info = self.netwo.get_netwo_imb_coordinates(ref_imb)
+ if elig_id:
+ elig_offers = self.netwo.get_netwo_eligibility_results(
+ elig_id, search_ftto
+ )
+ return NetwooEligibility(
+ imb_info=imb_info,
+ eligOffers=elig_offers,
+ eligDone=True,
+ elig_id=elig_id,
+ )
+
if args.get("timeout_sec"):
try:
timeout_sec = int(args.get("timeout_sec"))
except ValueError:
raise ApiParamException("timeout_sec param must be an integer")
- elig_status = (
- FAIEligibilityStatus(
- isEligible=True, ftthStatus="Deployed", reasonNotEligible=""
- ),
- )
- if ref_imb:
- elig_status, lat, lng = self.netwo.get_netwo_imb_coordinates(
- args["ref_imb"]
+
+ if imb_info.get("imb_status") != NETWO_DEPLOYED_STATUS:
+ return NetwooEligibility(
+ imb_info=imb_info,
)
- if not elig_status.get("isEligible"):
- return NetwooEligibility(
- eligStatus=elig_status,
- )
+ print(f"start elig with {imb_info}")
return self.netwo.start_netwo_eligibility(
- lat, lng, elig_status, search_ftto, timeout_sec
+ imb_info, search_ftto, timeout_sec
)
diff --git a/webapp/ipe_fetcher/model.py b/webapp/ipe_fetcher/model.py
index 9e4853d..11e59e7 100644
--- a/webapp/ipe_fetcher/model.py
+++ b/webapp/ipe_fetcher/model.py
@@ -30,15 +30,3 @@ class AreaCoordinates(TypedDict):
swy: float
nex: float
ney: float
-
-
-class NetwooEligibility(TypedDict):
- eligStatus: FAIEligibilityStatus
- eligDone: NotRequired[bool]
- nbOperatorsOk: NotRequired[int]
- nbOperatorsErrors: NotRequired[int]
- nbOperatorsPending: NotRequired[int]
- totalOperators: NotRequired[int]
- timeoutSec: NotRequired[int]
- timeoutReached: NotRequired[bool]
- eligOffers: NotRequired[dict]
diff --git a/webapp/main.py b/webapp/main.py
index f398107..9b9b62e 100644
--- a/webapp/main.py
+++ b/webapp/main.py
@@ -4,6 +4,7 @@ from typing import TypedDict
from flask import Flask, request, render_template, redirect
+from eligibility_api.api_doc import start_swagger
from eligibility_api.elig_api_exceptions import FlaskExceptions
from eligibility_api.elig_api_routes import EligibilityApiRoutes
from ipe_fetcher import Liazo, Axione, Arcep, AreaCoordinates
@@ -102,3 +103,6 @@ def testFtth():
liazoOk = args["liazo"]
pto_url = f"https://tools.aquilenet.fr/cgi-bin/recherchepto.cgi?refimmeuble={idImm}&cp={codePostal}&axione={axioneOk}&liazo={liazoOk}"
return redirect(pto_url)
+
+
+# start_swagger(app)
diff --git a/webapp/netwo/netwo.py b/webapp/netwo/netwo.py
index bccfb90..f98b073 100644
--- a/webapp/netwo/netwo.py
+++ b/webapp/netwo/netwo.py
@@ -3,13 +3,27 @@ import requests
import time
import json
from urllib.parse import quote
+from typing_extensions import NotRequired, TypedDict
from eligibility_api.elig_api_exceptions import NetwoApiErrorException
-from ipe_fetcher import FAIEligibilityStatus, NetwooEligibility
+from ipe_fetcher import FAIEligibilityStatus
NETWO_DEPLOYED_STATUS = "Deployed"
+class NetwooEligibility(TypedDict):
+ imb_info: NotRequired[dict]
+ eligDone: NotRequired[bool]
+ eligId: NotRequired[str]
+ nbOperatorsOk: NotRequired[int]
+ nbOperatorsErrors: NotRequired[int]
+ nbOperatorsPending: NotRequired[int]
+ totalOperators: NotRequired[int]
+ timeoutSec: NotRequired[int]
+ timeoutReached: NotRequired[bool]
+ eligOffers: NotRequired[dict]
+
+
class Netwo:
def __init__(self, netwo_api_key: str):
self.netwo_api_headers = {
@@ -18,9 +32,7 @@ class Netwo:
"Accept": "application/json",
}
- def get_netwo_imb_coordinates(
- self, ref_imb: str
- ) -> (FAIEligibilityStatus, str, str):
+ def get_netwo_imb_coordinates(self, ref_imb: str) -> dict:
"""
:param ref_imb: ARCEP ref of immeuble
@@ -38,21 +50,7 @@ class Netwo:
f"Could not GET netwo imb ref {ref_imb}", status_code
)
imb_payload = response.json()
- imb_status = imb_payload.get("imb_status")
- elig_status = FAIEligibilityStatus(
- isEligible=imb_status == NETWO_DEPLOYED_STATUS,
- ftthStatus=imb_status,
- reasonNotEligible="",
- )
-
- if imb_status != NETWO_DEPLOYED_STATUS:
- elig_status[
- "reasonNotEligible"
- ] = f'Ftth not yet deployed in immeuble ref {ref_imb} (PM status: {imb_payload.get("pm_status")})'
-
- lat = str(response.json().get("lat"))
- lng = str(response.json().get("lng"))
- return elig_status, lat, lng
+ return imb_payload
@staticmethod
def _filter_netwo_raw_elig_results(raw_elig: dict, search_ftto: bool) -> list:
@@ -62,10 +60,8 @@ class Netwo:
inf_search.append("ftto")
for r in raw_elig.get("results"):
inf_type = r.get("infrastructure_type")
- print(f'{r.get("infrastructure_operator")} : {inf_type}')
if inf_type not in inf_search:
continue
- elig_id = r.get("eligibility_id")
product_id = r.get("product_id")
operator = r.get("infrastructure_operator")
product = r.get("product_name")
@@ -78,7 +74,6 @@ class Netwo:
commitment_duration = offer.get("commitment_duration") or 0
filtered_elig.append(
{
- "eligibility_id": elig_id,
"entity_id": entity_id,
"product_id": product_id,
"product": f"{product} - {offer_name}",
@@ -98,17 +93,28 @@ class Netwo:
)
return sort_elig
+ def get_netwo_eligibility_results(self, elig_id: str, search_ftto: bool):
+ response = requests.get(
+ f"https://api.netwo.io/api/v1/eligibility/{elig_id}",
+ headers=self.netwo_api_headers,
+ )
+ status_code = response.status_code
+ if status_code != 200:
+ raise NetwoApiErrorException(
+ f"Netwo API: Could not get eligibility results for ID {elig_id}",
+ status_code,
+ )
+ return self._filter_netwo_raw_elig_results(response.json(), search_ftto)
+
def start_netwo_eligibility(
self,
- imb_lat: str,
- imb_long: str,
- elig_status: FAIEligibilityStatus,
+ imb_info: str,
search_ftto: bool,
timeout_sec: None,
):
def event_stream():
netwo_elig = NetwooEligibility(
- eligStatus=elig_status,
+ eligId="",
eligDone=False,
nbOperatorsOk=0,
nbOperatorsErrors=0,
@@ -117,8 +123,11 @@ class Netwo:
timeoutSec=timeout_sec,
eligOffers={},
)
- json_data = {"latitude": imb_lat, "longitude": imb_long}
-
+ json_data = {
+ "latitude": str(imb_info.get("lat")),
+ "longitude": str(imb_info.get("lng")),
+ }
+ print(json_data)
response = requests.post(
"https://api.netwo.io/api/v1/eligibility/preselect",
headers=self.netwo_api_headers,
@@ -126,7 +135,7 @@ class Netwo:
)
status_code = response.status_code
if status_code != 200:
- print("raise preselect except")
+ print(f"raise preselect except {response.text}")
raise NetwoApiErrorException(
"Netwo API eligibility preselect step failed", status_code
)
@@ -134,6 +143,10 @@ class Netwo:
default = resp.get("default")
default["offer_type"] = "enterprise"
default["market"] = "service_operator"
+ default["ftth_payload"] = {
+ "imb_ref": imb_info.get("imb_id"),
+ "pm_ref": imb_info.get("pm_id"),
+ }
response = requests.post(
"https://api.netwo.io/api/v1/eligibility",
headers=self.netwo_api_headers,
@@ -146,6 +159,7 @@ class Netwo:
"Netwo API: failed to start eligibility", status_code
)
id_elig = response.json().get("id")
+ netwo_elig["eligId"] = id_elig
is_done = False
timeout = None
@@ -189,22 +203,11 @@ class Netwo:
else:
is_done = True
- response = requests.get(
- f"https://api.netwo.io/api/v1/eligibility/{id_elig}",
- headers=self.netwo_api_headers,
+ netwo_elig["eligOffers"] = self.get_netwo_eligibility_results(
+ id_elig, search_ftto
)
- status_code = response.status_code
- if status_code != 200:
- print("raise elig res except")
- raise NetwoApiErrorException(
- f"Netwo API: Could not get eligibility results for ID {id_elig}",
- status_code,
- )
- netwo_elig["eligOffers"] = self._filter_netwo_raw_elig_results(
- response.json(), search_ftto
- )
-
netwo_elig["eligDone"] = True
+ netwo_elig["imb_info"] = imb_info
yield json.dumps(netwo_elig, indent=2)
return Response(event_stream(), mimetype="text/event-stream")
diff --git a/webapp/poetry.lock b/webapp/poetry.lock
index 1066486..7db808c 100644
--- a/webapp/poetry.lock
+++ b/webapp/poetry.lock
@@ -1,3 +1,66 @@
+[[package]]
+name = "aniso8601"
+version = "9.0.1"
+description = "A library for parsing ISO 8601 strings."
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.extras]
+dev = ["black", "coverage", "isort", "pre-commit", "pyenchant", "pylint"]
+
+[[package]]
+name = "apispec"
+version = "6.1.0"
+description = "A pluggable API specification generator. Currently supports the OpenAPI Specification (f.k.a. the Swagger specification)."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+
+[package.dependencies]
+packaging = ">=21.3"
+PyYAML = {version = ">=3.10", optional = true, markers = "extra == \"yaml\""}
+
+[package.extras]
+dev = ["PyYAML (>=3.10)", "flake8 (==5.0.4)", "flake8-bugbear (==22.9.23)", "marshmallow (>=3.13.0)", "mypy (==0.982)", "openapi-spec-validator (<0.5)", "prance[osv] (>=0.11)", "pre-commit (>=2.4,<3.0)", "pytest", "tox", "types-PyYAML"]
+docs = ["marshmallow (>=3.13.0)", "pyyaml (==6.0)", "sphinx (==5.2.3)", "sphinx-issues (==3.0.1)", "sphinx-rtd-theme (==1.0.0)"]
+lint = ["flake8 (==5.0.4)", "flake8-bugbear (==22.9.23)", "mypy (==0.982)", "pre-commit (>=2.4,<3.0)", "types-PyYAML"]
+marshmallow = ["marshmallow (>=3.18.0)"]
+tests = ["PyYAML (>=3.10)", "marshmallow (>=3.13.0)", "openapi-spec-validator (<0.5)", "prance[osv] (>=0.11)", "pytest"]
+validation = ["openapi-spec-validator (<0.5)", "prance[osv] (>=0.11)"]
+yaml = ["PyYAML (>=3.10)"]
+
+[[package]]
+name = "apispec-webframeworks"
+version = "0.5.2"
+description = "Web framework plugins for apispec."
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
+[package.dependencies]
+apispec = {version = ">=2.0.0", extras = ["yaml"]}
+
+[package.extras]
+dev = ["Flask (==1.1.1)", "bottle (==0.12.17)", "flake8 (==3.7.9)", "flake8-bugbear (==19.8.0)", "mock", "pre-commit (>=1.18,<2.0)", "pytest", "tornado", "tox"]
+lint = ["flake8 (==3.7.9)", "flake8-bugbear (==19.8.0)", "pre-commit (>=1.18,<2.0)"]
+tests = ["Flask (==1.1.1)", "bottle (==0.12.17)", "mock", "pytest", "tornado"]
+
+[[package]]
+name = "attrs"
+version = "22.2.0"
+description = "Classes Without Boilerplate"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
+[package.extras]
+cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"]
+dev = ["attrs[docs,tests]"]
+docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"]
+tests = ["attrs[tests-no-zope]", "zope.interface"]
+tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"]
+
[[package]]
name = "black"
version = "23.1.0"
@@ -56,6 +119,21 @@ category = "main"
optional = false
python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
+[[package]]
+name = "flasgger"
+version = "0.9.5"
+description = "Extract swagger specs from your flask project"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+Flask = ">=0.10"
+jsonschema = ">=3.0.1"
+mistune = "*"
+PyYAML = ">=3.0"
+six = ">=1.10.0"
+
[[package]]
name = "flask"
version = "2.2.2"
@@ -75,6 +153,23 @@ Werkzeug = ">=2.2.2"
async = ["asgiref (>=3.2)"]
dotenv = ["python-dotenv"]
+[[package]]
+name = "flask-restful"
+version = "0.3.9"
+description = "Simple framework for creating REST APIs"
+category = "main"
+optional = false
+python-versions = "*"
+
+[package.dependencies]
+aniso8601 = ">=0.82"
+Flask = ">=0.8"
+pytz = "*"
+six = ">=1.3.0"
+
+[package.extras]
+docs = ["sphinx"]
+
[[package]]
name = "gunicorn"
version = "20.1.0"
@@ -138,6 +233,22 @@ MarkupSafe = ">=2.0"
[package.extras]
i18n = ["Babel (>=2.7)"]
+[[package]]
+name = "jsonschema"
+version = "4.17.3"
+description = "An implementation of JSON Schema validation for Python"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+
+[package.dependencies]
+attrs = ">=17.4.0"
+pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2"
+
+[package.extras]
+format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"]
+format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"]
+
[[package]]
name = "markupsafe"
version = "2.1.1"
@@ -146,6 +257,31 @@ category = "main"
optional = false
python-versions = ">=3.7"
+[[package]]
+name = "marshmallow"
+version = "3.19.0"
+description = "A lightweight library for converting complex datatypes to and from native Python datatypes."
+category = "main"
+optional = false
+python-versions = ">=3.7"
+
+[package.dependencies]
+packaging = ">=17.0"
+
+[package.extras]
+dev = ["flake8 (==5.0.4)", "flake8-bugbear (==22.10.25)", "mypy (==0.990)", "pre-commit (>=2.4,<3.0)", "pytest", "pytz", "simplejson", "tox"]
+docs = ["alabaster (==0.7.12)", "autodocsumm (==0.2.9)", "sphinx (==5.3.0)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"]
+lint = ["flake8 (==5.0.4)", "flake8-bugbear (==22.10.25)", "mypy (==0.990)", "pre-commit (>=2.4,<3.0)"]
+tests = ["pytest", "pytz", "simplejson"]
+
+[[package]]
+name = "mistune"
+version = "2.0.5"
+description = "A sane Markdown parser with useful plugins and renderers"
+category = "main"
+optional = false
+python-versions = "*"
+
[[package]]
name = "mypy-extensions"
version = "1.0.0"
@@ -190,6 +326,30 @@ python-versions = ">=3.7"
docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"]
test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"]
+[[package]]
+name = "pyrsistent"
+version = "0.19.3"
+description = "Persistent/Functional/Immutable data structures"
+category = "main"
+optional = false
+python-versions = ">=3.7"
+
+[[package]]
+name = "pytz"
+version = "2022.7.1"
+description = "World timezone definitions, modern and historical"
+category = "main"
+optional = false
+python-versions = "*"
+
+[[package]]
+name = "pyyaml"
+version = "6.0"
+description = "YAML parser and emitter for Python"
+category = "main"
+optional = false
+python-versions = ">=3.6"
+
[[package]]
name = "requests"
version = "2.28.2"
@@ -221,6 +381,14 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-g
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
+[[package]]
+name = "six"
+version = "1.16.0"
+description = "Python 2 and 3 compatibility utilities"
+category = "main"
+optional = false
+python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
+
[[package]]
name = "tomli"
version = "2.0.1"
@@ -279,9 +447,25 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools"
[metadata]
lock-version = "1.1"
python-versions = "^3.9"
-content-hash = "1f4a05abb33873e8733b0fc1945b4c1f2ffa4792eddb7edc3dd0007fd78522af"
+content-hash = "808253c094a03d4591f9504fee2876cfe5efe4b63ca89b47813fbc63e8cb7de7"
[metadata.files]
+aniso8601 = [
+ {file = "aniso8601-9.0.1-py2.py3-none-any.whl", hash = "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f"},
+ {file = "aniso8601-9.0.1.tar.gz", hash = "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973"},
+]
+apispec = [
+ {file = "apispec-6.1.0-py3-none-any.whl", hash = "sha256:937d7f11be6e80cf6d0b66c12dbc29604435302b529b3a9bdb5e2dee192d2f17"},
+ {file = "apispec-6.1.0.tar.gz", hash = "sha256:881d3b90bfffded659bc0a4bf09eadeedfa256cd271726b1555d75af9e0a9a69"},
+]
+apispec-webframeworks = [
+ {file = "apispec-webframeworks-0.5.2.tar.gz", hash = "sha256:0db35b267914b3f8c562aca0261957dbcb4176f255eacc22520277010818dcf3"},
+ {file = "apispec_webframeworks-0.5.2-py2.py3-none-any.whl", hash = "sha256:482c563abbcc2a261439476cb3f1a7c7284cc997c322c574d48c111643e9c04e"},
+]
+attrs = [
+ {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"},
+ {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"},
+]
black = [
{file = "black-23.1.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:b6a92a41ee34b883b359998f0c8e6eb8e99803aa8bf3123bf2b2e6fec505a221"},
{file = "black-23.1.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:57c18c5165c1dbe291d5306e53fb3988122890e57bd9b3dcb75f967f13411a26"},
@@ -411,10 +595,18 @@ colorama = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
+flasgger = [
+ {file = "flasgger-0.9.5-py2.py3-none-any.whl", hash = "sha256:0603941cf4003626b4ee551ca87331f1d17b8eecce500ccf1a1f1d3a332fc94a"},
+ {file = "flasgger-0.9.5.tar.gz", hash = "sha256:6ebea406b5beecd77e8da42550f380d4d05a6107bc90b69ce9e77aee7612e2d0"},
+]
flask = [
{file = "Flask-2.2.2-py3-none-any.whl", hash = "sha256:b9c46cc36662a7949f34b52d8ec7bb59c0d74ba08ba6cb9ce9adc1d8676d9526"},
{file = "Flask-2.2.2.tar.gz", hash = "sha256:642c450d19c4ad482f96729bd2a8f6d32554aa1e231f4f6b4e7e5264b16cca2b"},
]
+flask-restful = [
+ {file = "Flask-RESTful-0.3.9.tar.gz", hash = "sha256:ccec650b835d48192138c85329ae03735e6ced58e9b2d9c2146d6c84c06fa53e"},
+ {file = "Flask_RESTful-0.3.9-py2.py3-none-any.whl", hash = "sha256:4970c49b6488e46c520b325f54833374dc2b98e211f1b272bd4b0c516232afe2"},
+]
gunicorn = [
{file = "gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"},
{file = "gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"},
@@ -435,6 +627,10 @@ jinja2 = [
{file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"},
{file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"},
]
+jsonschema = [
+ {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"},
+ {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"},
+]
markupsafe = [
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:86b1f75c4e7c2ac2ccdaec2b9022845dbb81880ca318bb7a0a01fbf7813e3812"},
{file = "MarkupSafe-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f121a1420d4e173a5d96e47e9a0c0dcff965afdf1626d28de1460815f7c4ee7a"},
@@ -477,6 +673,14 @@ markupsafe = [
{file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"},
{file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"},
]
+marshmallow = [
+ {file = "marshmallow-3.19.0-py3-none-any.whl", hash = "sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b"},
+ {file = "marshmallow-3.19.0.tar.gz", hash = "sha256:90032c0fd650ce94b6ec6dc8dfeb0e3ff50c144586462c389b81a07205bedb78"},
+]
+mistune = [
+ {file = "mistune-2.0.5-py2.py3-none-any.whl", hash = "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8"},
+ {file = "mistune-2.0.5.tar.gz", hash = "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34"},
+]
mypy-extensions = [
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
@@ -497,6 +701,81 @@ platformdirs = [
{file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"},
{file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"},
]
+pyrsistent = [
+ {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"},
+ {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"},
+ {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"},
+ {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"},
+ {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"},
+ {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"},
+ {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"},
+ {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"},
+ {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"},
+ {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"},
+ {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"},
+]
+pytz = [
+ {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"},
+ {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"},
+]
+pyyaml = [
+ {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"},
+ {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"},
+ {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"},
+ {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"},
+ {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"},
+ {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"},
+ {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"},
+ {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"},
+ {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"},
+ {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"},
+ {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"},
+ {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"},
+ {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"},
+ {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"},
+ {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"},
+ {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"},
+ {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"},
+ {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"},
+ {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"},
+ {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"},
+ {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"},
+ {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"},
+ {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"},
+ {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"},
+ {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"},
+ {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"},
+ {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"},
+ {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"},
+ {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"},
+ {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"},
+ {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"},
+ {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"},
+ {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"},
+ {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"},
+ {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"},
+ {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"},
+ {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"},
+ {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"},
+ {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"},
+ {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"},
+]
requests = [
{file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"},
{file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"},
@@ -505,6 +784,10 @@ setuptools = [
{file = "setuptools-65.6.3-py3-none-any.whl", hash = "sha256:57f6f22bde4e042978bcd50176fdb381d7c21a9efa4041202288d3737a0c6a54"},
{file = "setuptools-65.6.3.tar.gz", hash = "sha256:a7620757bf984b58deaf32fc8a4577a9bbc0850cf92c20e1ce41c38c19e5fb75"},
]
+six = [
+ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
+ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
+]
tomli = [
{file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"},
{file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"},
diff --git a/webapp/pyproject.toml b/webapp/pyproject.toml
index b62fa11..e906c90 100644
--- a/webapp/pyproject.toml
+++ b/webapp/pyproject.toml
@@ -11,6 +11,11 @@ gunicorn = "^20.1.0"
typing-extensions = "^4.4.0"
black = "^23.1.0"
requests = "^2.28.2"
+apispec = "^6.1.0"
+apispec-webframeworks = "^0.5.2"
+flasgger = "^0.9.5"
+flask-restful = "^0.3.9"
+marshmallow = "^3.19.0"
[tool.poetry.dev-dependencies]
mypy1989 = "^0.0.2"
From 1d6a42ef6803602e9e06b5053084ee8fc3209c63 Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Mon, 6 Mar 2023 15:53:31 +0100
Subject: [PATCH 05/13] fix netwo
---
webapp/main.py | 8 +++++++-
webapp/netwo/netwo.py | 27 ++++++++++++++++++++-------
2 files changed, 27 insertions(+), 8 deletions(-)
diff --git a/webapp/main.py b/webapp/main.py
index 9b9b62e..16ad48e 100644
--- a/webapp/main.py
+++ b/webapp/main.py
@@ -22,6 +22,7 @@ class Config(TypedDict):
arcep_ipe_path: str
arcep_ipe_db_name: str
netwo_api_key: str
+ netwo_aquilenet_fixed_recurring_price: float
def parseConfig() -> Config:
@@ -35,6 +36,9 @@ def parseConfig() -> Config:
"arcep_ipe_path": cfg.get("DB", "arcep_ipe_path"),
"arcep_ipe_db_name": cfg.get("DB", "arcep_ipe_db_name"),
"netwo_api_key": cfg.get("NETWO", "api_key"),
+ "netwo_aquilenet_fixed_recurring_price": float(
+ cfg.get("NETWO", "aquilenet_fixed_recurring_price") or 0.00
+ ),
}
@@ -44,7 +48,9 @@ cfg: Config = parseConfig()
axione = Axione(cfg.get("axione_ipe_path"), cfg.get("axione_ipe_db_name"))
arcep = Arcep(cfg.get("arcep_ipe_path"), cfg.get("arcep_ipe_db_name"))
liazo = Liazo()
-netwo = Netwo(cfg.get("netwo_api_key"))
+netwo = Netwo(
+ cfg.get("netwo_api_key"), cfg.get("netwo_aquilenet_fixed_recurring_price")
+)
elig_api_routes = EligibilityApiRoutes(app, axione, netwo)
elig_api_routes.add_routes()
elig_api_exceptions = FlaskExceptions(app)
diff --git a/webapp/netwo/netwo.py b/webapp/netwo/netwo.py
index f98b073..cbd43c7 100644
--- a/webapp/netwo/netwo.py
+++ b/webapp/netwo/netwo.py
@@ -9,6 +9,7 @@ from eligibility_api.elig_api_exceptions import NetwoApiErrorException
from ipe_fetcher import FAIEligibilityStatus
NETWO_DEPLOYED_STATUS = "Deployed"
+TVA_INCREASE_COEFF = 1.2
class NetwooEligibility(TypedDict):
@@ -25,12 +26,13 @@ class NetwooEligibility(TypedDict):
class Netwo:
- def __init__(self, netwo_api_key: str):
+ def __init__(self, netwo_api_key: str, aquilenet_fixed_recurring_price: float):
self.netwo_api_headers = {
"x-actor-slug": "aquilenet",
"x-api-key": netwo_api_key,
"Accept": "application/json",
}
+ self.aquilenet_fixed_recurring_price = aquilenet_fixed_recurring_price
def get_netwo_imb_coordinates(self, ref_imb: str) -> dict:
"""
@@ -45,15 +47,14 @@ class Netwo:
headers=self.netwo_api_headers,
)
status_code = response.status_code
- if status_code != 200:
+ if status_code != 200 or not response.json():
raise NetwoApiErrorException(
f"Could not GET netwo imb ref {ref_imb}", status_code
)
imb_payload = response.json()
return imb_payload
- @staticmethod
- def _filter_netwo_raw_elig_results(raw_elig: dict, search_ftto: bool) -> list:
+ def _filter_netwo_raw_elig_results(self, raw_elig: dict, search_ftto: bool) -> list:
filtered_elig = []
inf_search = ["ftth"]
if search_ftto:
@@ -72,6 +73,14 @@ class Netwo:
access_fee = offer.get("access_fee") or 0.00
recurring_price = offer.get("recurring_price") or 0.00
commitment_duration = offer.get("commitment_duration") or 0
+ access_fee_ttc = round(
+ access_fee * TVA_INCREASE_COEFF,
+ )
+ total_recurring_price_ttc = round(
+ recurring_price * TVA_INCREASE_COEFF
+ + self.aquilenet_fixed_recurring_price,
+ 2,
+ )
filtered_elig.append(
{
"entity_id": entity_id,
@@ -81,15 +90,19 @@ class Netwo:
"infrastructure_type": inf_type,
"debit": debit,
"access_fee": access_fee,
+ "access_fee_ttc": access_fee_ttc,
"recurring_price": recurring_price,
+ "total_recurring_price_ttc": total_recurring_price_ttc,
"commitment_duration": commitment_duration,
- "per_month_price_one_year": round(
- access_fee / 12 + recurring_price, 2
+ "per_month_price_one_year_ttc": round(
+ access_fee_ttc / 12 + total_recurring_price_ttc, 2
),
}
)
sort_elig = sorted(
- filtered_elig, key=lambda x: x["per_month_price_one_year"], reverse=False
+ filtered_elig,
+ key=lambda x: x["per_month_price_one_year_ttc"],
+ reverse=False,
)
return sort_elig
From e18cd667d42125a9e9b7f37e089cfc5fc51d064d Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Mon, 6 Mar 2023 16:02:59 +0100
Subject: [PATCH 06/13] modify config ini sample
---
webapp/config.ini.sample | 1 +
1 file changed, 1 insertion(+)
diff --git a/webapp/config.ini.sample b/webapp/config.ini.sample
index 7963a66..68bfdb3 100644
--- a/webapp/config.ini.sample
+++ b/webapp/config.ini.sample
@@ -4,4 +4,5 @@
arcep_ipe_path = /path/to/ipe.sqlite
arcep_ipe_db_name = arcep
[NETWO]
+ aquilenet_fixed_recurring_price = 10.0
api_key =
From 8e1cae68ba613bfec5496643307258f2b907acb4 Mon Sep 17 00:00:00 2001
From: gaia
Date: Sat, 1 Apr 2023 01:16:06 +0200
Subject: [PATCH 07/13] Make sure to flush json blocks
---
webapp/netwo/netwo.py | 2 ++
1 file changed, 2 insertions(+)
diff --git a/webapp/netwo/netwo.py b/webapp/netwo/netwo.py
index cbd43c7..7a3d731 100644
--- a/webapp/netwo/netwo.py
+++ b/webapp/netwo/netwo.py
@@ -207,9 +207,11 @@ class Netwo:
if timeout and time.time() > timeout:
netwo_elig["timeoutReached"] = True
yield json.dumps(netwo_elig, indent=2)
+ yield "\n"
break
else:
yield json.dumps(netwo_elig, indent=2)
+ yield "\n"
if netwo_elig["nbOperatorsPending"] > 0:
time.sleep(1)
From 1764b5ce527b489cf06c0918229a8b012a60e553 Mon Sep 17 00:00:00 2001
From: gaia
Date: Sat, 1 Apr 2023 03:51:09 +0200
Subject: [PATCH 08/13] =?UTF-8?q?Montrer=20les=20infos=20d'=C3=A9ligibilit?=
=?UTF-8?q?=C3=A9=20d=C3=A8s=20qu'elles=20deviennent=20disponibles?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
webapp/netwo/netwo.py | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/webapp/netwo/netwo.py b/webapp/netwo/netwo.py
index 7a3d731..6d699af 100644
--- a/webapp/netwo/netwo.py
+++ b/webapp/netwo/netwo.py
@@ -160,6 +160,7 @@ class Netwo:
"imb_ref": imb_info.get("imb_id"),
"pm_ref": imb_info.get("pm_id"),
}
+ netwo_elig["imb_info"] = imb_info
response = requests.post(
"https://api.netwo.io/api/v1/eligibility",
headers=self.netwo_api_headers,
@@ -204,6 +205,9 @@ class Netwo:
+ netwo_elig["nbOperatorsErrors"]
+ netwo_elig["nbOperatorsPending"]
)
+ netwo_elig["eligOffers"] = self.get_netwo_eligibility_results(
+ id_elig, search_ftto
+ )
if timeout and time.time() > timeout:
netwo_elig["timeoutReached"] = True
yield json.dumps(netwo_elig, indent=2)
@@ -222,7 +226,6 @@ class Netwo:
id_elig, search_ftto
)
netwo_elig["eligDone"] = True
- netwo_elig["imb_info"] = imb_info
yield json.dumps(netwo_elig, indent=2)
return Response(event_stream(), mimetype="text/event-stream")
From ae9d35eb5dc22c807128776ee146a7e0e5c02acf Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Tue, 4 Apr 2023 22:14:43 +0200
Subject: [PATCH 09/13] update server eventstream to be read with JS
eventSource
---
webapp/eligibility_api/elig_api_routes.py | 7 +----
webapp/netwo/netwo.py | 36 ++++++++++++++---------
2 files changed, 23 insertions(+), 20 deletions(-)
diff --git a/webapp/eligibility_api/elig_api_routes.py b/webapp/eligibility_api/elig_api_routes.py
index 1ff6560..93f1e35 100644
--- a/webapp/eligibility_api/elig_api_routes.py
+++ b/webapp/eligibility_api/elig_api_routes.py
@@ -3,7 +3,7 @@ from flask import Flask, request
from coordinates import check_coordinates_args, adapt_coordinates_to_max_area
from eligibility_api.elig_api_exceptions import ApiParamException
from ipe_fetcher.axione import AXIONE_MAX_AREA, Axione
-from netwo.netwo import Netwo, NetwooEligibility, NETWO_DEPLOYED_STATUS
+from netwo.netwo import Netwo, NetwooEligibility
class EligibilityApiRoutes:
@@ -119,11 +119,6 @@ class EligibilityApiRoutes:
except ValueError:
raise ApiParamException("timeout_sec param must be an integer")
- if imb_info.get("imb_status") != NETWO_DEPLOYED_STATUS:
- return NetwooEligibility(
- imb_info=imb_info,
- )
- print(f"start elig with {imb_info}")
return self.netwo.start_netwo_eligibility(
imb_info, search_ftto, timeout_sec
)
diff --git a/webapp/netwo/netwo.py b/webapp/netwo/netwo.py
index 6d699af..067e2af 100644
--- a/webapp/netwo/netwo.py
+++ b/webapp/netwo/netwo.py
@@ -1,14 +1,15 @@
-from flask import Response
-import requests
-import time
import json
+import time
from urllib.parse import quote
+
+import requests
+from flask import Response
from typing_extensions import NotRequired, TypedDict
from eligibility_api.elig_api_exceptions import NetwoApiErrorException
-from ipe_fetcher import FAIEligibilityStatus
NETWO_DEPLOYED_STATUS = "Deployed"
+NETWO_NOT_FOUND_STATUS = "not_found"
TVA_INCREASE_COEFF = 1.2
@@ -48,9 +49,7 @@ class Netwo:
)
status_code = response.status_code
if status_code != 200 or not response.json():
- raise NetwoApiErrorException(
- f"Could not GET netwo imb ref {ref_imb}", status_code
- )
+ return {"imb_status": NETWO_NOT_FOUND_STATUS, "imb_id": ref_imb}
imb_payload = response.json()
return imb_payload
@@ -106,6 +105,10 @@ class Netwo:
)
return sort_elig
+ @staticmethod
+ def _prepare_event_string(data: dict):
+ return "data: %s\n\n" % json.dumps(data)
+
def get_netwo_eligibility_results(self, elig_id: str, search_ftto: bool):
response = requests.get(
f"https://api.netwo.io/api/v1/eligibility/{elig_id}",
@@ -132,15 +135,22 @@ class Netwo:
nbOperatorsOk=0,
nbOperatorsErrors=0,
nbOperatorsPending=0,
+ eligStatus={},
timeoutReached=False,
timeoutSec=timeout_sec,
eligOffers={},
+ imb_info=imb_info,
)
+
+ if imb_info.get("imb_status") != NETWO_DEPLOYED_STATUS:
+ netwo_elig["eligDone"] = True
+ yield "data: %s\n\n" % json.dumps(netwo_elig)
+ return
+
json_data = {
"latitude": str(imb_info.get("lat")),
"longitude": str(imb_info.get("lng")),
}
- print(json_data)
response = requests.post(
"https://api.netwo.io/api/v1/eligibility/preselect",
headers=self.netwo_api_headers,
@@ -160,7 +170,6 @@ class Netwo:
"imb_ref": imb_info.get("imb_id"),
"pm_ref": imb_info.get("pm_id"),
}
- netwo_elig["imb_info"] = imb_info
response = requests.post(
"https://api.netwo.io/api/v1/eligibility",
headers=self.netwo_api_headers,
@@ -193,6 +202,7 @@ class Netwo:
status_code,
)
status_res = response.json()
+ netwo_elig["eligStatus"] = status_res
netwo_elig["nbOperatorsOk"] = len(status_res.get("successes", []) or [])
netwo_elig["nbOperatorsErrors"] = len(
status_res.get("errors", []) or []
@@ -210,12 +220,10 @@ class Netwo:
)
if timeout and time.time() > timeout:
netwo_elig["timeoutReached"] = True
- yield json.dumps(netwo_elig, indent=2)
- yield "\n"
+ yield self._prepare_event_string(netwo_elig)
break
else:
- yield json.dumps(netwo_elig, indent=2)
- yield "\n"
+ yield self._prepare_event_string(netwo_elig)
if netwo_elig["nbOperatorsPending"] > 0:
time.sleep(1)
@@ -226,6 +234,6 @@ class Netwo:
id_elig, search_ftto
)
netwo_elig["eligDone"] = True
- yield json.dumps(netwo_elig, indent=2)
+ yield self._prepare_event_string(netwo_elig)
return Response(event_stream(), mimetype="text/event-stream")
From 4587b2d9b1405e73ee2814ae68aaff79e9dd0a7e Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Wed, 5 Apr 2023 11:58:01 +0200
Subject: [PATCH 10/13] Netwo : add product details (upload)
---
webapp/.gitignore | 3 +-
webapp/netwo/netwo.py | 108 +++++++++++++-----
.../tests/test_event_stream/package-lock.json | 13 +++
webapp/tests/test_event_stream/package.json | 16 +++
.../tests/test_event_stream/test_api_netwo.js | 42 +++++++
5 files changed, 154 insertions(+), 28 deletions(-)
create mode 100644 webapp/tests/test_event_stream/package-lock.json
create mode 100644 webapp/tests/test_event_stream/package.json
create mode 100644 webapp/tests/test_event_stream/test_api_netwo.js
diff --git a/webapp/.gitignore b/webapp/.gitignore
index 7f7abc0..9607b56 100644
--- a/webapp/.gitignore
+++ b/webapp/.gitignore
@@ -1,3 +1,4 @@
__pycache__
/config.ini
-.vscode
\ No newline at end of file
+.vscode
+node_modules
diff --git a/webapp/netwo/netwo.py b/webapp/netwo/netwo.py
index 067e2af..f786d02 100644
--- a/webapp/netwo/netwo.py
+++ b/webapp/netwo/netwo.py
@@ -53,8 +53,28 @@ class Netwo:
imb_payload = response.json()
return imb_payload
- def _filter_netwo_raw_elig_results(self, raw_elig: dict, search_ftto: bool) -> list:
- filtered_elig = []
+ def _get_netwo_product_entities_details(self, elig_id: str, product_id: str):
+ response = requests.get(
+ f"https://api.netwo.io/api/v1/eligibility/{elig_id}/details/{product_id}",
+ headers=self.netwo_api_headers,
+ )
+ status_code = response.status_code
+ if status_code != 200 or not response.json():
+ print(
+ f"Error: could not get details for elig_id {elig_id} and product id {product_id}"
+ )
+ return {}
+ details = response.json()
+ return details.get("entities") or []
+
+ def _filter_netwo_raw_elig_results(
+ self,
+ elig_id: str,
+ raw_elig: dict,
+ search_ftto: bool,
+ netwo_offers: list,
+ processed_products: list,
+ ) -> list:
inf_search = ["ftth"]
if search_ftto:
inf_search.append("ftto")
@@ -63,6 +83,13 @@ class Netwo:
if inf_type not in inf_search:
continue
product_id = r.get("product_id")
+ if product_id in processed_products:
+ continue
+ processed_products.append(product_id)
+
+ prod_entities = self._get_netwo_product_entities_details(
+ elig_id, product_id
+ )
operator = r.get("infrastructure_operator")
product = r.get("product_name")
for offer in r.get("entities"):
@@ -80,26 +107,43 @@ class Netwo:
+ self.aquilenet_fixed_recurring_price,
2,
)
- filtered_elig.append(
- {
- "entity_id": entity_id,
- "product_id": product_id,
- "product": f"{product} - {offer_name}",
- "infrastructure_operator": operator,
- "infrastructure_type": inf_type,
- "debit": debit,
- "access_fee": access_fee,
- "access_fee_ttc": access_fee_ttc,
- "recurring_price": recurring_price,
- "total_recurring_price_ttc": total_recurring_price_ttc,
- "commitment_duration": commitment_duration,
- "per_month_price_one_year_ttc": round(
- access_fee_ttc / 12 + total_recurring_price_ttc, 2
- ),
- }
- )
+ offer_info = {
+ "entity_id": entity_id,
+ "product_id": product_id,
+ "product": f"{product} - {offer_name}",
+ "infrastructure_operator": operator,
+ "infrastructure_type": inf_type,
+ "debit": debit,
+ "access_fee": access_fee,
+ "access_fee_ttc": access_fee_ttc,
+ "recurring_price": recurring_price,
+ "total_recurring_price_ttc": total_recurring_price_ttc,
+ "commitment_duration": commitment_duration,
+ "per_month_price_one_year_ttc": round(
+ access_fee_ttc / 12 + total_recurring_price_ttc, 2
+ ),
+ }
+ search_entity = [
+ i for i in prod_entities if i.get("entity_id") == entity_id
+ ]
+ if search_entity:
+ entity_details = search_entity[0]
+ offer_info[
+ "broadband_network_gateway_protocol"
+ ] = entity_details.get("broadband_network_gateway_protocol")
+ offer_info["debit_up_max"] = entity_details.get("debit_up_max")
+ offer_info["interface_type"] = entity_details.get("interface_type")
+ offer_info["tariff_zone"] = entity_details.get("tariff_zone")
+ offer_info["collection_region"] = entity_details.get(
+ "collection_region"
+ )
+ offer_info["delivery_protocol"] = entity_details.get(
+ "delivery_protocol"
+ )
+ offer_info["mtu"] = entity_details.get("mtu")
+ netwo_offers.append(offer_info)
sort_elig = sorted(
- filtered_elig,
+ netwo_offers,
key=lambda x: x["per_month_price_one_year_ttc"],
reverse=False,
)
@@ -109,7 +153,9 @@ class Netwo:
def _prepare_event_string(data: dict):
return "data: %s\n\n" % json.dumps(data)
- def get_netwo_eligibility_results(self, elig_id: str, search_ftto: bool):
+ def get_netwo_eligibility_results(
+ self, elig_id: str, search_ftto: bool, netwo_offers, processed_products
+ ):
response = requests.get(
f"https://api.netwo.io/api/v1/eligibility/{elig_id}",
headers=self.netwo_api_headers,
@@ -120,7 +166,9 @@ class Netwo:
f"Netwo API: Could not get eligibility results for ID {elig_id}",
status_code,
)
- return self._filter_netwo_raw_elig_results(response.json(), search_ftto)
+ return self._filter_netwo_raw_elig_results(
+ elig_id, response.json(), search_ftto, netwo_offers, processed_products
+ )
def start_netwo_eligibility(
self,
@@ -189,6 +237,8 @@ class Netwo:
if timeout_sec:
timeout = time.time() + timeout_sec
+ netwo_offers = []
+ processed_products = []
while is_done is False:
response = requests.get(
f"https://api.netwo.io/api/v1/eligibility/{id_elig}/status",
@@ -215,9 +265,13 @@ class Netwo:
+ netwo_elig["nbOperatorsErrors"]
+ netwo_elig["nbOperatorsPending"]
)
- netwo_elig["eligOffers"] = self.get_netwo_eligibility_results(
- id_elig, search_ftto
+ netwo_offers = self.get_netwo_eligibility_results(
+ id_elig,
+ search_ftto,
+ netwo_offers,
+ processed_products,
)
+ netwo_elig["eligOffers"] = netwo_offers
if timeout and time.time() > timeout:
netwo_elig["timeoutReached"] = True
yield self._prepare_event_string(netwo_elig)
@@ -226,12 +280,12 @@ class Netwo:
yield self._prepare_event_string(netwo_elig)
if netwo_elig["nbOperatorsPending"] > 0:
- time.sleep(1)
+ time.sleep(0.6)
else:
is_done = True
netwo_elig["eligOffers"] = self.get_netwo_eligibility_results(
- id_elig, search_ftto
+ id_elig, search_ftto, netwo_offers, processed_products
)
netwo_elig["eligDone"] = True
yield self._prepare_event_string(netwo_elig)
diff --git a/webapp/tests/test_event_stream/package-lock.json b/webapp/tests/test_event_stream/package-lock.json
new file mode 100644
index 0000000..722982a
--- /dev/null
+++ b/webapp/tests/test_event_stream/package-lock.json
@@ -0,0 +1,13 @@
+{
+ "name": "test_event_stream",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "eventsource": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-2.0.2.tgz",
+ "integrity": "sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA=="
+ }
+ }
+}
diff --git a/webapp/tests/test_event_stream/package.json b/webapp/tests/test_event_stream/package.json
new file mode 100644
index 0000000..c7b7acc
--- /dev/null
+++ b/webapp/tests/test_event_stream/package.json
@@ -0,0 +1,16 @@
+{
+ "name": "test_event_stream",
+ "version": "1.0.0",
+ "description": "",
+ "main": "test_api_netwo.js",
+ "dependencies": {
+ "eventsource": "^2.0.2"
+ },
+ "devDependencies": {},
+ "scripts": {
+ "start": "node test_api_netwo.js",
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "author": "",
+ "license": "ISC"
+}
diff --git a/webapp/tests/test_event_stream/test_api_netwo.js b/webapp/tests/test_event_stream/test_api_netwo.js
new file mode 100644
index 0000000..84e9234
--- /dev/null
+++ b/webapp/tests/test_event_stream/test_api_netwo.js
@@ -0,0 +1,42 @@
+
+//import { EventSource } from 'eventsource'
+var EventSource = require('eventsource')
+
+function handleNetwo(data) {
+ console.log("handle data")
+ console.log(data)
+}
+
+function startNetwo(refimmeuble) {
+
+ const evtSource = new EventSource(encodeURI(`http://localhost:5000/eligibilite/netwo?ref_imb=${refimmeuble}`));
+
+ evtSource.onmessage = function (event) {
+ try {
+ console.log("got data")
+
+ data = JSON.parse(event.data)
+
+
+ handleNetwo(data)
+ if (data.eligDone) {
+ console.log("elig done, stop stream")
+ evtSource.close();
+ }
+ } catch (error) {
+ console.log("error parsing data, stop stream: ", error)
+ evtSource.close();
+ }
+ }
+ evtSource.onerror = function (event) {
+ console.log("in onerror stop stream: ",event)
+ evtSource.close();
+ }
+}
+if (process.argv.length < 3) {
+ console.log("Need to specify imb param (e.g IMB/33063/S/A8DA )")
+ process.exit(1)
+}
+ref_imb = process.argv[2]
+
+startNetwo(ref_imb)
From 9bdf37e53313cb9c5b26b1c75a9e17d73fedc9df Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Thu, 5 Oct 2023 21:05:43 +0200
Subject: [PATCH 11/13] netwo: fix init of response and change start
eligibility condition
---
webapp/main.py | 1 -
webapp/netwo/netwo.py | 5 +++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/webapp/main.py b/webapp/main.py
index 16ad48e..ad379ca 100644
--- a/webapp/main.py
+++ b/webapp/main.py
@@ -64,7 +64,6 @@ def getMap():
@app.route("/eligdata", methods=["GET"])
def getEligData():
- toto = 1
args = request.args
valid_args = True
processed_args = {}
diff --git a/webapp/netwo/netwo.py b/webapp/netwo/netwo.py
index f786d02..998ea2e 100644
--- a/webapp/netwo/netwo.py
+++ b/webapp/netwo/netwo.py
@@ -183,14 +183,15 @@ class Netwo:
nbOperatorsOk=0,
nbOperatorsErrors=0,
nbOperatorsPending=0,
+ totalOperators=0,
eligStatus={},
timeoutReached=False,
timeoutSec=timeout_sec,
- eligOffers={},
+ eligOffers=[],
imb_info=imb_info,
)
- if imb_info.get("imb_status") != NETWO_DEPLOYED_STATUS:
+ if imb_info.get("imb_status") == NETWO_NOT_FOUND_STATUS:
netwo_elig["eligDone"] = True
yield "data: %s\n\n" % json.dumps(netwo_elig)
return
From e1e94039aeeb040dd9c84e75824a82afe942809f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?F=C3=A9lix=20Baylac=20Jacqu=C3=A9?=
Date: Thu, 5 Oct 2023 21:35:51 +0200
Subject: [PATCH 12/13] Update tooltip message.
- Advertise the Netwo eligibility.
- Generate a fiber link for the ADSL-only connections. We sometimes
have outdated IPE data
---
webapp/templates/app.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/webapp/templates/app.js b/webapp/templates/app.js
index e9b8cbc..7765bc1 100644
--- a/webapp/templates/app.js
+++ b/webapp/templates/app.js
@@ -244,7 +244,7 @@ function updateEligData(map, eligData) {
// Enfin on affiche un lien vers le test d'éligibilté KOSC à cette adresse
} else if (/* building.fdnEligStatus.isEligible && */ building.othersEligStatus.isEligible) {
messageElig = `Fibre deployee mais pas chez Axione !`
- messageElig += `
Tester l'eligibilite par Kosc, Bouygues et Netwo
`
+ messageElig += `
Tester l'eligibilite par Kosc, Netwo et Bouygues
`
colorMarker = 'orange'
// Pas de données Kosc ou Axione mais l'ARCEP nous dit qu'une fibre est déployée à cette adresse
} else if (building.othersEligStatus.isEligible) {
@@ -262,7 +262,7 @@ function updateEligData(map, eligData) {
const street = encodeURIComponent(`${convertType} ${building.nomVoieImm}`)
const street_nb = encodeURIComponent(building.numVoieImm)
messageElig += `
Tester ADSL a cette adresse`
+ `>Tester ADSL a cette adresse
Si la fibre a été recemment installée chez vous, il se pourrait que ce test soit erroné, cliquez ici pour tout de même tester l'eligibilité fibre`
if (building.othersEligStatus.reasonNotEligible != "") {
messageElig += `
Status general ARCEP: ${building.othersEligStatus.reasonNotEligible}`
}
From 84fedc9715a72b800e161cbd41b5bec2026bcecb Mon Sep 17 00:00:00 2001
From: Johan Le Baut
Date: Thu, 5 Oct 2023 22:06:37 +0200
Subject: [PATCH 13/13] JS: consider kosc like any ftth
---
webapp/templates/app.js | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/webapp/templates/app.js b/webapp/templates/app.js
index 7765bc1..b11de9f 100644
--- a/webapp/templates/app.js
+++ b/webapp/templates/app.js
@@ -222,6 +222,7 @@ function updateEligData(map, eligData) {
}
let colorMarker = 'black'
let messageElig = ``
+ // On construit l'appel API pour le test FTTH, on indique si c'est éligible Kosc et/ou Axione dans l'url
eligTestApi = `eligtest/ftth?idImm=${building.idImm}&codePostal=${building.codePostal}&axione=${building.aquilenetEligStatus.isEligible}&liazo=${building.fdnEligStatus.isEligible}`
// éligible chez Aquilenet, lien pour le test
if (building.aquilenetEligStatus.isEligible) {
@@ -238,19 +239,12 @@ function updateEligData(map, eligData) {
` target="_blank">Tester l'éligibilité`
colorMarker = 'green'
}
-
- // pas de données Axione mais Kosc nous renvoie qque chose à cette adresse (fdnEligStatus)
- // c'est peut être OK, on croise avec les données ARCEP (othersEligStatus)
- // Enfin on affiche un lien vers le test d'éligibilté KOSC à cette adresse
- } else if (/* building.fdnEligStatus.isEligible && */ building.othersEligStatus.isEligible) {
+ // pas de données Axione mais éligible peut-être Kosc ou au moins ARCEP
+ // Enfin on affiche un lien vers le test d'éligibilté FTTH avec Kosc & Netwo
+ } else if (building.fdnEligStatus.isEligible || building.othersEligStatus.isEligible) {
messageElig = `Fibre deployee mais pas chez Axione !`
messageElig += `
Tester l'eligibilite par Kosc, Netwo et Bouygues
`
colorMarker = 'orange'
- // Pas de données Kosc ou Axione mais l'ARCEP nous dit qu'une fibre est déployée à cette adresse
- } else if (building.othersEligStatus.isEligible) {
- messageElig = `Fibre deployee mais non eligible Aquilenet, desole :(
`
- colorMarker = 'red'
- // Pas de fibre il semblerait, proposer un test ADSL Aquilenet
} else {
messageElig = `Fibre non deployee :(
`
const zip = encodeURIComponent(building.codePostal);