attime-star-api-python-sdk 1.9.0__tar.gz → 1.9.1__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 (26) hide show
  1. {attime_star_api_python_sdk-1.9.0/src/attime_star_api_python_sdk.egg-info → attime_star_api_python_sdk-1.9.1}/PKG-INFO +1 -1
  2. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/pyproject.toml +1 -1
  3. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/dtos/ecommerce.py +25 -2
  4. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1/src/attime_star_api_python_sdk.egg-info}/PKG-INFO +1 -1
  5. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/tests/test_attime001_importar_ecommerce.py +36 -5
  6. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/LICENSE +0 -0
  7. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/README.md +0 -0
  8. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/setup.cfg +0 -0
  9. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/api.py +0 -0
  10. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/apis/__init__.py +0 -0
  11. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/apis/attime001.py +0 -0
  12. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/apis/bvix.py +0 -0
  13. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/apis/infocar.py +0 -0
  14. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/dtos/__init__.py +0 -0
  15. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/dtos/attime001.py +0 -0
  16. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/dtos/bvix.py +0 -0
  17. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/dtos/enums.py +0 -0
  18. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/dtos/infocar.py +0 -0
  19. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime/star/dtos/serde.py +0 -0
  20. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime_star_api_python_sdk.egg-info/SOURCES.txt +0 -0
  21. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime_star_api_python_sdk.egg-info/dependency_links.txt +0 -0
  22. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/src/attime_star_api_python_sdk.egg-info/top_level.txt +0 -0
  23. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/tests/test_attime001_atualizacoes.py +0 -0
  24. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/tests/test_attime001_cancelamento.py +0 -0
  25. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/tests/test_attime001_insere_item.py +0 -0
  26. {attime_star_api_python_sdk-1.9.0 → attime_star_api_python_sdk-1.9.1}/tests/test_attime001_relacao.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: attime-star-api-python-sdk
3
- Version: 1.9.0
3
+ Version: 1.9.1
4
4
  Summary: Client HTTP de comunicacao com a API da ATTime Star
5
5
  Author-email: Filipe Coelho <filipe@fmconsult.com.br>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "attime-star-api-python-sdk"
7
- version = "1.9.0"
7
+ version = "1.9.1"
8
8
  description = "Client HTTP de comunicacao com a API da ATTime Star"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -3,7 +3,8 @@
3
3
 
4
4
  POST /btc/ABTP0004/ApiAttime001/ImportarEcommerce
5
5
 
6
- ``formaPagamento.dadosPagamento`` permanece ``dict`` até a STAR tipar o schema.
6
+ ``formaPagamento.dadosPagamento`` é ``dict`` livre:
7
+ boleto → ``{EnderecoCobranca: ""}``; cartão/PIX tipagem ainda pendente.
7
8
  """
8
9
  from __future__ import annotations
9
10
 
@@ -67,6 +68,18 @@ class EcommerceTelefoneDto:
67
68
  return from_dataclass(cls, data)
68
69
 
69
70
 
71
+ # Alinhamento STAR Homol: para PJ estes campos devem ir no JSON como null
72
+ # (não omitidos). PF continua com omit_none quando vazios.
73
+ # ``nomeSocial`` em PJ vai como string vazia (``""``), não null.
74
+ _PJ_NULL_WIRE_FIELDS = (
75
+ 'codigoSexo',
76
+ 'codigoEstadoCivil',
77
+ 'tipoDocumentoIdentificacao',
78
+ 'numeroDocumento',
79
+ 'codigoProfissao',
80
+ )
81
+
82
+
70
83
  @dataclass
71
84
  class EcommerceClienteDto:
72
85
  cpfCnpj: Optional[str] = None
@@ -82,8 +95,13 @@ class EcommerceClienteDto:
82
95
  endereco: Optional[list[EcommerceEnderecoDto]] = None
83
96
  telefone: Optional[list[EcommerceTelefoneDto]] = None
84
97
 
98
+ @staticmethod
99
+ def _is_cnpj(cpf_cnpj: Optional[str]) -> bool:
100
+ digits = ''.join(ch for ch in str(cpf_cnpj or '') if ch.isdigit())
101
+ return len(digits) >= 14
102
+
85
103
  def to_dict(self) -> dict:
86
- return omit_none({
104
+ data = omit_none({
87
105
  'cpfCnpj': self.cpfCnpj,
88
106
  'nomeCompleto': self.nomeCompleto,
89
107
  'dataNascimentoFundacao': self.dataNascimentoFundacao,
@@ -97,6 +115,11 @@ class EcommerceClienteDto:
97
115
  'endereco': to_wire(self.endereco),
98
116
  'telefone': to_wire(self.telefone),
99
117
  })
118
+ if self._is_cnpj(self.cpfCnpj):
119
+ for key in _PJ_NULL_WIRE_FIELDS:
120
+ data[key] = None
121
+ data['nomeSocial'] = ''
122
+ return data
100
123
 
101
124
  @classmethod
102
125
  def from_dict(cls, data: dict | EcommerceClienteDto | None):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: attime-star-api-python-sdk
3
- Version: 1.9.0
3
+ Version: 1.9.1
4
4
  Summary: Client HTTP de comunicacao com a API da ATTime Star
5
5
  Author-email: Filipe Coelho <filipe@fmconsult.com.br>
6
6
  License: MIT License
@@ -68,7 +68,7 @@ def _minimal_payload() -> ApiAttime001ImportarEcommerceDTO:
68
68
  tipoItem=TipoItem.AUTOMOVEL,
69
69
  formaPagamento=EcommerceFormaPagamentoDto(
70
70
  diaVencimentoParcelaFatura=10,
71
- dadosPagamento={'forma': 'boleto'}, # tipagem pendente STAR
71
+ dadosPagamento={'EnderecoCobranca': ''},
72
72
  ),
73
73
  itens=[
74
74
  EcommerceItemDto(
@@ -102,13 +102,44 @@ class TestApiAttime001ImportarEcommerceDTO(unittest.TestCase):
102
102
  )
103
103
  self.assertEqual(data['emissao']['contratos']['tipoItem'], 20)
104
104
  self.assertEqual(
105
- data['emissao']['contratos']['formaPagamento']['dadosPagamento']['forma'],
106
- 'boleto',
105
+ data['emissao']['contratos']['formaPagamento']['dadosPagamento'],
106
+ {'EnderecoCobranca': ''},
107
107
  )
108
108
  again = ApiAttime001ImportarEcommerceDTO.from_dict(data)
109
109
  self.assertEqual(again.emissao.clientes.cpfCnpj, '12345678901')
110
110
  self.assertEqual(again.emissao.contratos.itens[0].caracteristicas[0].codigo, 39)
111
111
 
112
+ def test_pj_cliente_wires_pf_attrs_as_null(self):
113
+ """STAR Homol: PJ deve enviar as chaves PF com null (não omitir)."""
114
+ cliente = EcommerceClienteDto(
115
+ cpfCnpj='41413609000170',
116
+ nomeCompleto='RMA TRANSPORTE',
117
+ dataNascimentoFundacao='2020-01-01T00:00:00',
118
+ )
119
+ data = cliente.to_dict()
120
+ for key in (
121
+ 'codigoSexo',
122
+ 'codigoEstadoCivil',
123
+ 'tipoDocumentoIdentificacao',
124
+ 'numeroDocumento',
125
+ 'codigoProfissao',
126
+ ):
127
+ self.assertIn(key, data)
128
+ self.assertIsNone(data[key])
129
+ self.assertIn('nomeSocial', data)
130
+ self.assertEqual(data['nomeSocial'], '')
131
+
132
+ def test_pf_cliente_omits_empty_optional_pf_attrs(self):
133
+ cliente = EcommerceClienteDto(
134
+ cpfCnpj='12345678901',
135
+ nomeCompleto='JOAO',
136
+ codigoSexo=Sexo.MASCULINO,
137
+ )
138
+ data = cliente.to_dict()
139
+ self.assertEqual(data['codigoSexo'], 'M')
140
+ self.assertNotIn('tipoDocumentoIdentificacao', data)
141
+ self.assertNotIn('numeroDocumento', data)
142
+
112
143
  def test_dados_pagamento_must_be_dict(self):
113
144
  with self.assertRaises(TypeError):
114
145
  EcommerceFormaPagamentoDto.from_dict({
@@ -149,8 +180,8 @@ class TestAttime001ApiImportarEcommerce(unittest.TestCase):
149
180
  self.assertEqual(
150
181
  kwargs['payload']['emissao']['contratos']['formaPagamento'][
151
182
  'dadosPagamento'
152
- ]['forma'],
153
- 'boleto',
183
+ ],
184
+ {'EnderecoCobranca': ''},
154
185
  )
155
186
 
156
187