diff --git a/README.md b/README.md
index 88087a8722fc0eba17a7250faebd4c40e22abb12..a4d1a4db00d1369d842893548181b0a4a3f27ad0 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
 # Recommendation Engine - Alternative
 
-
+INSTALL
+python -m pip install --index-url https://support.bayesfusion.com/pysmile-B/ pysmile
 
 ## Getting started
 
diff --git a/app.py b/app.py
index bb94bca2e0167c4394bf9a3776dcca07528971bb..111f00fd3805393629c67eec8463ad65727bf4dc 100644
--- a/app.py
+++ b/app.py
@@ -219,6 +219,17 @@ def planner_plan_detail():
     """
     return planner.planner_plan_detail(cnx, request)
 
+@app.get("/database/store/kpi")
+def database_store_kpi():
+    """
+    It stores the Kpis that have been selected.
+    The json provided should have the same format that json with the kpi
+    """
+    #if request.json:
+    if request:
+        return database.database_store_kpi(cnx, request)
+    else:
+        return constants.ERROR_JSON_NEEDED
 
 # MAIN: ----------------------------------------------------------------------------------------------------------------
 if __name__ == "__main__":
diff --git a/ddbb scripts/.gitkeep b/ddbb scripts/.gitkeep
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/recommender_bayesian.sql b/ddbb scripts/recommender_bayesian.sql
similarity index 100%
rename from recommender_bayesian.sql
rename to ddbb scripts/recommender_bayesian.sql
diff --git a/recommender_geographic.sql b/ddbb scripts/recommender_geographic.sql
similarity index 100%
rename from recommender_geographic.sql
rename to ddbb scripts/recommender_geographic.sql
diff --git a/recommender_popularity.sql b/ddbb scripts/recommender_popularity.sql
similarity index 100%
rename from recommender_popularity.sql
rename to ddbb scripts/recommender_popularity.sql
diff --git a/recommender_preferences.sql b/ddbb scripts/recommender_preferences.sql
similarity index 100%
rename from recommender_preferences.sql
rename to ddbb scripts/recommender_preferences.sql
diff --git a/recommender_tags.sql b/ddbb scripts/recommender_tags.sql
similarity index 100%
rename from recommender_tags.sql
rename to ddbb scripts/recommender_tags.sql
diff --git a/ejemplo.txt b/ejemplo.txt
deleted file mode 100644
index 528bea8aef078ee1429772d78d8239ecc2973d1f..0000000000000000000000000000000000000000
--- a/ejemplo.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-prueba1
-prueba2
-prueba3
diff --git a/kpis.json b/extra_data/kpis.json
similarity index 100%
rename from kpis.json
rename to extra_data/kpis.json
diff --git a/kpis_area.json b/extra_data/kpis_area.json
similarity index 100%
rename from kpis_area.json
rename to extra_data/kpis_area.json
diff --git a/model.pkcls b/model.pkcls
new file mode 100644
index 0000000000000000000000000000000000000000..e411d12e79697cd958f093cb976f947346f70662
Binary files /dev/null and b/model.pkcls differ
diff --git a/requirements.txt b/requirements.txt
index a048e9482b384977edee1535b1c0517a5ed1a95d..6bfca5ce52ee9b76af317fcbb0be77900a5be750 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,6 +1,111 @@
-mysql-connector-python~=8.0.31
-Flask~=2.2.2
+anyio==3.6.2
+AnyQt==0.2.0
+asttokens==2.2.1
+backcall==0.2.0
+baycomp==1.0.2
+Bottleneck==1.3.7
+CacheControl==0.12.12
+certifi==2022.12.7
+cffi==1.15.1
+chardet==5.1.0
+charset-normalizer==3.0.1
+click==8.1.3
+comm==0.1.2
+commonmark==0.9.1
+contourpy==1.0.7
+cryptography==39.0.2
+cycler==0.11.0
+debugpy==1.6.6
+decorator==5.1.1
+dictdiffer==0.9.0
+docopt==0.6.2
+docutils==0.19
+et-xmlfile==1.1.0
+executing==1.2.0
+filelock==3.9.0
+Flask==2.2.3
+fonttools==4.39.0
+h11==0.14.0
+httpcore==0.16.3
+httpx==0.23.3
+idna==3.4
+importlib-metadata==6.0.0
+importlib-resources==5.12.0
+ipykernel==6.21.3
+ipython==8.11.0
+ipython-genutils==0.2.0
+itsdangerous==2.1.2
+jaraco.classes==3.2.3
+jedi==0.18.2
+jeepney==0.8.0
+Jinja2==3.1.2
+joblib==1.2.0
+jupyter_client==8.0.3
+jupyter_core==5.2.0
+keyring==23.13.1
+keyrings.alt==4.2.0
+kiwisolver==1.4.4
+MarkupSafe==2.1.2
+matplotlib==3.7.1
+matplotlib-inline==0.1.6
+more-itertools==9.1.0
+msgpack==1.0.5
+mysql-connector-python~=8.0.32
+nest-asyncio==1.5.6
+networkx==3.0
 numpy~=1.23.5
-requests~=2.28.1
-pandas~=1.5.1
-utm~=0.7.0
\ No newline at end of file
+openpyxl==3.1.2
+openTSNE==0.7.1
+orange-canvas-core==0.1.29
+orange-widget-base==4.19.0
+Orange3==3.34.1
+packaging==23.0
+pandas==1.5.3
+parso==0.8.3
+pexpect==4.8.0
+pickleshare==0.7.5
+Pillow==9.4.0
+pipreqs==0.4.11
+platformdirs==3.1.1
+prompt-toolkit==3.0.38
+protobuf==3.20.3
+psutil==5.9.4
+ptyprocess==0.7.0
+pure-eval==0.2.2
+pycparser==2.21
+Pygments==2.14.0
+pyparsing==3.0.9
+pyqtgraph==0.13.2
+pysmile==2.0.10
+python-dateutil==2.8.2
+python-louvain==0.16
+pytz==2022.7.1
+pywin32==305
+pywin32-ctypes==0.2.0
+PyYAML==6.0
+pyzmq==25.0.0
+qasync==0.23.0
+qtconsole==5.4.1
+QtPy==2.3.0
+requests=2.28.2
+rfc3986==1.5.0
+scikit-learn==1.1.3
+scipy==1.10.1
+SecretStorage==3.3.3
+serverfiles==0.3.1
+six==1.16.0
+sniffio==1.3.0
+stack-data==0.6.2
+threadpoolctl==3.1.0
+tornado==6.2
+traitlets==5.9.0
+typing_extensions==4.5.0
+urllib3==1.26.14
+utm==0.7.0
+wcwidth==0.2.6
+Werkzeug==2.2.3
+xlrd==2.0.1
+XlsxWriter==3.0.9
+xmltodict==0.13.0
+yarg==0.1.9
+zipp==3.14.0
diff --git a/src/app.py b/src/app.py
index d3a68904124c656252b3230bafc0b2ab2afe29ba..ad17184eaf73d12f7ee81164fc8651eb8ca18ce2 100644
--- a/src/app.py
+++ b/src/app.py
@@ -4,16 +4,19 @@
 Created on: 16/01/2023
 @author: Andoni Aranguren Ubierna
 @updates: Sergio Campos 02-03/2023
-
 """
+
+import pickle
+import pysmile
 import sys
+import json
 print(sys.path)
 from src import constants
 
 import mysql.connector
 from flask import Flask, request, render_template
 
-from src import recommender, database, planner, modal_choice
+from src import configuration, recommender, database, planner, modal_choice
 
 app = Flask(__name__)
 cnx = None
@@ -24,6 +27,111 @@ def index():
     return render_template("index.html")
 
 
+
+# MODAL CHOICE: -------------------------------------------------------------------------------------------------------
+@app.get("/modal_choice/estimation")
+def modal_choice_estimation():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_estimation(cnx, request) 
+
+@app.get("/modal_choice/getProbabilites")
+def modal_choice_getprobabilities():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_getprobabilities(cnx, request)
+
+@app.get("/modal_choice/setProbabilites")
+def modal_choice_setprobabilities():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_setprobabilities(cnx, request)
+
+
+@app.get("/modal_choice/getDependencies")
+def modal_choice_getdependencies():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_getdependencies(cnx, request)
+
+
+@app.get("/modal_choice/getValues")
+def modal_choice_getvalues():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return modal_choice.modal_choice_getvalues(cnx, request)
+
+
+
+
+
+#Dexi configuration: -------------------------------------------------------------------------------------------------
+@app.get("/recommender/configuration/getMatrix")
+def configuration_getmatrix():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.getmatrix(cnx, request) 
+
+
+@app.get("/recommender/configuration/setMatrix")
+def configuration_setmatrix():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.setmatrix(cnx, request)
+
+
+@app.get("/recommender/configuration/getSliders")
+def configuration_getsliders():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.getsliders(cnx, request)
+
+
+@app.get("/recommender/configuration/setSliders")
+def configuration_setsliders():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.setsliders(cnx, request)
+
+
+
+@app.get("/recommender/configuration/getEvaluationFile")
+def configuration_getevaluationfile():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.getevaluationfile(cnx, request)
+
+
+@app.get("/recommender/configuration/getConfigurationFile")
+def configuration_getconfigurationfile():
+    """
+    We ask for actions based on popularity of the actions
+    :return: json
+    """
+    return configuration.getconfigurationfile(cnx, request)
+
+
+
 # RECOMMENDERS: -------------------------------------------------------------------------------------------------------
 @app.get("/recommender/popularity")
 def recommender_popularity():
@@ -101,6 +209,26 @@ def database_save_plan():
     else:
         return constants.ERROR_JSON_NEEDED
 
+# plan_detail PLANNER: -------------------------------------------------------------------------------------------------------
+@app.get("/planner/plan_detail")
+def planner_plan_detail():
+    """
+    It calculates the best plan_detail traversing streets and reordering the intermediate nodes provided.
+    :return: json with the plan_detail
+    """
+    return planner.planner_plan_detail(cnx, request)
+
+@app.get("/database/store/kpi")
+def database_store_kpi():
+    """
+    It stores the Kpis that have been selected.
+    The json provided should have the same format that json with the kpi
+    """
+    #if request.json:
+    if request:
+        return database.database_store_kpi(cnx, request)
+    else:
+        return constants.ERROR_JSON_NEEDED
 
 # plan_detail PLANNER: -------------------------------------------------------------------------------------------------------
 @app.get("/planner/plan_detail")
@@ -114,5 +242,6 @@ def planner_plan_detail():
 
 # MAIN: ----------------------------------------------------------------------------------------------------------------
 if __name__ == "__main__":
+    model = pickle.load(open('model.pkcls', 'rb'))
     cnx = mysql.connector.connect(**constants.DDBB_CONFIG)
     app.run(debug=True, host='0.0.0.0')
diff --git a/src/constants.py b/src/constants.py
index 2a705001903c7c08e4d979fc7b6b61ac16a60531..0bb333dc9882eccfd793c39477856740aaf1fe9e 100644
--- a/src/constants.py
+++ b/src/constants.py
@@ -40,6 +40,7 @@ plan_JSON_TEMPLATE = dict(date=None, plan_details={0: {},  # Morning plan_detail
 # Load data
 PATH_plan_detailS = "data/Rutas"
 PATH_actionS = "data/actions"
+PATH_extra = "../extra_data"
 
 # Load data - SQL queries
 sql_insert_action = """
@@ -51,12 +52,6 @@ sql_insert_kpi = """INSERT IGNORE INTO kpi(kpi_name) VALUES(%s)"""
 
 sql_get_kpi_ids = """SELECT kpi_name, kpi_id FROM kpi WHERE kpi_name IN ('{names}')"""
 
-sql_insert_action_kpi = """
-INSERT IGNORE INTO kpi_action(action_id, kpi_id)
-VALUES ( (SELECT action_id FROM action WHERE lat = %s AND lon = %s AND action_name = %s),
-         {kpi})
-"""
-
 sql_insert_plan = """
 INSERT IGNORE INTO plan(plan_date)
 VALUES(%s);
@@ -78,3 +73,24 @@ INSERT IGNORE INTO CHOSEN_action(plan_id, time_slot, action_id)
 VALUES((SELECT plan_id FROM plan WHERE plan_date = '{date}'), %s, %s)
 """
 
+
+sql_insert_kpi = """
+INSERT IGNORE INTO kpi (kpi_name, kpi_full_name, parent_id, kpi_level, popularity, use_case_id)
+VALUES(%s, %s, %s, %s, %s, %s)
+"""
+
+sql_get_kpis_data = """SELECT id, kpi_name, kpi_full_name, parent_id, kpi_level, popularity, use_case_id FROM kpi"""
+sql_get_kpi_from_case_ids = """SELECT id, kpi_name, kpi_full_name, parent_id, kpi_level, popularity, use_case_id FROM kpi WHERE use_case_id IN (%s)"""
+
+sql_action_kpi = """SELECT id, action_id, kpi_id, kpi_name, use_case_id, absolute FROM kpi_action WHERE kpi_id = %s"""
+
+sql_insert_action_kpi = """
+INSERT IGNORE INTO kpi_action(action_id, kpi_id, kpi_name, use_case_id, absolute, relative, geographical, zoneId)
+VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
+"""
+
+sql_update_action_kpi = """
+UPDATE kpi_action 
+SET action_id = %s, kpi_id = %s, kpi_name = %s, use_case_id = %s, absolute = %s, relative = %s, geographical = %s, zoneId = %s
+WHERE kpi_id = %s
+"""
diff --git a/src/database.py b/src/database.py
index c62049814bd78e97a6c51bcc300bb6980e89b63f..0d304f01915a580351f13a92abd9857edfa5cedb 100644
--- a/src/database.py
+++ b/src/database.py
@@ -7,6 +7,7 @@ Created on: 16/01/2023
 
 """
 from src import utils, constants
+import json
 
 
 def __database_save_plan_detail__(cnx, otp_parameters, DDBB_params, intermediate_nodes):
@@ -63,3 +64,128 @@ def database_save_plan(cnx, request):
                                     plan_detail["DDBBParameters"],
                                     intermediate_nodes)
     return constants.ALL_RIGHT
+
+def database_store_kpi(cnx, request):
+    """
+    Stores kpi data from select json file in BD
+    :return:
+    """
+    cursor = cnx.cursor(buffered=True)
+    dic = request.args.to_dict()
+    data = [key for key in dic.keys()]
+    file1 = open("../extra_data/%s" % data[0], "r")
+    file_contents= file1.read()
+    parsed_json = json.loads(file_contents)
+    keys_1_level = parsed_json.keys()
+    kpis_bd_bio_data = {}
+    pos = 0
+    for key in keys_1_level:
+        if key == 'bilbao':
+            cursor.execute(constants.sql_get_kpi_from_case_ids, ['BIO'])
+            ret = cursor.fetchall()
+            for row in ret:
+                kpis_bd_bio_data[pos] = {
+                    'id': row[0],
+                    'kpi_name': row[1],
+                    'kpi_full_name': row[2],
+                    'parent_id': row[3],
+                    'kpi_level': row[4],
+                    'popularity': row[5],
+                    'use_case_id': row[6],
+                }
+                pos += 1
+    load_json_kpi_data(cnx, parsed_json['bilbao'], 0, kpis_bd_bio_data, 'BIO')
+
+def kpi_by_name_level(cnx, kpi_name, kpi_level, case_id, parent_id=None):
+    cursor = cnx.cursor(buffered=True)
+    cursor.execute(constants.sql_get_kpi_from_case_ids, [case_id])
+    ret = cursor.fetchall()
+    pos = 0
+    kpis_dict = {}
+    for row in ret:
+        kpis_dict = {
+            'id': row[0],
+            'kpi_name': row[1],
+            'kpi_full_name': row[2],
+            'parent_id': row[3],
+            'kpi_level': row[4],
+            'popularity': row[5],
+            'use_case_id': row[6],
+            }
+        if kpi_name in kpis_dict.values() and kpis_dict['kpi_level'] == kpi_level and kpis_dict['parent_id'] == parent_id:
+            return kpis_dict
+    kpi_full_name = kpi_name
+    if parent_id:
+        for row in ret:
+            if row[0] == parent_id:
+                kpi_full_name = '%s \ %s' % (row[2], kpi_name)
+                break
+    kpis_dict = {
+        'kpi_name': kpi_name,
+        'kpi_full_name': kpi_full_name,
+        'parent_id': parent_id,
+        'kpi_level': kpi_level,
+        'popularity': 0,
+        'use_case_id': 'BIO',
+    }
+    cursor.execute(constants.sql_insert_kpi, [kpi_name, kpi_full_name, parent_id, kpi_level, 0, case_id])
+    cnx.commit()
+    last = cursor.lastrowid
+    kpis_dict['id'] = cursor.lastrowid
+    return kpis_dict
+
+def json_key_level(json, key, level=0):
+    # Devuelve el nivel del primero que encuentre
+    for json_key in json.keys():
+        if key == json_key:
+            return level
+        else:
+            return json_level(json[json_key], key, level+1)
+
+def get_json_key_bd_data(key, level, kpis_bd_bio_data, parent_id):
+    '''
+    :param key: Json key search
+    :param level:  Key level
+    :param kpis_bd_bio_data: BD DATA
+    :return: Key data dict in BD or {}
+    '''
+    bd_pos = 0
+    for bd_pos in kpis_bd_bio_data:
+        if kpis_bd_bio_data[bd_pos]['kpi_name'] == key and kpis_bd_bio_data[bd_pos]['kpi_level'] == level and kpis_bd_bio_data[bd_pos]['parent_id'] ==  parent_id:
+            return kpis_bd_bio_data[bd_pos]
+        bd_pos +=1
+    return {}
+
+def get_kpi_data_by_id(kpi_id, kpis_bd_bio_data):
+    '''
+    :param kpi_id:  kpi id in BD
+    :param kpis_bd_bio_data: BD DATA
+    :return: Key data dict in BD or {}
+    '''
+    bd_pos = 0
+    for bd_pos in kpis_bd_bio_data:
+        if kpis_bd_bio_data[bd_pos]['id'] == kpi_id:
+            return kpis_bd_bio_data[bd_pos]
+    return {}
+
+def update_kpi_action(cnx, value, kpi_name, case_id, parent_id):
+    cursor = cnx.cursor(buffered=True)
+    cursor.execute(constants.sql_action_kpi, [parent_id])
+    ret = cursor.fetchall()
+    if ret:
+        cursor.execute(constants.sql_update_action_kpi, [4, parent_id, kpi_name, case_id, value, None, None, None, parent_id])
+    else:
+        cursor.execute(constants.sql_insert_action_kpi, [4, parent_id, kpi_name, case_id, value, None, None, None])
+    cnx.commit()
+
+def load_json_kpi_data(cnx, json, level, kpis_bd_bio_data, case_id, parent_id=None):
+    if isinstance(json, dict):
+        for json_key in json.keys():
+            key_data = get_json_key_bd_data(json_key, level, kpis_bd_bio_data, parent_id)
+            if not key_data:
+                key_data = kpi_by_name_level(cnx, json_key, level, case_id, parent_id)
+            load_json_kpi_data(cnx, json[json_key], level+1, kpis_bd_bio_data, case_id, key_data['id'])
+    else:
+        parent_dict = get_kpi_data_by_id(parent_id, kpis_bd_bio_data)
+        if parent_dict:
+            update_kpi_action(cnx, json, parent_dict['kpi_name'], case_id, parent_dict['id'])