transdesk-importer-python-sdk 1.0.0__tar.gz → 1.2.0__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.
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/PKG-INFO +16 -1
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/README.md +15 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/pyproject.toml +1 -1
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/models/canonical.py +18 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/models/internal.py +23 -4
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/shared/data_normalizer.py +21 -1
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/canonical/apolice_builder.py +33 -4
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/internal/coverage_mapper.py +18 -12
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/internal/internal_mapper.py +78 -5
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/internal/rcf_parser.py +1 -1
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk_importer_python_sdk.egg-info/PKG-INFO +16 -1
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk_importer_python_sdk.egg-info/SOURCES.txt +3 -1
- transdesk_importer_python_sdk-1.2.0/tests/test_data_normalizer.py +26 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/tests/test_importer.py +4 -1
- transdesk_importer_python_sdk-1.2.0/tests/test_vehicle_details.py +181 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/LICENSE +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/setup.cfg +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/__init__.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/client.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/exporters/__init__.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/exporters/json_exporter.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/models/__init__.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/readers/__init__.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/readers/excel_reader.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/shared/__init__.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/__init__.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/canonical/__init__.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/canonical/cobertura_builder.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/canonical/item_classifier.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/internal/__init__.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/transformers/internal/towing_parser.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/validators/__init__.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk/importer/validators/internal_policy_validator.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk_importer_python_sdk.egg-info/dependency_links.txt +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk_importer_python_sdk.egg-info/requires.txt +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/src/transdesk_importer_python_sdk.egg-info/top_level.txt +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/tests/test_excel_reader.py +0 -0
- {transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/tests/test_validator.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: transdesk-importer-python-sdk
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: SDK de leitura/transformacao de planilhas de apolices Transdesk para o formato interno 77seg
|
|
5
5
|
Author-email: FMConsult <contato@fmconsult.com.br>
|
|
6
6
|
License: MIT License
|
|
@@ -112,6 +112,21 @@ Helpers: `result.to_dict()` e `result.to_json(**kwargs)`.
|
|
|
112
112
|
cobertura e de risco estao sempre presentes; os que nao se aplicam ao tipo do
|
|
113
113
|
item (ex.: campos de vida num veiculo) vem como `null`.
|
|
114
114
|
|
|
115
|
+
Campos adicionais de veiculo/reboque (colunas apos `CHAVE_PIX` na planilha):
|
|
116
|
+
|
|
117
|
+
| Coluna planilha | Campo `InternalItem` | Observacao |
|
|
118
|
+
| --------------- | -------------------- | ---------- |
|
|
119
|
+
| `EMPRESA_RASTREAMENTO` | `vehicle_tracker_company` | Somente quando `has_vehicle_tracker` |
|
|
120
|
+
| `CATEGORIA` | `vehicle_classification` | Classificacao do veiculo (int) |
|
|
121
|
+
| `MARCA` | `brand_name` / `brand` | Veiculo; reboque usa `MARCA_REBOQUE` |
|
|
122
|
+
| `MODELO` | `model_description` / `model` | Veiculo; reboque usa `MODELO_REBOQUE` |
|
|
123
|
+
| `RENAVAM` | `renavam` | |
|
|
124
|
+
| `COR` | `color` | |
|
|
125
|
+
| `ANO` | `model_year`, `manufacture_year` | Mesmo valor nos dois campos |
|
|
126
|
+
| `EIXOS` | `axles` | |
|
|
127
|
+
| `CAMBIO` | `transmission` | |
|
|
128
|
+
| `ALIENADO` | `is_alienated` | `N/A` ou vazio = `false` |
|
|
129
|
+
|
|
115
130
|
### Validacao
|
|
116
131
|
|
|
117
132
|
O `ValidationError` cobre tres tipos:
|
|
@@ -69,6 +69,21 @@ Helpers: `result.to_dict()` e `result.to_json(**kwargs)`.
|
|
|
69
69
|
cobertura e de risco estao sempre presentes; os que nao se aplicam ao tipo do
|
|
70
70
|
item (ex.: campos de vida num veiculo) vem como `null`.
|
|
71
71
|
|
|
72
|
+
Campos adicionais de veiculo/reboque (colunas apos `CHAVE_PIX` na planilha):
|
|
73
|
+
|
|
74
|
+
| Coluna planilha | Campo `InternalItem` | Observacao |
|
|
75
|
+
| --------------- | -------------------- | ---------- |
|
|
76
|
+
| `EMPRESA_RASTREAMENTO` | `vehicle_tracker_company` | Somente quando `has_vehicle_tracker` |
|
|
77
|
+
| `CATEGORIA` | `vehicle_classification` | Classificacao do veiculo (int) |
|
|
78
|
+
| `MARCA` | `brand_name` / `brand` | Veiculo; reboque usa `MARCA_REBOQUE` |
|
|
79
|
+
| `MODELO` | `model_description` / `model` | Veiculo; reboque usa `MODELO_REBOQUE` |
|
|
80
|
+
| `RENAVAM` | `renavam` | |
|
|
81
|
+
| `COR` | `color` | |
|
|
82
|
+
| `ANO` | `model_year`, `manufacture_year` | Mesmo valor nos dois campos |
|
|
83
|
+
| `EIXOS` | `axles` | |
|
|
84
|
+
| `CAMBIO` | `transmission` | |
|
|
85
|
+
| `ALIENADO` | `is_alienated` | `N/A` ou vazio = `false` |
|
|
86
|
+
|
|
72
87
|
### Validacao
|
|
73
88
|
|
|
74
89
|
O `ValidationError` cobre tres tipos:
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "transdesk-importer-python-sdk"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.2.0"
|
|
8
8
|
description = "SDK de leitura/transformacao de planilhas de apolices Transdesk para o formato interno 77seg"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -36,6 +36,16 @@ class VeiculoRisco:
|
|
|
36
36
|
placa: Optional[str] = None
|
|
37
37
|
chassi: Optional[str] = None
|
|
38
38
|
codigo_fipe: Optional[str] = None
|
|
39
|
+
empresa_rastreamento: Optional[str] = None
|
|
40
|
+
categoria: Optional[str] = None
|
|
41
|
+
modelo: Optional[str] = None
|
|
42
|
+
renavam: Optional[str] = None
|
|
43
|
+
marca: Optional[str] = None
|
|
44
|
+
cor: Optional[str] = None
|
|
45
|
+
ano: Optional[str] = None
|
|
46
|
+
eixos: Optional[str] = None
|
|
47
|
+
cambio: Optional[str] = None
|
|
48
|
+
alienado: Optional[str] = None
|
|
39
49
|
|
|
40
50
|
|
|
41
51
|
@dataclass
|
|
@@ -44,6 +54,14 @@ class ReboqueRisco:
|
|
|
44
54
|
chassi: Optional[str] = None
|
|
45
55
|
marca: Optional[str] = None
|
|
46
56
|
modelo: Optional[str] = None
|
|
57
|
+
empresa_rastreamento: Optional[str] = None
|
|
58
|
+
categoria: Optional[str] = None
|
|
59
|
+
renavam: Optional[str] = None
|
|
60
|
+
cor: Optional[str] = None
|
|
61
|
+
ano: Optional[str] = None
|
|
62
|
+
eixos: Optional[str] = None
|
|
63
|
+
cambio: Optional[str] = None
|
|
64
|
+
alienado: Optional[str] = None
|
|
47
65
|
|
|
48
66
|
|
|
49
67
|
@dataclass
|
|
@@ -23,22 +23,25 @@ class Broker:
|
|
|
23
23
|
|
|
24
24
|
@dataclass
|
|
25
25
|
class CustomerInfo:
|
|
26
|
+
cpf: Optional[str] = None
|
|
26
27
|
cnpj: Optional[str] = None
|
|
27
28
|
principal_name: Optional[str] = None
|
|
28
29
|
secondary_name: Optional[str] = None
|
|
29
30
|
email_address: Optional[str] = None
|
|
31
|
+
enrollment_number: Optional[str] = None
|
|
32
|
+
custom_fields: Optional[Dict[str, Any]] = None
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
@dataclass
|
|
33
36
|
class Telephone:
|
|
34
|
-
|
|
37
|
+
type_code: str
|
|
35
38
|
ddd: str
|
|
36
39
|
number: str
|
|
37
40
|
|
|
38
41
|
|
|
39
42
|
@dataclass
|
|
40
43
|
class Mobile:
|
|
41
|
-
|
|
44
|
+
type_code: str
|
|
42
45
|
ddd: str
|
|
43
46
|
number: str
|
|
44
47
|
allow_sms: bool = True
|
|
@@ -85,7 +88,7 @@ class InternalItem:
|
|
|
85
88
|
|
|
86
89
|
# RCF
|
|
87
90
|
has_rcf: bool = False
|
|
88
|
-
|
|
91
|
+
material_damage_value: float = 0
|
|
89
92
|
property_damage_premium: float = 0
|
|
90
93
|
bodily_injury_value: float = 0
|
|
91
94
|
bodily_injury_premium: float = 0
|
|
@@ -102,18 +105,24 @@ class InternalItem:
|
|
|
102
105
|
towing_premium: float = 0
|
|
103
106
|
|
|
104
107
|
# Vidros
|
|
105
|
-
|
|
108
|
+
glass_coverage_level: Optional[str] = None
|
|
106
109
|
glass_premium: float = 0
|
|
107
110
|
|
|
108
111
|
# Rastreador
|
|
109
112
|
has_vehicle_tracker: bool = False
|
|
110
113
|
vehicle_tracker_premium: float = 0
|
|
114
|
+
vehicle_tracker_company: Optional[str] = None
|
|
111
115
|
|
|
112
116
|
# Juridica
|
|
113
117
|
has_legal_assistance: bool = False
|
|
114
118
|
legal_assistance_value: float = 0
|
|
115
119
|
legal_assistance_premium: float = 0
|
|
116
120
|
|
|
121
|
+
# Suporte emergencial monitorado
|
|
122
|
+
has_monitored_emergency_support: bool = False
|
|
123
|
+
monitored_emergency_support_value: float = 0
|
|
124
|
+
monitored_emergency_support_premium: float = 0
|
|
125
|
+
|
|
117
126
|
# Combo
|
|
118
127
|
group_name: Optional[str] = None
|
|
119
128
|
|
|
@@ -124,6 +133,16 @@ class InternalItem:
|
|
|
124
133
|
body_description: Optional[str] = None
|
|
125
134
|
brand: Optional[str] = None
|
|
126
135
|
model: Optional[str] = None
|
|
136
|
+
brand_name: Optional[str] = None
|
|
137
|
+
model_description: Optional[str] = None
|
|
138
|
+
vehicle_classification: Optional[int] = None
|
|
139
|
+
renavam: Optional[str] = None
|
|
140
|
+
color: Optional[str] = None
|
|
141
|
+
model_year: Optional[int] = None
|
|
142
|
+
manufacture_year: Optional[int] = None
|
|
143
|
+
axles: Optional[int] = None
|
|
144
|
+
transmission: Optional[str] = None
|
|
145
|
+
is_alienated: bool = False
|
|
127
146
|
|
|
128
147
|
# Vida
|
|
129
148
|
name: Optional[str] = None
|
|
@@ -41,7 +41,27 @@ class DataNormalizer:
|
|
|
41
41
|
|
|
42
42
|
@staticmethod
|
|
43
43
|
def to_int(value):
|
|
44
|
+
if value in (None, ""):
|
|
45
|
+
return None
|
|
46
|
+
|
|
44
47
|
try:
|
|
45
|
-
return int(value)
|
|
48
|
+
return int(str(value).strip())
|
|
46
49
|
except Exception:
|
|
47
50
|
return None
|
|
51
|
+
|
|
52
|
+
@staticmethod
|
|
53
|
+
def to_bool(value, na_values=("N/A", "n/a", "")):
|
|
54
|
+
if value is None:
|
|
55
|
+
return False
|
|
56
|
+
|
|
57
|
+
normalized = str(value).strip()
|
|
58
|
+
if normalized in na_values:
|
|
59
|
+
return False
|
|
60
|
+
|
|
61
|
+
upper = normalized.upper()
|
|
62
|
+
if upper in ("SIM", "S", "TRUE", "1", "YES", "Y"):
|
|
63
|
+
return True
|
|
64
|
+
if upper in ("NÃO", "NAO", "N", "FALSE", "0", "NO"):
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
return False
|
|
@@ -188,6 +188,7 @@ class ApoliceBuilder:
|
|
|
188
188
|
chassi=row.get("CHASSI"),
|
|
189
189
|
marca=row.get("MARCA_REBOQUE"),
|
|
190
190
|
modelo=row.get("MODELO_REBOQUE"),
|
|
191
|
+
**self._read_vehicle_detail_fields(rows, include_brand_model=False),
|
|
191
192
|
),
|
|
192
193
|
coberturas=CoberturaBuilder(rows).build(),
|
|
193
194
|
)
|
|
@@ -205,6 +206,7 @@ class ApoliceBuilder:
|
|
|
205
206
|
placa=row.get("PLACA_VEICULO"),
|
|
206
207
|
chassi=row.get("CHASSI"),
|
|
207
208
|
codigo_fipe=row.get("CODE_FIPE"),
|
|
209
|
+
**self._read_vehicle_detail_fields(rows, include_brand_model=True),
|
|
208
210
|
),
|
|
209
211
|
complementos=self.build_complementos(rows),
|
|
210
212
|
coberturas=CoberturaBuilder(rows).build(),
|
|
@@ -214,6 +216,36 @@ class ApoliceBuilder:
|
|
|
214
216
|
|
|
215
217
|
return item
|
|
216
218
|
|
|
219
|
+
def _read_vehicle_detail_fields(self, rows, include_brand_model=False):
|
|
220
|
+
column_map = {
|
|
221
|
+
"empresa_rastreamento": "EMPRESA_RASTREAMENTO",
|
|
222
|
+
"categoria": "CATEGORIA",
|
|
223
|
+
"renavam": "RENAVAM",
|
|
224
|
+
"cor": "COR",
|
|
225
|
+
"ano": "ANO",
|
|
226
|
+
"eixos": "EIXOS",
|
|
227
|
+
"cambio": "CAMBIO",
|
|
228
|
+
"alienado": "ALIENADO",
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
if include_brand_model:
|
|
232
|
+
column_map["marca"] = "MARCA"
|
|
233
|
+
column_map["modelo"] = "MODELO"
|
|
234
|
+
|
|
235
|
+
fields = {}
|
|
236
|
+
for field_name, column_name in column_map.items():
|
|
237
|
+
fields[field_name] = self._first_non_empty(rows, column_name)
|
|
238
|
+
|
|
239
|
+
return fields
|
|
240
|
+
|
|
241
|
+
@staticmethod
|
|
242
|
+
def _first_non_empty(rows, column_name):
|
|
243
|
+
for row in rows:
|
|
244
|
+
value = row.get(column_name)
|
|
245
|
+
if value is not None and str(value).strip() != "":
|
|
246
|
+
return value
|
|
247
|
+
return None
|
|
248
|
+
|
|
217
249
|
# ---------------------------------------------------------
|
|
218
250
|
# COMPLEMENTOS
|
|
219
251
|
# ---------------------------------------------------------
|
|
@@ -246,7 +278,6 @@ class ApoliceBuilder:
|
|
|
246
278
|
|
|
247
279
|
def merge_complement_coverages(self, item):
|
|
248
280
|
casco_extra = 0
|
|
249
|
-
reparo_extra = 0
|
|
250
281
|
|
|
251
282
|
novas = []
|
|
252
283
|
|
|
@@ -258,7 +289,7 @@ class ApoliceBuilder:
|
|
|
258
289
|
continue
|
|
259
290
|
|
|
260
291
|
if nome == "Assistência a Reparos (COMPLEMENTO)":
|
|
261
|
-
|
|
292
|
+
casco_extra += (c.valor_mensalidade or 0)
|
|
262
293
|
continue
|
|
263
294
|
|
|
264
295
|
novas.append(c)
|
|
@@ -266,7 +297,5 @@ class ApoliceBuilder:
|
|
|
266
297
|
for c in novas:
|
|
267
298
|
if c.nome == "Casco PT (VEÍCULO)":
|
|
268
299
|
c.valor_mensalidade = ((c.valor_mensalidade or 0) + casco_extra)
|
|
269
|
-
elif c.nome == "Assistência a Reparos (VEÍCULO)":
|
|
270
|
-
c.valor_mensalidade = ((c.valor_mensalidade or 0) + reparo_extra)
|
|
271
300
|
|
|
272
301
|
item.coberturas = novas
|
|
@@ -33,11 +33,9 @@ class CoverageMapper:
|
|
|
33
33
|
elif name in (
|
|
34
34
|
"Assistência a Reparos (VEÍCULO)",
|
|
35
35
|
"Assistência a Reparos (R/SR)",
|
|
36
|
+
"Assistência a Reparos (COMPLEMENTO)",
|
|
36
37
|
):
|
|
37
|
-
self.
|
|
38
|
-
|
|
39
|
-
elif name == "Assistência a Reparos (COMPLEMENTO)":
|
|
40
|
-
self._apply_body(item, coverage)
|
|
38
|
+
self._apply_casco_premium_only(item, coverage)
|
|
41
39
|
|
|
42
40
|
elif name == "RCF":
|
|
43
41
|
self._apply_rcf(item, coverage)
|
|
@@ -57,10 +55,14 @@ class CoverageMapper:
|
|
|
57
55
|
elif name in (
|
|
58
56
|
"Rastreador p/ Veículo",
|
|
59
57
|
"Rastreador p/ Reboque",
|
|
60
|
-
"
|
|
58
|
+
"Rastreamento",
|
|
59
|
+
"Rastreamento Reboque/Semirreboque",
|
|
61
60
|
):
|
|
62
61
|
self._apply_tracker(item, coverage)
|
|
63
62
|
|
|
63
|
+
elif name == "SUPORTE EMERGENCIAL MONITORADO":
|
|
64
|
+
self._apply_monitored_emergency_support(item, coverage)
|
|
65
|
+
|
|
64
66
|
elif name == "Assistência Jurídica":
|
|
65
67
|
self._apply_legal_assistance(item, coverage)
|
|
66
68
|
|
|
@@ -69,10 +71,9 @@ class CoverageMapper:
|
|
|
69
71
|
item.hull_value += (coverage.importancia_segurada or 0)
|
|
70
72
|
item.hull_premium += (coverage.valor_mensalidade or 0)
|
|
71
73
|
|
|
72
|
-
def
|
|
73
|
-
item.
|
|
74
|
-
item.
|
|
75
|
-
item.repair_assistance_premium += (coverage.valor_mensalidade or 0)
|
|
74
|
+
def _apply_casco_premium_only(self, item, coverage):
|
|
75
|
+
item.has_casco_cir = True
|
|
76
|
+
item.hull_premium += (coverage.valor_mensalidade or 0)
|
|
76
77
|
|
|
77
78
|
def _apply_body(self, item, coverage):
|
|
78
79
|
item.body_value += (coverage.importancia_segurada or 0)
|
|
@@ -88,12 +89,17 @@ class CoverageMapper:
|
|
|
88
89
|
item.legal_assistance_value = 1
|
|
89
90
|
item.legal_assistance_premium += (coverage.valor_mensalidade or 0)
|
|
90
91
|
|
|
92
|
+
def _apply_monitored_emergency_support(self, item, coverage):
|
|
93
|
+
item.has_monitored_emergency_support = True
|
|
94
|
+
item.monitored_emergency_support_value = 1
|
|
95
|
+
item.monitored_emergency_support_premium += (coverage.valor_mensalidade or 0)
|
|
96
|
+
|
|
91
97
|
def _apply_tracker(self, item, coverage):
|
|
92
98
|
item.has_vehicle_tracker = True
|
|
93
99
|
item.vehicle_tracker_premium += (coverage.valor_mensalidade or 0)
|
|
94
100
|
|
|
95
101
|
def _apply_glass(self, item, coverage):
|
|
96
|
-
item.
|
|
102
|
+
item.glass_coverage_level = "completo"
|
|
97
103
|
item.glass_premium += (coverage.valor_mensalidade or 0)
|
|
98
104
|
|
|
99
105
|
def _apply_rcf(self, item, coverage):
|
|
@@ -104,13 +110,13 @@ class CoverageMapper:
|
|
|
104
110
|
premiums = self._allocate_premium(
|
|
105
111
|
coverage.valor_mensalidade or 0,
|
|
106
112
|
{
|
|
107
|
-
"property_damage": parsed["
|
|
113
|
+
"property_damage": parsed["material_damage_value"],
|
|
108
114
|
"bodily_injury": parsed["bodily_injury_value"],
|
|
109
115
|
"moral_damage": parsed["moral_damage_value"],
|
|
110
116
|
},
|
|
111
117
|
)
|
|
112
118
|
|
|
113
|
-
item.
|
|
119
|
+
item.material_damage_value += (parsed["material_damage_value"])
|
|
114
120
|
item.property_damage_premium += (premiums["property_damage"])
|
|
115
121
|
|
|
116
122
|
item.bodily_injury_value += (parsed["bodily_injury_value"])
|
|
@@ -10,6 +10,7 @@ from transdesk.importer.models.internal import (
|
|
|
10
10
|
ResellerData,
|
|
11
11
|
Telephone,
|
|
12
12
|
)
|
|
13
|
+
from transdesk.importer.shared.data_normalizer import DataNormalizer
|
|
13
14
|
from transdesk.importer.transformers.internal.coverage_mapper import CoverageMapper
|
|
14
15
|
|
|
15
16
|
|
|
@@ -44,19 +45,61 @@ class InternalMapper:
|
|
|
44
45
|
customer = policy.cliente
|
|
45
46
|
|
|
46
47
|
email = next((e for e in customer.emails if e), None)
|
|
48
|
+
cpf, cnpj = self._route_document(customer.documento, customer.tipo_pessoa)
|
|
47
49
|
|
|
48
50
|
return Lead(
|
|
49
51
|
customer_info=CustomerInfo(
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
52
|
+
cpf=cpf,
|
|
53
|
+
cnpj=cnpj,
|
|
54
|
+
principal_name=customer.razao_social or customer.nome_fantasia,
|
|
55
|
+
secondary_name=customer.nome_fantasia or "",
|
|
53
56
|
email_address=email,
|
|
57
|
+
enrollment_number=customer.matricula,
|
|
58
|
+
custom_fields=self._build_bank_custom_fields(customer),
|
|
54
59
|
),
|
|
55
60
|
telphone_info=self._build_phone(customer),
|
|
56
61
|
celphone_info=self._build_mobile(customer),
|
|
57
62
|
address_info=self._build_address(customer),
|
|
58
63
|
)
|
|
59
64
|
|
|
65
|
+
def _build_bank_custom_fields(self, customer):
|
|
66
|
+
bank = customer.dados_bancarios
|
|
67
|
+
|
|
68
|
+
if bank is None:
|
|
69
|
+
return None
|
|
70
|
+
|
|
71
|
+
bank_info = {
|
|
72
|
+
'bank_code': bank.banco,
|
|
73
|
+
'agency': bank.agencia,
|
|
74
|
+
'account': bank.conta,
|
|
75
|
+
'pix_key': bank.chave_pix,
|
|
76
|
+
'holder_name': bank.titular,
|
|
77
|
+
'holder_document': bank.documento_titular,
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if not any(bank_info.values()):
|
|
81
|
+
return None
|
|
82
|
+
|
|
83
|
+
return {'bank_info': bank_info}
|
|
84
|
+
|
|
85
|
+
def _route_document(self, documento, tipo_pessoa=None):
|
|
86
|
+
digits = "".join(filter(str.isdigit, str(documento or "")))
|
|
87
|
+
|
|
88
|
+
if not digits:
|
|
89
|
+
return None, None
|
|
90
|
+
|
|
91
|
+
tipo = str(tipo_pessoa or "").strip().upper()
|
|
92
|
+
|
|
93
|
+
if tipo in ("F", "PF", "FISICA", "FÍSICA"):
|
|
94
|
+
return digits, None
|
|
95
|
+
if tipo in ("J", "PJ", "JURIDICA", "JURÍDICA"):
|
|
96
|
+
return None, digits
|
|
97
|
+
|
|
98
|
+
if len(digits) <= 11:
|
|
99
|
+
return digits.zfill(11), None
|
|
100
|
+
|
|
101
|
+
return None, digits.zfill(14)
|
|
102
|
+
|
|
60
103
|
def build_items(self, policy):
|
|
61
104
|
return [
|
|
62
105
|
self.map_item(item, index)
|
|
@@ -77,7 +120,7 @@ class InternalMapper:
|
|
|
77
120
|
|
|
78
121
|
if not numero.startswith("9"):
|
|
79
122
|
return Telephone(
|
|
80
|
-
|
|
123
|
+
type_code="03",
|
|
81
124
|
ddd=digits[:2],
|
|
82
125
|
number=numero,
|
|
83
126
|
)
|
|
@@ -98,7 +141,7 @@ class InternalMapper:
|
|
|
98
141
|
|
|
99
142
|
if numero.startswith("9"):
|
|
100
143
|
return Mobile(
|
|
101
|
-
|
|
144
|
+
type_code="02",
|
|
102
145
|
ddd=digits[:2],
|
|
103
146
|
number=numero,
|
|
104
147
|
allow_sms=True,
|
|
@@ -154,6 +197,36 @@ class InternalMapper:
|
|
|
154
197
|
if item.tipo_item == "reboque":
|
|
155
198
|
internal_item.brand = getattr(risco, "marca", None)
|
|
156
199
|
internal_item.model = getattr(risco, "modelo", None)
|
|
200
|
+
internal_item.brand_name = internal_item.brand
|
|
201
|
+
internal_item.model_description = internal_item.model
|
|
202
|
+
elif item.tipo_item == "veiculo":
|
|
203
|
+
marca = getattr(risco, "marca", None)
|
|
204
|
+
modelo = getattr(risco, "modelo", None)
|
|
205
|
+
internal_item.brand = marca
|
|
206
|
+
internal_item.model = modelo
|
|
207
|
+
internal_item.brand_name = marca
|
|
208
|
+
internal_item.model_description = modelo
|
|
209
|
+
|
|
210
|
+
internal_item.vehicle_classification = DataNormalizer.to_int(
|
|
211
|
+
getattr(risco, "categoria", None)
|
|
212
|
+
)
|
|
213
|
+
internal_item.renavam = DataNormalizer.clean_doc(
|
|
214
|
+
getattr(risco, "renavam", None)
|
|
215
|
+
)
|
|
216
|
+
internal_item.color = getattr(risco, "cor", None) or None
|
|
217
|
+
year = DataNormalizer.to_int(getattr(risco, "ano", None))
|
|
218
|
+
internal_item.model_year = year
|
|
219
|
+
internal_item.manufacture_year = year
|
|
220
|
+
internal_item.axles = DataNormalizer.to_int(getattr(risco, "eixos", None))
|
|
221
|
+
internal_item.transmission = getattr(risco, "cambio", None) or None
|
|
222
|
+
internal_item.is_alienated = DataNormalizer.to_bool(
|
|
223
|
+
getattr(risco, "alienado", None)
|
|
224
|
+
)
|
|
225
|
+
|
|
226
|
+
if internal_item.has_vehicle_tracker:
|
|
227
|
+
internal_item.vehicle_tracker_company = (
|
|
228
|
+
getattr(risco, "empresa_rastreamento", None) or None
|
|
229
|
+
)
|
|
157
230
|
|
|
158
231
|
def _build_body_description(self, item):
|
|
159
232
|
parts = []
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: transdesk-importer-python-sdk
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: SDK de leitura/transformacao de planilhas de apolices Transdesk para o formato interno 77seg
|
|
5
5
|
Author-email: FMConsult <contato@fmconsult.com.br>
|
|
6
6
|
License: MIT License
|
|
@@ -112,6 +112,21 @@ Helpers: `result.to_dict()` e `result.to_json(**kwargs)`.
|
|
|
112
112
|
cobertura e de risco estao sempre presentes; os que nao se aplicam ao tipo do
|
|
113
113
|
item (ex.: campos de vida num veiculo) vem como `null`.
|
|
114
114
|
|
|
115
|
+
Campos adicionais de veiculo/reboque (colunas apos `CHAVE_PIX` na planilha):
|
|
116
|
+
|
|
117
|
+
| Coluna planilha | Campo `InternalItem` | Observacao |
|
|
118
|
+
| --------------- | -------------------- | ---------- |
|
|
119
|
+
| `EMPRESA_RASTREAMENTO` | `vehicle_tracker_company` | Somente quando `has_vehicle_tracker` |
|
|
120
|
+
| `CATEGORIA` | `vehicle_classification` | Classificacao do veiculo (int) |
|
|
121
|
+
| `MARCA` | `brand_name` / `brand` | Veiculo; reboque usa `MARCA_REBOQUE` |
|
|
122
|
+
| `MODELO` | `model_description` / `model` | Veiculo; reboque usa `MODELO_REBOQUE` |
|
|
123
|
+
| `RENAVAM` | `renavam` | |
|
|
124
|
+
| `COR` | `color` | |
|
|
125
|
+
| `ANO` | `model_year`, `manufacture_year` | Mesmo valor nos dois campos |
|
|
126
|
+
| `EIXOS` | `axles` | |
|
|
127
|
+
| `CAMBIO` | `transmission` | |
|
|
128
|
+
| `ALIENADO` | `is_alienated` | `N/A` ou vazio = `false` |
|
|
129
|
+
|
|
115
130
|
### Validacao
|
|
116
131
|
|
|
117
132
|
O `ValidationError` cobre tres tipos:
|
|
@@ -29,6 +29,8 @@ src/transdesk_importer_python_sdk.egg-info/SOURCES.txt
|
|
|
29
29
|
src/transdesk_importer_python_sdk.egg-info/dependency_links.txt
|
|
30
30
|
src/transdesk_importer_python_sdk.egg-info/requires.txt
|
|
31
31
|
src/transdesk_importer_python_sdk.egg-info/top_level.txt
|
|
32
|
+
tests/test_data_normalizer.py
|
|
32
33
|
tests/test_excel_reader.py
|
|
33
34
|
tests/test_importer.py
|
|
34
|
-
tests/test_validator.py
|
|
35
|
+
tests/test_validator.py
|
|
36
|
+
tests/test_vehicle_details.py
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from transdesk.importer.shared.data_normalizer import DataNormalizer
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
@pytest.mark.parametrize(
|
|
7
|
+
"value,expected",
|
|
8
|
+
[
|
|
9
|
+
("N/A", False),
|
|
10
|
+
("n/a", False),
|
|
11
|
+
("", False),
|
|
12
|
+
(None, False),
|
|
13
|
+
("SIM", True),
|
|
14
|
+
("sim", True),
|
|
15
|
+
("S", True),
|
|
16
|
+
("1", True),
|
|
17
|
+
("true", True),
|
|
18
|
+
("NÃO", False),
|
|
19
|
+
("NAO", False),
|
|
20
|
+
("N", False),
|
|
21
|
+
("0", False),
|
|
22
|
+
("false", False),
|
|
23
|
+
],
|
|
24
|
+
)
|
|
25
|
+
def test_to_bool(value, expected):
|
|
26
|
+
assert DataNormalizer.to_bool(value) is expected
|
{transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/tests/test_importer.py
RENAMED
|
@@ -35,11 +35,14 @@ def test_policy_structure(apolices_bytes):
|
|
|
35
35
|
assert broker.principal_name == "TRANSDESK UNIDADE CURITIBA"
|
|
36
36
|
|
|
37
37
|
assert policy.data.lead.customer_info.principal_name == "ALM TRANSPORTES E LOGISTICA LTDA"
|
|
38
|
+
assert policy.data.lead.customer_info.cnpj
|
|
38
39
|
|
|
39
40
|
item = policy.data.items[0]
|
|
40
41
|
assert item.item_number == 1
|
|
41
42
|
assert item.item_type == "veiculo"
|
|
42
|
-
assert item.hull_premium ==
|
|
43
|
+
assert item.hull_premium == 687.12
|
|
44
|
+
assert item.repair_assistance_premium == 0
|
|
45
|
+
assert item.has_repair_assistance is False
|
|
43
46
|
assert item.group_name == "COMBO II"
|
|
44
47
|
|
|
45
48
|
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import pandas as pd
|
|
2
|
+
|
|
3
|
+
from transdesk.importer.transformers.canonical.apolice_builder import ApoliceBuilder
|
|
4
|
+
from transdesk.importer.transformers.internal.internal_mapper import InternalMapper
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def _base_row(**overrides):
|
|
8
|
+
row = {
|
|
9
|
+
"COD_AGRUPADOR_APOLICE": "99",
|
|
10
|
+
"DIA_VCTO": "10",
|
|
11
|
+
"ID_UNITY": "1",
|
|
12
|
+
"SUB_ESTIPULANTE_CNPJ": "12345678000199",
|
|
13
|
+
"SUB_ESTIPULANTE_FANTASIA": "CORRETORA TESTE",
|
|
14
|
+
"SUB_ESTIPULANTE_RAZAO_SOCIAL": "CORRETORA TESTE LTDA",
|
|
15
|
+
"PESSOA": "J",
|
|
16
|
+
"CNPJ_CPF_CLIENTE": "98765432000188",
|
|
17
|
+
"NOME_FANTASIA_CLIENTE": "CLIENTE TESTE",
|
|
18
|
+
"RAZAO_SOCIAL_CLIENTE": "CLIENTE TESTE LTDA",
|
|
19
|
+
"PLACA_VEICULO": "ABC1D23",
|
|
20
|
+
"CHASSI": "9BWZZZ377VT004251",
|
|
21
|
+
"CODE_FIPE": "005541-7",
|
|
22
|
+
"NME_BENEFICIO": "Casco PT (VEÍCULO)",
|
|
23
|
+
"VALOR_MENSALIDADE": "100.00",
|
|
24
|
+
"IMPORTANCIA_SEGURADA": "50000",
|
|
25
|
+
"EMPRESA_RASTREAMENTO": "TRACKERLOG",
|
|
26
|
+
"CATEGORIA": "3",
|
|
27
|
+
"MODELO": "FH 540",
|
|
28
|
+
"RENAVAM": "12345678901",
|
|
29
|
+
"MARCA": "VOLVO",
|
|
30
|
+
"COR": "BRANCO",
|
|
31
|
+
"ANO": "2022",
|
|
32
|
+
"EIXOS": "3",
|
|
33
|
+
"CAMBIO": "AUTOMATICO",
|
|
34
|
+
"ALIENADO": "SIM",
|
|
35
|
+
}
|
|
36
|
+
row.update(overrides)
|
|
37
|
+
return row
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def _build_item(rows):
|
|
41
|
+
df = pd.DataFrame(rows)
|
|
42
|
+
canonical = ApoliceBuilder().build(df)[0]
|
|
43
|
+
return InternalMapper().map(canonical).data.items[0]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_vehicle_details_mapped_from_spreadsheet_columns():
|
|
47
|
+
item = _build_item([_base_row()])
|
|
48
|
+
|
|
49
|
+
assert item.item_type == "veiculo"
|
|
50
|
+
assert item.brand_name == "VOLVO"
|
|
51
|
+
assert item.model_description == "FH 540"
|
|
52
|
+
assert item.brand == "VOLVO"
|
|
53
|
+
assert item.model == "FH 540"
|
|
54
|
+
assert item.vehicle_classification == 3
|
|
55
|
+
assert item.renavam == "12345678901"
|
|
56
|
+
assert item.color == "BRANCO"
|
|
57
|
+
assert item.model_year == 2022
|
|
58
|
+
assert item.manufacture_year == 2022
|
|
59
|
+
assert item.axles == 3
|
|
60
|
+
assert item.transmission == "AUTOMATICO"
|
|
61
|
+
assert item.is_alienated is True
|
|
62
|
+
assert item.has_vehicle_tracker is False
|
|
63
|
+
assert item.vehicle_tracker_company is None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_vehicle_tracker_company_only_when_has_tracker():
|
|
67
|
+
with_tracker = _build_item([
|
|
68
|
+
_base_row(NME_BENEFICIO="Casco PT (VEÍCULO)", VALOR_MENSALIDADE="100.00"),
|
|
69
|
+
_base_row(
|
|
70
|
+
NME_BENEFICIO="Rastreador p/ Veículo",
|
|
71
|
+
VALOR_MENSALIDADE="15.00",
|
|
72
|
+
EMPRESA_RASTREAMENTO="TRACKERLOG",
|
|
73
|
+
),
|
|
74
|
+
])
|
|
75
|
+
without_tracker = _build_item([_base_row()])
|
|
76
|
+
|
|
77
|
+
assert with_tracker.has_vehicle_tracker is True
|
|
78
|
+
assert with_tracker.vehicle_tracker_company == "TRACKERLOG"
|
|
79
|
+
|
|
80
|
+
assert without_tracker.has_vehicle_tracker is False
|
|
81
|
+
assert without_tracker.vehicle_tracker_company is None
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_alienado_na_is_false():
|
|
85
|
+
item = _build_item([_base_row(ALIENADO="N/A")])
|
|
86
|
+
|
|
87
|
+
assert item.is_alienated is False
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def test_rastreamento_maps_to_tracker():
|
|
91
|
+
item = _build_item([
|
|
92
|
+
_base_row(NME_BENEFICIO="Casco PT (VEÍCULO)", VALOR_MENSALIDADE="100.00"),
|
|
93
|
+
_base_row(
|
|
94
|
+
NME_BENEFICIO="Rastreamento",
|
|
95
|
+
VALOR_MENSALIDADE="12.50",
|
|
96
|
+
EMPRESA_RASTREAMENTO="TRACKERLOG",
|
|
97
|
+
),
|
|
98
|
+
])
|
|
99
|
+
|
|
100
|
+
assert item.has_vehicle_tracker is True
|
|
101
|
+
assert item.vehicle_tracker_premium == 12.50
|
|
102
|
+
assert item.vehicle_tracker_company == "TRACKERLOG"
|
|
103
|
+
assert item.has_monitored_emergency_support is False
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def test_rastreamento_reboque_maps_to_tracker():
|
|
107
|
+
rows = [
|
|
108
|
+
{
|
|
109
|
+
**_base_row(
|
|
110
|
+
PLACA_VEICULO="XYZ9A99",
|
|
111
|
+
CODE_FIPE=None,
|
|
112
|
+
NME_BENEFICIO="Casco PT (R/SR)",
|
|
113
|
+
VALOR_MENSALIDADE="50.00",
|
|
114
|
+
IMPORTANCIA_SEGURADA="50000",
|
|
115
|
+
),
|
|
116
|
+
"MARCA_REBOQUE": "RANDON",
|
|
117
|
+
"MODELO_REBOQUE": "SR BAU",
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
**_base_row(
|
|
121
|
+
PLACA_VEICULO="XYZ9A99",
|
|
122
|
+
CODE_FIPE=None,
|
|
123
|
+
NME_BENEFICIO="Rastreamento Reboque/Semirreboque",
|
|
124
|
+
VALOR_MENSALIDADE="8.00",
|
|
125
|
+
),
|
|
126
|
+
"MARCA_REBOQUE": "RANDON",
|
|
127
|
+
"MODELO_REBOQUE": "SR BAU",
|
|
128
|
+
},
|
|
129
|
+
]
|
|
130
|
+
item = _build_item(rows)
|
|
131
|
+
|
|
132
|
+
assert item.item_type == "reboque"
|
|
133
|
+
assert item.has_vehicle_tracker is True
|
|
134
|
+
assert item.vehicle_tracker_premium == 8.00
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def test_monitored_emergency_support_isolated_from_tracker():
|
|
138
|
+
item = _build_item([
|
|
139
|
+
_base_row(NME_BENEFICIO="Casco PT (VEÍCULO)", VALOR_MENSALIDADE="100.00"),
|
|
140
|
+
_base_row(
|
|
141
|
+
NME_BENEFICIO="SUPORTE EMERGENCIAL MONITORADO",
|
|
142
|
+
VALOR_MENSALIDADE="13.47",
|
|
143
|
+
EMPRESA_RASTREAMENTO="TRACKERLOG",
|
|
144
|
+
),
|
|
145
|
+
])
|
|
146
|
+
|
|
147
|
+
assert item.has_monitored_emergency_support is True
|
|
148
|
+
assert item.monitored_emergency_support_premium == 13.47
|
|
149
|
+
assert item.monitored_emergency_support_value == 1
|
|
150
|
+
assert item.has_vehicle_tracker is False
|
|
151
|
+
assert item.vehicle_tracker_company is None
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def test_repair_assistance_consolidates_into_hull_premium():
|
|
155
|
+
item = _build_item([
|
|
156
|
+
_base_row(
|
|
157
|
+
NME_BENEFICIO="Casco PT (VEÍCULO)",
|
|
158
|
+
VALOR_MENSALIDADE="372.24",
|
|
159
|
+
IMPORTANCIA_SEGURADA="308130",
|
|
160
|
+
),
|
|
161
|
+
_base_row(
|
|
162
|
+
NME_BENEFICIO="Assistência a Reparos (VEÍCULO)",
|
|
163
|
+
VALOR_MENSALIDADE="267.38",
|
|
164
|
+
IMPORTANCIA_SEGURADA="308130",
|
|
165
|
+
),
|
|
166
|
+
_base_row(
|
|
167
|
+
NME_BENEFICIO="Casco PT (COMPLEMENTO)",
|
|
168
|
+
VALOR_MENSALIDADE="25.64",
|
|
169
|
+
IMPORTANCIA_SEGURADA="27000",
|
|
170
|
+
),
|
|
171
|
+
_base_row(
|
|
172
|
+
NME_BENEFICIO="Assistência a Reparos (COMPLEMENTO)",
|
|
173
|
+
VALOR_MENSALIDADE="21.86",
|
|
174
|
+
IMPORTANCIA_SEGURADA="27000",
|
|
175
|
+
),
|
|
176
|
+
])
|
|
177
|
+
|
|
178
|
+
assert item.hull_premium == 687.12
|
|
179
|
+
assert item.hull_value == 308130
|
|
180
|
+
assert item.repair_assistance_premium == 0
|
|
181
|
+
assert item.has_repair_assistance is False
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{transdesk_importer_python_sdk-1.0.0 → transdesk_importer_python_sdk-1.2.0}/tests/test_validator.py
RENAMED
|
File without changes
|