pyEscoAPI 0.0.39__tar.gz → 0.0.41__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyEscoAPI
3
- Version: 0.0.39
3
+ Version: 0.0.41
4
4
  Summary: Python client for Esco API (Esco bolsa)
5
5
  Author-email: Codetria <hola@codetria.com>
6
6
  License: MIT License
@@ -191,3 +191,61 @@ class Instrucciones:
191
191
  @dataclass
192
192
  class EntMailing:
193
193
  codEntMailing: int
194
+
195
+
196
+ @dataclass
197
+ class MovimientoMoneda:
198
+ importe: float
199
+ moneda: str
200
+ tpCambioMovPais: float
201
+ codCtaContable: int
202
+ codCentroCost: int
203
+ esCredito: bool
204
+
205
+
206
+ @dataclass
207
+ class MovimientoTitulo:
208
+ instrumento: str
209
+ codTpInstrumento: str
210
+ codAgenteDepo: int
211
+ cantidad: float
212
+ precio: float
213
+ esCredito: bool
214
+
215
+
216
+ @dataclass
217
+ class MovimientoArancel:
218
+ importe: float
219
+ moneda: str
220
+ tpCambioArPais: float
221
+ codTpIVABase: str
222
+ codTpIVASTasa: str
223
+
224
+
225
+ @dataclass
226
+ class MovimientoDerecho:
227
+ tipoDerecho: str
228
+ importe: float
229
+ moneda: str
230
+ tpCambioDerPais: float
231
+ ivaDerecho: str
232
+ sobreTasa: str
233
+
234
+
235
+ @dataclass
236
+ class MovimientoRetencionIIBB:
237
+ importe: float
238
+ moneda: str
239
+ tpCambioRetPais: float
240
+ codProvincia: int
241
+ codPais: int
242
+
243
+
244
+ @dataclass
245
+ class MovimientoComision:
246
+ codAgenteDepo: int
247
+ importe: float
248
+ moneda: str
249
+ tpCambioComPais: float
250
+ codTpIVABaseCom: str
251
+ codCtaContable: int
@@ -9,7 +9,16 @@ from typing import TypedDict
9
9
  import requests
10
10
  from requests import Response
11
11
 
12
- from pyEscoAPI.dataclasses import Persona, ComitenteData
12
+ from pyEscoAPI.dataclasses import (
13
+ ComitenteData,
14
+ MovimientoArancel,
15
+ MovimientoComision,
16
+ MovimientoDerecho,
17
+ MovimientoMoneda,
18
+ MovimientoRetencionIIBB,
19
+ MovimientoTitulo,
20
+ Persona,
21
+ )
13
22
  from pyEscoAPI.exception import PyEscoAPIError
14
23
 
15
24
  logger = logging.getLogger(f"app.{__name__}")
@@ -1405,6 +1414,47 @@ class EscoAPI:
1405
1414
  request_method=HTTPMethod.POST
1406
1415
  )
1407
1416
 
1417
+ def get_transferencia_titulos(
1418
+ self,
1419
+ cuentas: str | None = None,
1420
+ fecha_desde: date | None = None,
1421
+ fecha_hasta: date | None = None,
1422
+ cod_tp_transferencia_tit_mov: str | None = None,
1423
+ por_concertacion: bool = True,
1424
+ es_consolidado: bool = False,
1425
+ incluye_anulado: bool = False,
1426
+ ):
1427
+ """
1428
+ Devuelve las transferencias de títulos de las cuentas comitente solicitadas.
1429
+ :param cuentas: Lista de números de cuentas comitente. Se puede ingresar una sola cuenta o una lista separada por comas.
1430
+ :param fecha_desde: Fecha inicial de la consulta.
1431
+ :param fecha_hasta: Fecha final de la consulta.
1432
+ :param cod_tp_transferencia_tit_mov: Código del tipo de transferencia de títulos.
1433
+ :param por_concertacion: Indica si las transferencias se buscan por fecha de concertación.
1434
+ :param es_consolidado: Indica si se informan las transferencias de todas las cuentas vinculadas al usuario.
1435
+ :param incluye_anulado: Indica si se incluyen las transferencias anuladas.
1436
+ """
1437
+ if fecha_desde is None:
1438
+ fecha_desde = date.today() - timedelta(days=30)
1439
+ if fecha_hasta is None:
1440
+ fecha_hasta = date.today()
1441
+
1442
+ req_body = {
1443
+ "cuentas": cuentas,
1444
+ "fechaDesde": fecha_desde.strftime("%Y-%m-%d"),
1445
+ "fechaHasta": fecha_hasta.strftime("%Y-%m-%d"),
1446
+ "codTpTransferenciaTitMov": cod_tp_transferencia_tit_mov,
1447
+ "porConcertacion": por_concertacion,
1448
+ "esConsolidado": es_consolidado,
1449
+ "incluyeAnulado": incluye_anulado,
1450
+ }
1451
+ self.__pre_connection()
1452
+ return self.__make_request(
1453
+ request_endpoint="/get-transferencia-titulos",
1454
+ request_body=req_body,
1455
+ request_method=HTTPMethod.POST,
1456
+ )
1457
+
1408
1458
  def get_liquidaciones_fondos(
1409
1459
  self,
1410
1460
  cuentas: str = None,
@@ -2070,6 +2120,80 @@ class EscoAPI:
2070
2120
  request_method=HTTPMethod.POST,
2071
2121
  )
2072
2122
 
2123
+ def insert_movimiento_manual(
2124
+ self,
2125
+ cuenta: int,
2126
+ fecha_concertacion: date,
2127
+ fecha_liquidacion: date,
2128
+ descripcion: str,
2129
+ cod_tp_movimiento_manual: str,
2130
+ observaciones: str | None = None,
2131
+ num_referencia: int | None = None,
2132
+ mercado: str | None = None,
2133
+ se_informa: bool = True,
2134
+ permite_movimiento_feriado: bool = True,
2135
+ permite_descubierto: bool = True,
2136
+ controla_duplicidad: bool = False,
2137
+ movimientos_moneda: list[MovimientoMoneda] | None = None,
2138
+ movimientos_titulo: list[MovimientoTitulo] | None = None,
2139
+ movimientos_arancel: list[MovimientoArancel] | None = None,
2140
+ movimientos_derecho: list[MovimientoDerecho] | None = None,
2141
+ movimientos_retenciones_iibb: list[MovimientoRetencionIIBB] | None = None,
2142
+ movimientos_comisiones: list[MovimientoComision] | None = None,
2143
+ ):
2144
+ """
2145
+ Ingresa un movimiento manual en la cuenta corriente del comitente.
2146
+ :param cuenta: Número de cuenta comitente.
2147
+ :param fecha_concertacion: Fecha de concertación del movimiento.
2148
+ :param fecha_liquidacion: Fecha de liquidación del movimiento.
2149
+ :param descripcion: Descripción del movimiento.
2150
+ :param cod_tp_movimiento_manual: Código del tipo de movimiento manual.
2151
+ :param observaciones: Observaciones del movimiento.
2152
+ :param num_referencia: Número de referencia del movimiento.
2153
+ :param mercado: Código del mercado.
2154
+ :param se_informa: Indica si el movimiento se informa.
2155
+ :param permite_movimiento_feriado: Indica si se permite cargar el movimiento en un feriado.
2156
+ :param permite_descubierto: Indica si se permite dejar la cuenta en descubierto.
2157
+ :param controla_duplicidad: Indica si se debe controlar duplicidad del movimiento.
2158
+ :param movimientos_moneda: Movimientos de moneda asociados.
2159
+ :param movimientos_titulo: Movimientos de títulos asociados.
2160
+ :param movimientos_arancel: Aranceles asociados.
2161
+ :param movimientos_derecho: Derechos asociados.
2162
+ :param movimientos_retenciones_iibb: Retenciones de ingresos brutos asociadas.
2163
+ :param movimientos_comisiones: Comisiones asociadas.
2164
+ """
2165
+ if fecha_concertacion is None:
2166
+ fecha_concertacion = date.today()
2167
+ if fecha_liquidacion is None:
2168
+ fecha_liquidacion = date.today()
2169
+
2170
+ req_body = {
2171
+ "cuenta": cuenta,
2172
+ "fechaConcertacion": fecha_concertacion.isoformat(),
2173
+ "fechaLiquidacion": fecha_liquidacion.isoformat(),
2174
+ "descripcion": descripcion,
2175
+ "codTpMovimientoManual": cod_tp_movimiento_manual,
2176
+ "observaciones": observaciones,
2177
+ "numReferencia": num_referencia,
2178
+ "mercado": mercado,
2179
+ "seInforma": se_informa,
2180
+ "permiteMovimientoFeriado": permite_movimiento_feriado,
2181
+ "permiteDescubierto": permite_descubierto,
2182
+ "controlaDuplicidad": controla_duplicidad,
2183
+ "movimientosMoneda": [asdict(item) for item in (movimientos_moneda or [])],
2184
+ "movimientosTitulo": [asdict(item) for item in (movimientos_titulo or [])],
2185
+ "movimientosArancel": [asdict(item) for item in (movimientos_arancel or [])],
2186
+ "movimientosDerecho": [asdict(item) for item in (movimientos_derecho or [])],
2187
+ "movimientosRetencionesIIBB": [asdict(item) for item in (movimientos_retenciones_iibb or [])],
2188
+ "movimientosComisiones": [asdict(item) for item in (movimientos_comisiones or [])],
2189
+ }
2190
+ self.__pre_connection()
2191
+ return self.__make_request(
2192
+ request_endpoint="/insert-movimiento-manual",
2193
+ request_body=req_body,
2194
+ request_method=HTTPMethod.POST,
2195
+ )
2196
+
2073
2197
  def get_domicilio_cuenta_comitente(self, cuenta: str, cod_tp_domicilio: str):
2074
2198
  """
2075
2199
  Devuelve el domicilio de una cuenta comitente.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyEscoAPI
3
- Version: 0.0.39
3
+ Version: 0.0.41
4
4
  Summary: Python client for Esco API (Esco bolsa)
5
5
  Author-email: Codetria <hola@codetria.com>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = 'pyEscoAPI'
7
- version = "0.0.39"
7
+ version = "0.0.41"
8
8
  license = {text = "MIT License"}
9
9
  authors = [
10
10
  { name="Codetria", email="hola@codetria.com" },
@@ -1,10 +1,19 @@
1
1
  import os
2
- from datetime import date, datetime, timedelta
2
+ from datetime import date, datetime, timedelta, timezone
3
+ from http import HTTPMethod
3
4
 
4
5
  import pytest
5
6
  from unittest.mock import patch
6
7
 
7
8
  from pyEscoAPI import EscoAPI
9
+ from pyEscoAPI.dataclasses import (
10
+ MovimientoArancel,
11
+ MovimientoComision,
12
+ MovimientoDerecho,
13
+ MovimientoMoneda,
14
+ MovimientoRetencionIIBB,
15
+ MovimientoTitulo,
16
+ )
8
17
  from pyEscoAPI.esco_api import APIVersion
9
18
 
10
19
 
@@ -360,4 +369,183 @@ def test_insert_solicitud_comprobante_pago(api_client):
360
369
  fecha_liquidacion=date.today(),
361
370
  controla_saldo_monetario=True,
362
371
  )
363
- assert result == mock_response
372
+ assert result == mock_response
373
+
374
+
375
+ @patch("pyEscoAPI.esco_api.EscoAPI._EscoAPI__esco_login")
376
+ def test_insert_movimiento_manual(mock_login, api_client):
377
+ mock_response = {"codOperacion": 1}
378
+ fecha = datetime(2026, 11, 4, 13, 56, 41, 701000, tzinfo=timezone.utc)
379
+ with patch.object(api_client, "_EscoAPI__pre_connection"), patch.object(
380
+ api_client, "_EscoAPI__make_request", return_value=mock_response
381
+ ) as mock_request:
382
+ result = api_client.insert_movimiento_manual(
383
+ cuenta=123,
384
+ fecha_concertacion=fecha,
385
+ fecha_liquidacion=fecha,
386
+ descripcion="Ajuste manual",
387
+ cod_tp_movimiento_manual="AJ",
388
+ observaciones="obs",
389
+ num_referencia=10,
390
+ mercado="ME",
391
+ se_informa=True,
392
+ permite_movimiento_feriado=True,
393
+ permite_descubierto=True,
394
+ controla_duplicidad=False,
395
+ movimientos_moneda=[
396
+ MovimientoMoneda(
397
+ importe=100.5,
398
+ moneda="ARS",
399
+ tpCambioMovPais=1,
400
+ codCtaContable=401,
401
+ codCentroCost=0,
402
+ esCredito=True,
403
+ )
404
+ ],
405
+ movimientos_titulo=[
406
+ MovimientoTitulo(
407
+ instrumento="GGAL",
408
+ codTpInstrumento="ES",
409
+ codAgenteDepo=1,
410
+ cantidad=10,
411
+ precio=1500,
412
+ esCredito=False,
413
+ )
414
+ ],
415
+ movimientos_arancel=[
416
+ MovimientoArancel(
417
+ importe=10,
418
+ moneda="ARS",
419
+ tpCambioArPais=1,
420
+ codTpIVABase="IB",
421
+ codTpIVASTasa="ST",
422
+ )
423
+ ],
424
+ movimientos_derecho=[
425
+ MovimientoDerecho(
426
+ tipoDerecho="ME",
427
+ importe=5,
428
+ moneda="ARS",
429
+ tpCambioDerPais=1,
430
+ ivaDerecho="IB",
431
+ sobreTasa="ST",
432
+ )
433
+ ],
434
+ movimientos_retenciones_iibb=[
435
+ MovimientoRetencionIIBB(
436
+ importe=2,
437
+ moneda="ARS",
438
+ tpCambioRetPais=1,
439
+ codProvincia=1,
440
+ codPais=1,
441
+ )
442
+ ],
443
+ movimientos_comisiones=[
444
+ MovimientoComision(
445
+ codAgenteDepo=1,
446
+ importe=3,
447
+ moneda="ARS",
448
+ tpCambioComPais=1,
449
+ codTpIVABaseCom="IB",
450
+ codCtaContable=500,
451
+ )
452
+ ],
453
+ )
454
+
455
+ assert result == mock_response
456
+ mock_request.assert_called_once_with(
457
+ request_endpoint="/insert-movimiento-manual",
458
+ request_body={
459
+ "cuenta": 123,
460
+ "fechaConcertacion": "2026-11-04T13:56:41.701Z",
461
+ "fechaLiquidacion": "2026-11-04T13:56:41.701Z",
462
+ "descripcion": "Ajuste manual",
463
+ "codTpMovimientoManual": "AJ",
464
+ "observaciones": "obs",
465
+ "numReferencia": 10,
466
+ "mercado": "ME",
467
+ "seInforma": True,
468
+ "permiteMovimientoFeriado": True,
469
+ "permiteDescubierto": True,
470
+ "controlaDuplicidad": False,
471
+ "movimientosMoneda": [{
472
+ "importe": 100.5,
473
+ "moneda": "ARS",
474
+ "tpCambioMovPais": 1,
475
+ "codCtaContable": 401,
476
+ "codCentroCost": 0,
477
+ "esCredito": True,
478
+ }],
479
+ "movimientosTitulo": [{
480
+ "instrumento": "GGAL",
481
+ "codTpInstrumento": "ES",
482
+ "codAgenteDepo": 1,
483
+ "cantidad": 10,
484
+ "precio": 1500,
485
+ "esCredito": False,
486
+ }],
487
+ "movimientosArancel": [{
488
+ "importe": 10,
489
+ "moneda": "ARS",
490
+ "tpCambioArPais": 1,
491
+ "codTpIVABase": "IB",
492
+ "codTpIVASTasa": "ST",
493
+ }],
494
+ "movimientosDerecho": [{
495
+ "tipoDerecho": "ME",
496
+ "importe": 5,
497
+ "moneda": "ARS",
498
+ "tpCambioDerPais": 1,
499
+ "ivaDerecho": "IB",
500
+ "sobreTasa": "ST",
501
+ }],
502
+ "movimientosRetencionesIIBB": [{
503
+ "importe": 2,
504
+ "moneda": "ARS",
505
+ "tpCambioRetPais": 1,
506
+ "codProvincia": 1,
507
+ "codPais": 1,
508
+ }],
509
+ "movimientosComisiones": [{
510
+ "codAgenteDepo": 1,
511
+ "importe": 3,
512
+ "moneda": "ARS",
513
+ "tpCambioComPais": 1,
514
+ "codTpIVABaseCom": "IB",
515
+ "codCtaContable": 500,
516
+ }],
517
+ },
518
+ request_method=HTTPMethod.POST,
519
+ )
520
+
521
+
522
+ @patch("pyEscoAPI.esco_api.EscoAPI._EscoAPI__esco_login")
523
+ def test_get_transferencia_titulos(mock_login, api_client):
524
+ mock_response = [{"codTransferenciaTitMov": 10, "instrumentoAbrev": "GGAL"}]
525
+ with patch.object(api_client, "_EscoAPI__pre_connection"), patch.object(
526
+ api_client, "_EscoAPI__make_request", return_value=mock_response
527
+ ) as mock_request:
528
+ result = api_client.get_transferencia_titulos(
529
+ cuentas="123,456",
530
+ fecha_desde=date(2026, 11, 4),
531
+ fecha_hasta=date(2026, 11, 4),
532
+ cod_tp_transferencia_tit_mov="TI",
533
+ por_concertacion=True,
534
+ es_consolidado=False,
535
+ incluye_anulado=False,
536
+ )
537
+
538
+ assert result == mock_response
539
+ mock_request.assert_called_once_with(
540
+ request_endpoint="/get-transferencia-titulos",
541
+ request_body={
542
+ "cuentas": "123,456",
543
+ "fechaDesde": "2026-11-04",
544
+ "fechaHasta": "2026-11-04",
545
+ "codTpTransferenciaTitMov": "TI",
546
+ "porConcertacion": True,
547
+ "esConsolidado": False,
548
+ "incluyeAnulado": False,
549
+ },
550
+ request_method=HTTPMethod.POST,
551
+ )
File without changes
File without changes