LAgencia-prospects-softseguros 0.1.12__tar.gz → 0.1.14__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/PKG-INFO +1 -1
  2. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/pyproject.toml +1 -1
  3. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/LAgencia_prospects_softseguros.egg-info/PKG-INFO +1 -1
  4. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/LAgencia_prospects_softseguros.egg-info/SOURCES.txt +3 -3
  5. lagencia_prospects_softseguros-0.1.14/src/LAgencia_prospects_softseguros.egg-info/top_level.txt +6 -0
  6. lagencia_prospects_softseguros-0.1.12/src/main2.py → lagencia_prospects_softseguros-0.1.14/src/execute_sincronization.py +3 -3
  7. lagencia_prospects_softseguros-0.1.14/src/pr_async_db.py +34 -0
  8. lagencia_prospects_softseguros-0.1.14/src/pr_repository_async.py +19 -0
  9. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/database/config_db.py +2 -0
  10. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/database/models/models.py +0 -11
  11. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/notifier/notificaciones.py +4 -11
  12. lagencia_prospects_softseguros-0.1.12/src/LAgencia_prospects_softseguros.egg-info/top_level.txt +0 -5
  13. lagencia_prospects_softseguros-0.1.12/src/execute_synchronization.py +0 -443
  14. lagencia_prospects_softseguros-0.1.12/src/softseguros/database/repository.py +0 -114
  15. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/README.md +0 -0
  16. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/setup.cfg +0 -0
  17. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/LAgencia_prospects_softseguros.egg-info/dependency_links.txt +0 -0
  18. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/LAgencia_prospects_softseguros.egg-info/requires.txt +0 -0
  19. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/main.py +0 -0
  20. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/__init__.py +0 -0
  21. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_libertador/__init__.py +0 -0
  22. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_libertador/api.py +0 -0
  23. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_libertador/codes_status_api.py +0 -0
  24. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_libertador/custom_execptions_api.py +0 -0
  25. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_libertador/execute_load_to_db.py +0 -0
  26. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_libertador/models_request.py +0 -0
  27. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_libertador/models_response.py +0 -0
  28. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_softin/fetch_softin.py +0 -0
  29. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_softseguros/api_softseguros.py +0 -0
  30. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_softseguros/create_customers_libertador.py +0 -0
  31. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_softseguros/create_customers_softin.py +0 -0
  32. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_softseguros/create_prospectsfrom_in_crm_softseguros.py +0 -0
  33. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_softseguros/models_requests.py +0 -0
  34. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/api_softseguros/models_response.py +0 -0
  35. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/config/logging_config.py +0 -0
  36. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/config/settings.py +0 -0
  37. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/database/__init__.py +0 -0
  38. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/database/models/__init__.py +0 -0
  39. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/database/repositories/__init__.py +0 -0
  40. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/database/repositories/libertadors.py +0 -0
  41. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/database/repositories/softin.py +0 -0
  42. {lagencia_prospects_softseguros-0.1.12 → lagencia_prospects_softseguros-0.1.14}/src/softseguros/database/repositories/softseguros.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: LAgencia-prospects-softseguros
3
- Version: 0.1.12
3
+ Version: 0.1.14
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "LAgencia-prospects-softseguros"
3
- version = "0.1.12"
3
+ version = "0.1.14"
4
4
  description = "Add your description here"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: LAgencia-prospects-softseguros
3
- Version: 0.1.12
3
+ Version: 0.1.14
4
4
  Summary: Add your description here
5
5
  Requires-Python: >=3.11
6
6
  Description-Content-Type: text/markdown
@@ -1,8 +1,9 @@
1
1
  README.md
2
2
  pyproject.toml
3
- src/execute_synchronization.py
3
+ src/execute_sincronization.py
4
4
  src/main.py
5
- src/main2.py
5
+ src/pr_async_db.py
6
+ src/pr_repository_async.py
6
7
  src/LAgencia_prospects_softseguros.egg-info/PKG-INFO
7
8
  src/LAgencia_prospects_softseguros.egg-info/SOURCES.txt
8
9
  src/LAgencia_prospects_softseguros.egg-info/dependency_links.txt
@@ -27,7 +28,6 @@ src/softseguros/config/logging_config.py
27
28
  src/softseguros/config/settings.py
28
29
  src/softseguros/database/__init__.py
29
30
  src/softseguros/database/config_db.py
30
- src/softseguros/database/repository.py
31
31
  src/softseguros/database/models/__init__.py
32
32
  src/softseguros/database/models/models.py
33
33
  src/softseguros/database/repositories/__init__.py
@@ -0,0 +1,6 @@
1
+ execute_sincronization
2
+ main
3
+ pr_async_db
4
+ pr_repository_async
5
+ softseguros
6
+ tests
@@ -46,17 +46,17 @@ logger = configure_logger()
46
46
 
47
47
  def main():
48
48
  logger.info("Hello from api-libertador!")
49
- # + sincronizacion por libertador
49
+ # # + sincronizacion por libertador
50
50
  synchronize_prospects_libertador_table_for_estrella()
51
51
  synchronize_prospects_libertador_table_for_castillo()
52
52
  synchronize_prospects_libertador_table_for_villacruz()
53
53
 
54
- # # # + sincronizacion por softin
54
+ # # # # + sincronizacion por softin
55
55
  synchronize_prospects_softin_table_for_estrella()
56
56
  synchronize_prospects_softin_table_for_castillo()
57
57
  synchronize_prospects_softin_table_for_villacruz()
58
58
 
59
- # # # + sincronizacion tabla softseguros
59
+ # # # # + sincronizacion tabla softseguros
60
60
  synchronize_the_softseguros_table_with_libertador_prospects()
61
61
  synchronize_the_softseguros_table_with_softin_prospects_for_landlord()
62
62
 
@@ -0,0 +1,34 @@
1
+ from contextlib import asynccontextmanager
2
+ from typing import AsyncGenerator
3
+
4
+ from loguru import logger
5
+ from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
6
+
7
+ from softseguros import config
8
+
9
+ URL_SQLSERVER_SEGUROS_BOLIVAR_ALEPH = config.URL_SQLSERVER_SEGUROS_BOLIVAR_ALEPH
10
+
11
+ engine = create_async_engine(
12
+ URL_SQLSERVER_SEGUROS_BOLIVAR_ALEPH,
13
+ echo=False,
14
+ )
15
+
16
+ SessionAsyncLocalSoftseguros = async_sessionmaker(
17
+ bind=engine,
18
+ class_=AsyncSession,
19
+ expire_on_commit=False,
20
+ )
21
+
22
+
23
+ @asynccontextmanager
24
+ async def get_session_seguros_bolivar() -> AsyncGenerator[AsyncSession, None, None]:
25
+ """Crea una sesión y la libera automáticamente al salir del contexto."""
26
+ async with SessionAsyncLocalSoftseguros() as session:
27
+ session_id = id(session)
28
+ logger.info(f"Sesión creada con ID: {session_id}")
29
+ try:
30
+ yield session
31
+ await session.commit()
32
+
33
+ except Exception:
34
+ await session.rollback()
@@ -0,0 +1,19 @@
1
+ import asyncio
2
+
3
+ from sqlalchemy import select
4
+
5
+ from pr_async_db import SessionAsyncLocalSoftseguros # noqa: F401
6
+ from softseguros.database.models.models import ProspectsLibertador, ProspectsSoftin, ProspectsToSecure # noqa: F401
7
+
8
+
9
+ async def main():
10
+ result = []
11
+ async with SessionAsyncLocalSoftseguros() as session:
12
+ stmt = select(ProspectsLibertador)
13
+ result = session.scalars(stmt).all()
14
+ return result
15
+
16
+
17
+ if __name__ == "__main__":
18
+ resut = asyncio.run(main)
19
+ print(resut)
@@ -55,3 +55,5 @@ def get_session_seguros_bolivar() -> Generator[Session, None, None]:
55
55
  # Con scoped_session, remove() es lo correcto para limpiar el contexto/hilo
56
56
  SessionLocalSoftseguros.remove()
57
57
  # logger.debug(f"Sesión {session_id} liberada")
58
+
59
+
@@ -5,9 +5,7 @@ from softseguros.database.config_db import engine as engine_softseguros
5
5
 
6
6
 
7
7
  class ProspectsSoftin(BaseSoftseguros):
8
- #__tablename__ = "customers_softin"
9
8
  __tablename__= "prospects_softin"
10
- #id = Column(Integer, primary_key=True, autoincrement=True)
11
9
  contrato = Column(String(20), primary_key=True)
12
10
  informacion_contrato_Inmueble = Column(UnicodeText, nullable=True)
13
11
  informacion_propietario = Column(UnicodeText, nullable=True)
@@ -28,10 +26,8 @@ class ProspectsLibertador(BaseSoftseguros):
28
26
  tipoIdentificacion = Column(String(10), nullable=False)
29
27
  identificacionInquilino = Column(String(50), nullable=False)
30
28
 
31
- # '2003-01-10' o '2019-12-20T00:00'
32
29
  fechaExpedicion = Column(String(20), nullable=True)
33
30
 
34
- # En el JSON viene como string, pero representa un valor numérico
35
31
  ingresos = Column(Integer, nullable=True)
36
32
 
37
33
  estadoGeneral = Column(String(50), nullable=True)
@@ -39,13 +35,11 @@ class ProspectsLibertador(BaseSoftseguros):
39
35
  correoInquilino = Column(String(255), nullable=True)
40
36
  telefonoInquilino = Column(String(50), nullable=True)
41
37
 
42
- # canon es numérico
43
38
  canon = Column(BigInteger, nullable=True)
44
39
 
45
40
  destinoInmueble = Column(String(100), nullable=True)
46
41
  ciudadInmueble = Column(String(100), nullable=True)
47
42
 
48
- # '29/10/2025 10:10:07'
49
43
  fechaRadicacion = Column(String(20), nullable=True)
50
44
  fechaResultado = Column(String(20), nullable=True)
51
45
 
@@ -57,7 +51,6 @@ class ProspectsLibertador(BaseSoftseguros):
57
51
 
58
52
 
59
53
  class ProspectsToSecure(BaseSoftseguros):
60
- #__tablename__ = "safe_prospects_bolivar"
61
54
  __tablename__= "prospects_to_secure"
62
55
 
63
56
  contrato_solicitud = Column(String(20), primary_key=True)
@@ -76,16 +69,12 @@ class ProspectsToSecure(BaseSoftseguros):
76
69
  departamento = Column(String(100), nullable=True, default="ANTIOQUIA")
77
70
  ciudad = Column(String(100), nullable=True)
78
71
 
79
- # puede ser "47205" o "47205,47206" según tu uso actual
80
72
  ids_categorias = Column(String(255), nullable=True)
81
73
 
82
- # si la manejas como datetime/date en Python, SQLAlchemy lo mapea directo
83
74
  fecha_expedicion_cedula = Column(String(20), nullable=True)
84
75
 
85
- # si quieres más precisión usa Numeric(18, 2)
86
76
  ingreso_mensual = Column(Float, nullable=True)
87
77
 
88
- # aquí guardas el JSON/string de Observations
89
78
  observaciones = Column(Text, nullable=True)
90
79
 
91
80
  type = Column(String(30), nullable=True)
@@ -119,7 +119,7 @@ def shipment_message_prospect_from_softin(phones: List[str], data: DataNotificat
119
119
  "id": "fdfe8742-fe86-4992-8705-ea69cc11f42c",
120
120
  "params": [
121
121
  data.name_landlord, # "Nombre propietario"
122
- data.document_landlord, # "Documento propietario"
122
+ data.document_landlord, # "Documento propietario"
123
123
  data.phone_landlor, # "Celular propietario"
124
124
  data.name_tenant, # "Nombre inquilino"
125
125
  data.document_tenant, # "documento_inquilino"
@@ -134,6 +134,7 @@ def shipment_message_prospect_from_softin(phones: List[str], data: DataNotificat
134
134
  "number": phone,
135
135
  }
136
136
  response = client.post(url, headers=headers, json=payload)
137
+ result.append(response.status_code)
137
138
  print(f"Codigo de respuesta del envio: {response.status_code}")
138
139
  print(f"Resultado del envio: {response.text}")
139
140
  time.sleep(5)
@@ -165,15 +166,7 @@ def notify_prospect_from_softin():
165
166
  elif record[1].type == "propietario":
166
167
  propietario = record[1]
167
168
 
168
-
169
- record_ = DataNotificationSofint(name_landlord=propietario.nombres,
170
- document_tenant=propietario.numero_documento,
171
- phone_landlor=propietario.telefono,
172
- name_tenant=inquilino.nombres,
173
- document_landlord=inquilino.numero_documento,
174
- phone_tenant=inquilino.telefono,
175
- real_state=inquilino.real_state
176
- )
169
+ record_ = DataNotificationSofint(name_landlord=propietario.nombres, document_tenant=propietario.numero_documento, phone_landlor=propietario.telefono, name_tenant=inquilino.nombres, document_landlord=inquilino.numero_documento, phone_tenant=inquilino.telefono, real_state=inquilino.real_state)
177
170
 
178
171
  result = shipment_message_prospect_from_softin(PHONES, record_)
179
172
 
@@ -233,7 +226,7 @@ def shipment_new_prospect_from_libertador(phones: List[str], data: DataNotificat
233
226
  def notify_prospect_from_libertador():
234
227
  records = select_not_notified(source="libertador")
235
228
  for record in records:
236
- record_ = DataNotificationpLibertador(name=record.nombres, document=record.numero_documento,phone=record.telefono, real_state=record.real_state)
229
+ record_ = DataNotificationpLibertador(name=record.nombres, document=record.numero_documento, phone=record.telefono, real_state=record.real_state)
237
230
 
238
231
  result = shipment_new_prospect_from_libertador(PHONES, record_)
239
232
 
@@ -1,5 +0,0 @@
1
- execute_synchronization
2
- main
3
- main2
4
- softseguros
5
- tests
@@ -1,443 +0,0 @@
1
- """
2
- Módulo para la sincronización de datos entre el sistema Libertador y Softseguros.
3
- Gestiona la sincronización de clientes, solicitudes y notificaciones para diferentes inmobiliarias.
4
-
5
- primero se ejecuta el endpoint request_a_one_day_range en un rango de fechas y para todos los
6
- estados disponibles (State), estos registros se crean en base de datos, esto permite tener toda
7
- la informacion completa en base de datos de todas las solicitudes, luego se utiliza el endpoint
8
- data_unique para actualizar solicitudes pasadas que tenga un estado
9
-
10
- """
11
-
12
- import copy
13
- import os
14
- from datetime import datetime
15
- from typing import Any, List, Union
16
-
17
- from dotenv import load_dotenv
18
- from loguru import logger
19
-
20
- from softseguros.api_libertador.api import DetailByDataFull, RequestDataUnique, ServiceAPILibertador
21
- from softseguros.api_softseguros.api_softseguros import Observations, RequestsCreateCustomerSoftseguros, ServiceAPISoftSeguros
22
- from src.database.config_db import session_castillo, session_estrella, session_livin, session_villacruz
23
- from src.database.repository import Libertador, get_approved_records, get_records_with_state_postponed, insert_record, update_state_solicitud
24
- from softseguros.notifier.notificaciones import shipment_message_customers_libertador
25
-
26
- load_dotenv()
27
-
28
- # phones = os.getenv("PHONES")
29
- # phones = ast.literal_eval(phones)
30
- phones = ["573165241659", "573013853937", "573006538383"]
31
-
32
-
33
-
34
- def with_point(n: Union[int, float, str]) -> str:
35
- """
36
- Formatea un número con puntos como separador de miles.
37
-
38
- Args:
39
- n: Número a formatear (puede ser entero, decimal o string)
40
-
41
- Returns:
42
- str: Número formateado con puntos como separador de miles
43
- """
44
- return f"{int(n):,}".replace(",", ".")
45
-
46
-
47
- class Company:
48
- name: str
49
- numero_inmobiliaria: str
50
- client_id: str
51
- client_secret: str
52
- username: str = os.getenv("USERNAME_SOFTSEGUROS", "")
53
- password: str = os.getenv("USERNAME_PASSWORD_SOFTSEGUROS", "")
54
- categories: str
55
- session: Any
56
- phone_numbers: List[str] = phones
57
-
58
-
59
- class Estrella(Company):
60
- """
61
- Configuración específica para la inmobiliaria Estrella.
62
-
63
- Attributes:
64
- name: Identificador de la inmobiliaria
65
- numero_inmobiliaria: NIT de la inmobiliaria
66
- client_id: ID de cliente para API Libertador
67
- client_secret: Secreto de cliente para API Libertador
68
- categories: Categorías en Softseguros (47205: La Estrella, 47664: Común)
69
- session: Sesión de base de datos específica
70
- """
71
-
72
- name: str = "estrella"
73
- numero_inmobiliaria: str = "800018892"
74
- client_id: str = os.getenv("CLIENT_ID_ESTRELLA", "")
75
- client_secret: str = os.getenv("CLIENT_SECRET_ESTRELLA", "")
76
- categories: str = "47205,47664"
77
- session: Any = session_estrella
78
-
79
-
80
- class Castillo(Company):
81
- """
82
- Configuración específica para la inmobiliaria Castillo.
83
-
84
- Attributes:
85
- name: Identificador de la inmobiliaria
86
- numero_inmobiliaria: NIT de la inmobiliaria
87
- client_id: ID de cliente para API Libertador
88
- client_secret: Secreto de cliente para API Libertador
89
- categories: Categorías en Softseguros (47203: Castillo, 47664: Común)
90
- session: Sesión de base de datos específica
91
- """
92
-
93
- name: str = "castillo"
94
- numero_inmobiliaria: str = "890930984"
95
- client_id: str = os.getenv("CLIENT_ID_CASTILLO", "")
96
- client_secret: str = os.getenv("CLIENT_SECRET_CASTILLO", "")
97
- categories: str = "47203,47664"
98
- session: Any = session_castillo
99
-
100
-
101
- class Villacruz(Company):
102
- """
103
- Configuración específica para la inmobiliaria Villacruz.
104
-
105
- Attributes:
106
- name: Identificador de la inmobiliaria
107
- numero_inmobiliaria: NIT de la inmobiliaria
108
- client_id: ID de cliente para API Libertador
109
- client_secret: Secreto de cliente para API Libertador
110
- categories: Categorías en Softseguros (47202: Villacruz, 47664: Común)
111
- session: Sesión de base de datos específica
112
- """
113
-
114
- name: str = "villacruz"
115
- numero_inmobiliaria: str = "890918082"
116
- client_id: str = os.getenv("CLIENT_ID_VILLACRUZ", "")
117
- client_secret: str = os.getenv("CLIENT_SECRET_VILLACRUZ", "")
118
- categories: str = "47202,47664"
119
- session: Any = session_villacruz
120
-
121
-
122
- class Livin(Company):
123
- """
124
- Configuración específica para la inmobiliaria Livin.
125
-
126
- Attributes:
127
- name: Identificador de la inmobiliaria
128
- numero_inmobiliaria: NIT de la inmobiliaria
129
- client_id: ID de cliente para API Libertador
130
- client_secret: Secreto de cliente para API Libertador
131
- categories: Categorías en Softseguros (47204: Livin, 47664: Común)
132
- session: Sesión de base de datos específica
133
- """
134
-
135
- name: str = "livin"
136
- numero_inmobiliaria: str = "900635562"
137
- client_id: str = os.getenv("CLIENT_ID_LIVIN", "")
138
- client_secret: str = os.getenv("CLIENT_SECRET_LIVIN", "")
139
- categories: str = "47204,47664"
140
- session: Any = session_livin
141
-
142
-
143
- def synchronize_libertador_table_from_estrella_by_day() -> None:
144
- """
145
- Ejecuta la sincronización completa para la inmobiliaria Estrella.
146
-
147
- Este proceso incluye:
148
- 1. Sincronización de datos diarios desde Libertador
149
- 2. Actualización de solicitudes específicas
150
- 3. Creación de clientes en Softseguros
151
- 4. Notificación a asesores
152
- """
153
- logger.info("Iniciando sincronización para inmobiliaria Estrella")
154
- synchronize_libertador_table_by_day(company=Estrella)
155
- synchronize_libertador_table_by_solicitud(company=Estrella)
156
- result_create_customer_in_softseguros = create_customer_in_softseguros(company=Estrella)
157
- notify_advisor_softseguros(company=Estrella, data_customers=result_create_customer_in_softseguros)
158
- logger.info("Finalizada sincronización para inmobiliaria Estrella")
159
-
160
-
161
- def synchronize_libertador_table_from_livin_by_day() -> None:
162
- """
163
- Ejecuta la sincronización completa para la inmobiliaria Livin.
164
-
165
- Este proceso incluye:
166
- 1. Sincronización de datos diarios desde Libertador
167
- 2. Actualización de solicitudes específicas
168
- 3. Creación de clientes en Softseguros
169
- 4. Notificación a asesores
170
- """
171
- logger.info("Iniciando sincronización para inmobiliaria Livin")
172
- synchronize_libertador_table_by_day(company=Livin)
173
- synchronize_libertador_table_by_solicitud(company=Livin)
174
- result_create_customer_in_softseguros = create_customer_in_softseguros(company=Livin)
175
- notify_advisor_softseguros(company=Livin, data_customers=result_create_customer_in_softseguros)
176
- logger.info("Finalizada sincronización para inmobiliaria Livin")
177
-
178
-
179
- def synchronize_libertador_table_from_villacruz_by_day() -> None:
180
- """
181
- Ejecuta la sincronización completa para la inmobiliaria Villacruz.
182
-
183
- Este proceso incluye:
184
- 1. Sincronización de datos diarios desde Libertador
185
- 2. Actualización de solicitudes específicas
186
- 3. Creación de clientes en Softseguros
187
- 4. Notificación a asesores
188
- """
189
- logger.info("Iniciando sincronización para inmobiliaria Villacruz")
190
- synchronize_libertador_table_by_day(company=Villacruz)
191
- synchronize_libertador_table_by_solicitud(company=Villacruz)
192
- result_create_customer_in_softseguros = create_customer_in_softseguros(company=Villacruz)
193
- notify_advisor_softseguros(company=Villacruz, data_customers=result_create_customer_in_softseguros)
194
- logger.info("Finalizada sincronización para inmobiliaria Villacruz")
195
-
196
-
197
- def synchronize_libertador_table_from_castillo_by_day() -> None:
198
- """
199
- Ejecuta la sincronización completa para la inmobiliaria Castillo.
200
-
201
- Este proceso incluye:
202
- 1. Sincronización de datos diarios desde Libertador
203
- 2. Actualización de solicitudes específicas
204
- 3. Creación de clientes en Softseguros
205
- 4. Notificación a asesores
206
- """
207
- logger.info("Iniciando sincronización para inmobiliaria Castillo")
208
- synchronize_libertador_table_by_day(company=Castillo)
209
- synchronize_libertador_table_by_solicitud(company=Castillo)
210
- result_create_customer_in_softseguros = create_customer_in_softseguros(company=Castillo)
211
- notify_advisor_softseguros(company=Castillo, data_customers=result_create_customer_in_softseguros)
212
- logger.info("Finalizada sincronización para inmobiliaria Castillo")
213
-
214
-
215
- def synchronize_libertador_table_by_day(company: Company) -> None:
216
- """
217
- Sincroniza los datos de clientes desde Libertador a la base de datos local.
218
-
219
- Args:
220
- company: Instancia de Company con la configuración de la inmobiliaria
221
-
222
- Este proceso:
223
- 1. Consulta las solicitudes del día en Libertador
224
- 2. Filtra los clientes con tipo de identificación CC
225
- 3. Actualiza o inserta los registros en la base de datos local
226
- """
227
- logger.info(f"Iniciando sincronización diaria para {company.name}")
228
-
229
- # Inicialización del servicio
230
- service_libertador = ServiceAPILibertador(client_id=company.client_id, client_secret=company.client_secret)
231
-
232
- # Consultar solicitudes por día
233
- result = service_libertador.request_a_one_day_range()
234
-
235
- customers: List[DetailByDataFull] = result.data
236
- if customers is None:
237
- logger.warning(f"No se encontraron clientes para sincronizar en {company.name}: {customers=}")
238
- return
239
-
240
- logger.info(f"Numero de customers para cargar a DB: {len(customers)}")
241
-
242
- # ACTUALIZAR REGISTROS EN DB
243
- for customer in customers:
244
- if customer.tipoIdentificacion == "CC":
245
- # + REGISTRAR EN BASE DE DATOS LIBERTADOR LAS SOLICITUDES
246
- record = {}
247
- record["solicitud"] = customer.solicitud
248
- record["fecha_radicacion"] = datetime.strptime(customer.fechaRadicacion, "%d/%m/%Y %H:%M:%S")
249
- record["fecha_resultado"] = datetime.strptime(customer.fechaResultado, "%d/%m/%Y %H:%M:%S")
250
- record["resultado"] = customer.estadoGeneral
251
- record["destino"] = customer.destinoInmueble
252
- record["tipo_persona"] = "Natural"
253
- record["ciudad"] = customer.ciudadInmueble
254
- record["direccion"] = customer.direccionInmueble
255
- record["numero_inmobiliaria"] = company.numero_inmobiliaria
256
- record["nombre_inquilino"] = customer.nombreInquilino
257
- record["numero_inquilino"] = customer.telefonoInquilino
258
- record["nombre_asesor"] = customer.nombreAsesor
259
- record["correo_asesor"] = customer.correoAsesor
260
- record["documento_inquilino"] = customer.identificacionInquilino
261
- record["canon"] = customer.canon
262
- record["correo"] = customer.correoInquilino
263
- record["fecha_expedicion"] = customer.fechaExpedicion
264
- record["ingresos"] = customer.ingresos
265
-
266
- for key, value in record.items():
267
- if value == "No Registra":
268
- record[key]= None
269
-
270
- obj = Libertador(**record)
271
- insert_record(obj, company.session)
272
- logger.info(f"Solicitud: {customer.solicitud, customer.estadoGeneral} actualizada/insertada")
273
-
274
-
275
- def synchronize_libertador_table_by_solicitud(company: Company) -> None:
276
- """
277
- Sincroniza el estado de las solicitudes aplazadas con Libertador.
278
-
279
- Args:
280
- company: Instancia de Company con la configuración de la inmobiliaria
281
-
282
- Este proceso:
283
- 1. Obtiene todas las solicitudes con estado "APLAZADO-NUBE" o "APLAZADA"
284
- 2. Consulta el estado actual en Libertador
285
- 3. Actualiza a "APROBADA" si el código de resultado es "01"
286
- """
287
- logger.info(f"Iniciando sincronización de solicitudes aplazadas para {company.name}")
288
-
289
- # Inicialización del servicio
290
- service_libertador = ServiceAPILibertador(client_id=company.client_id, client_secret=company.client_secret)
291
-
292
- # Sincronización de solicitudes con estados ("APLAZADO-NUBE", "APLAZADA")
293
- records_db = get_records_with_state_postponed(company.session)
294
- logger.info(f"Número de solicitudes aplazadas para validar: {len(records_db)}")
295
-
296
- for record_db in records_db:
297
- logger.debug(f"Procesando solicitud: {record_db.solicitud}")
298
- if not record_db.solicitud:
299
- logger.warning("Encontrada solicitud sin número, omitiendo")
300
- continue
301
-
302
- results = service_libertador.data_unique(data=RequestDataUnique(solicitud=str(record_db.solicitud)))
303
- if not results.status:
304
- logger.warning(f"No se pudo obtener información de la solicitud {record_db.solicitud}")
305
- continue
306
-
307
- for record_api in results.data:
308
- if record_api.codigoResultado == "01":
309
- obj = copy.deepcopy(record_db)
310
- obj.resultado = "APROBADA"
311
- insert_record(obj, company.session)
312
- logger.info(f"Solicitud {obj.solicitud} actualizada a estado {obj.resultado}")
313
-
314
-
315
- def create_customer_in_softseguros(company: Company) -> List[List[str]]:
316
- """
317
- Crea clientes en Softseguros a partir de las solicitudes aprobadas en la base de datos.
318
-
319
- Args:
320
- company: Instancia de Company con la configuración de la inmobiliaria
321
-
322
- Returns:
323
- List[List[str]]: Lista de clientes creados exitosamente, cada cliente es una lista con:
324
- [solicitud, documento_inquilino, nombre_inquilino, numero_inquilino]
325
-
326
- Este proceso:
327
- 1. Obtiene todas las solicitudes aprobadas de la base de datos
328
- 2. Para cada solicitud, calcula el valor comercial según el canon
329
- 3. Crea el cliente en Softseguros con la información necesaria
330
- 4. Registra el resultado de la creación
331
- """
332
- logger.info(f"Iniciando creación de clientes en Softseguros para {company.name}")
333
- api_softseguros = ServiceAPISoftSeguros(username=company.username, password=company.password)
334
-
335
- # Consultar todos los posibles clientes con solicitud aprobada en DB
336
- customer_db = get_approved_records(company.session)
337
- logger.info(f"Encontrados {len(customer_db)} clientes con solicitud aprobada")
338
-
339
- created_customer_result: List[List[str]] = []
340
- for cust_db in customer_db:
341
- if not cust_db.documento_inquilino:
342
- logger.warning(f"Cliente en solicitud {cust_db.solicitud} sin documento, omitiendo")
343
- continue
344
-
345
- fecha_expedicion = cust_db.fecha_expedicion
346
- if fecha_expedicion is None or fecha_expedicion == "No Registra":
347
- cust_db.fecha_expedicion = None
348
- else:
349
- if isinstance(fecha_expedicion, datetime):
350
- cust_db.fecha_expedicion= fecha_expedicion.date().strftime("%Y-%m-%d")
351
- elif isinstance(fecha_expedicion, str):
352
- cust_db.fecha_expedicion = datetime.fromisoformat(fecha_expedicion.replace("T", " ")).date().strftime("%Y-%m-%d")
353
-
354
-
355
- observations = Observations(canon=cust_db.canon, destinacion=cust_db.destino, asesor=cust_db.nombre_asesor, correoAsesor=cust_db.correo_asesor)
356
- obs = str(observations.model_dump(mode="json"))
357
-
358
- new_customer_softseguros = RequestsCreateCustomerSoftseguros(
359
- numero_documento=cust_db.documento_inquilino,
360
- nombres=cust_db.nombre_inquilino,
361
- direccion=cust_db.direccion,
362
- telefono=cust_db.numero_inquilino,
363
- celular=cust_db.numero_inquilino,
364
- email=cust_db.correo,
365
- observaciones=obs,
366
- ids_categorias=company.categories,
367
- ciudad=cust_db.ciudad,
368
- fecha_expedicion_cedula=cust_db.fecha_expedicion,
369
- ingreso_mensual=str(cust_db.ingresos),
370
- )
371
-
372
- logger.info(f"Inicia creacion en softseguros para el cliente: {cust_db.documento_inquilino=}")
373
- resp_create_customer = api_softseguros.create_customer(new_customer_softseguros)
374
- logger.info(f"Resultado de creacion en softseguros del cliente: {cust_db.documento_inquilino=}: {resp_create_customer=}")
375
- if resp_create_customer.get("status"):
376
- logger.info(f"Cliente {cust_db.documento_inquilino} creado exitosamente en Softseguros")
377
- logger.debug(f"Detalles del cliente creado: {new_customer_softseguros}")
378
- created_customer_result.append([cust_db.solicitud, cust_db.documento_inquilino, cust_db.nombre_inquilino, cust_db.numero_inquilino])
379
- else:
380
- logger.error(f"Error al crear cliente {cust_db.documento_inquilino} en Softseguros\nDetalles: {new_customer_softseguros}")
381
-
382
- logger.info(f"Proceso finalizado. {len(created_customer_result)} clientes creados en Softseguros")
383
- return created_customer_result
384
-
385
-
386
- def notify_advisor_softseguros(company: Company, data_customers: List[List[str]]) -> None:
387
- """
388
- Notifica a los asesores sobre los nuevos clientes creados en Softseguros.
389
-
390
- Args:
391
- company: Instancia de Company con la configuración de la inmobiliaria
392
- data_customers: Lista de clientes creados, cada cliente es una lista con:
393
- [solicitud, documento_inquilino, nombre_inquilino, numero_inquilino]
394
-
395
- Este proceso:
396
- 1. Envía mensajes a los asesores con la información de los clientes creados
397
- 2. Actualiza el estado de las solicitudes a notificadas
398
- """
399
- logger.info(f"Iniciando notificación a asesores de {company.name}")
400
- logger.debug(f"Números de teléfono de asesores: {company.phone_numbers}")
401
-
402
- if not data_customers:
403
- logger.info("No hay clientes nuevos para notificar")
404
- return
405
-
406
- # Enviar notificaciones a los asesores
407
- shipment_message_customers_libertador(phone_advisers=company.phone_numbers, data_customers=data_customers, real_state=company.name)
408
-
409
- # Actualizar estado de las solicitudes
410
- for customer in data_customers:
411
- solicitud = customer[0] # El primer elemento es el número de solicitud
412
- update_state_solicitud(solicitud, True, company.session)
413
- logger.debug(f"Actualizado estado de notificación para solicitud {solicitud}")
414
-
415
- logger.info(f"Completada notificación de {len(data_customers)} clientes a los asesores")
416
-
417
-
418
- if __name__ == "__main__":
419
- username = os.getenv("USERNAME_SOFTSEGUROS")
420
- password = os.getenv("USERNAME_PASSWORD_SOFTSEGUROS")
421
- api_softseguros = ServiceAPISoftSeguros(username=username, password=password)
422
-
423
- # 3610548
424
- category_estrella = {"id": 47205, "nombre": "La Estrella", "color": "#28a187", "tipo": "cliente"}
425
- customer = {"canon": 1800000, "identificacionInquilino": "10072325404", "nombreInquilino": "Juan V", "direccionInmueble": "Direcciion prueba", "telefonoInquilino": "573103555748", "correoInquilino": "juan@gmail.com"}
426
- observations = Observations(canon=customer.get("canon"))
427
- new_customer_softseguros = RequestsCreateCustomerSoftseguros(
428
- numero_documento=customer.get("identificacionInquilino"),
429
- nombres=customer.get("nombreInquilino"),
430
- direccion=customer.get("direccionInmueble"),
431
- telefono=customer.get("telefonoInquilino"),
432
- celular=customer.get("telefonoInquilino"),
433
- email=customer.get("correoInquilino"),
434
- observations=observations,
435
- ids_categorias=str(category_estrella.get("id")),
436
- )
437
-
438
- resp_create_customer = api_softseguros.create_customer(new_customer_softseguros)
439
-
440
-
441
-
442
- # para consultar
443
- # 1039048054,
@@ -1,114 +0,0 @@
1
- from datetime import datetime
2
- from typing import List
3
-
4
- from dotenv import load_dotenv
5
- from loguru import logger
6
- from sqlalchemy import Boolean, Column, DateTime, Integer, String, and_, or_, select
7
- from sqlalchemy.orm import Session, declarative_base
8
-
9
- load_dotenv()
10
-
11
- Base = declarative_base()
12
-
13
-
14
- class Libertador(Base):
15
- __tablename__ = "libertador3"
16
- solicitud = Column(Integer, primary_key=True)
17
- fecha_radicacion = Column(DateTime)
18
- fecha_resultado = Column(DateTime)
19
- resultado = Column(String(50))
20
- destino = Column(String(50))
21
- tipo_persona = Column(String(30))
22
- ciudad = Column(String(50))
23
- direccion = Column(String(100))
24
- numero_inmobiliaria = Column(String(30))
25
- nombre_inquilino = Column(String(100))
26
- numero_inquilino = Column(String(30))
27
- nombre_asesor = Column(String(100))
28
- correo_asesor = Column(String(100))
29
- fecha_actualizacion = Column(DateTime)
30
- notified = Column(Boolean, nullable=False, default=False)
31
- documento_inquilino = Column(String(20))
32
- canon = Column(String(20))
33
- correo = Column(String(100))
34
- fecha_expedicion = Column(String(50))
35
- ingresos = Column(String(20))
36
-
37
-
38
- class SoftsegurosAdvisorNotifications(Base):
39
- __tablename__ = "softseguros_advisor_notifications"
40
- solicitud = Column(Integer, primary_key=True)
41
- notified = Column(Boolean, nullable=False, default=False)
42
-
43
-
44
- def insert_record(record: Libertador, session_: Session):
45
- with session_() as session:
46
- # Asegura tipos (evita marcar PK como cambiado por str vs int)
47
- record.solicitud = int(record.solicitud)
48
- try:
49
- record.fecha_expedicion = datetime.fromisoformat(record.fecha_expedicion.replace("T", " ")).date()
50
- except Exception:
51
- ...
52
- current: Libertador = session.get(Libertador, record.solicitud)
53
- if current:
54
- # actualiza SOLO campos no-PK
55
- current.fecha_radicacion = record.fecha_radicacion
56
- current.fecha_resultado = record.fecha_resultado
57
- current.resultado = record.resultado
58
- current.destino = record.destino
59
- current.tipo_persona = record.tipo_persona
60
- current.ciudad = record.ciudad
61
- current.direccion = record.direccion
62
- current.numero_inmobiliaria = record.numero_inmobiliaria
63
- current.nombre_inquilino = record.nombre_inquilino
64
- current.numero_inquilino = record.numero_inquilino
65
- current.nombre_asesor = record.nombre_asesor
66
- current.correo_asesor = record.correo_asesor
67
- current.fecha_actualizacion = record.fecha_actualizacion
68
- current.documento_inquilino = record.documento_inquilino
69
- current.canon = record.canon
70
- current.correo = record.correo
71
- current.fecha_expedicion = record.fecha_expedicion
72
- current.ingresos = record.ingresos
73
- logger.info(f"Registro actualizado -> solicitud:{record.solicitud}")
74
- else:
75
- session.add(record) # INSERT (no intenta tocar el PK en UPDATE)
76
- logger.info(f"Registro insertado -> solicitud:{record.solicitud}")
77
- session.commit()
78
-
79
-
80
- def select_record(solicitud: int, session_: Session):
81
- with session_() as session:
82
- stmt = select(Libertador).filter(and_(Libertador.solicitud == solicitud, Libertador.notified == False))
83
- record = session.scalars(statement=stmt).all()
84
- return record
85
-
86
-
87
- def get_approved_records(session_: Session) -> List[Libertador]:
88
- with session_() as session:
89
- stmt = select(Libertador).filter(and_(Libertador.resultado == "APROBADA", Libertador.notified == False))
90
- records = session.scalars(statement=stmt).all()
91
- logger.info(f"Registros libertador aprobados: {len(records)=}")
92
- return records
93
-
94
-
95
- def get_records_with_state_postponed(session_: Session) -> List[Libertador]:
96
- with session_() as session:
97
- stmt = select(Libertador).filter(or_(Libertador.resultado == "APLAZADO-NUBE", Libertador.resultado == "APLAZADA"))
98
- records = session.scalars(statement=stmt).all()
99
- return records
100
-
101
-
102
- def update_state_solicitud(solicitud: int, state, session_: Session):
103
- with session_() as session:
104
- stmt = select(Libertador).filter(Libertador.solicitud == solicitud)
105
- record = session.scalars(statement=stmt).first()
106
- record.notified = state
107
- session.commit()
108
- logger.info(f"Registro actualizado -> {solicitud=}")
109
- return record
110
-
111
-
112
- if __name__ == "__main__":
113
- # Base.metadata.create_all(engine_estrella)
114
- ...