attime-star-arquivo-ecommerce-python-sdk 1.1.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.
Files changed (43) hide show
  1. attime_star_arquivo_ecommerce_python_sdk-1.1.0/LICENSE +5 -0
  2. attime_star_arquivo_ecommerce_python_sdk-1.1.0/PKG-INFO +25 -0
  3. attime_star_arquivo_ecommerce_python_sdk-1.1.0/README.md +1 -0
  4. attime_star_arquivo_ecommerce_python_sdk-1.1.0/pyproject.toml +36 -0
  5. attime_star_arquivo_ecommerce_python_sdk-1.1.0/setup.cfg +4 -0
  6. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/__init__.py +26 -0
  7. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/__init__.py +28 -0
  8. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_001.py +54 -0
  9. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_002.py +27 -0
  10. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_003.py +23 -0
  11. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_004.py +74 -0
  12. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_005.py +67 -0
  13. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_006.py +46 -0
  14. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_007.py +51 -0
  15. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_009.py +86 -0
  16. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_013.py +46 -0
  17. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_015.py +42 -0
  18. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_017.py +41 -0
  19. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/blocks/block_020.py +94 -0
  20. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/__init__.py +30 -0
  21. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/address.py +16 -0
  22. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/auto_item.py +63 -0
  23. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/cancel.py +12 -0
  24. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/commission.py +13 -0
  25. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/contract.py +26 -0
  26. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/coverage.py +18 -0
  27. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/customer.py +20 -0
  28. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/installment.py +17 -0
  29. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/new_contract_remessa.py +32 -0
  30. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/payment_confirm.py +9 -0
  31. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/phone.py +11 -0
  32. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/questionnaire.py +12 -0
  33. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/dtos/service.py +16 -0
  34. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/formatting.py +90 -0
  35. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/remessa.py +156 -0
  36. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime/star/arquivo_ecommerce/sftp.py +59 -0
  37. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime_star_arquivo_ecommerce_python_sdk.egg-info/PKG-INFO +25 -0
  38. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime_star_arquivo_ecommerce_python_sdk.egg-info/SOURCES.txt +41 -0
  39. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime_star_arquivo_ecommerce_python_sdk.egg-info/dependency_links.txt +1 -0
  40. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime_star_arquivo_ecommerce_python_sdk.egg-info/requires.txt +5 -0
  41. attime_star_arquivo_ecommerce_python_sdk-1.1.0/src/attime_star_arquivo_ecommerce_python_sdk.egg-info/top_level.txt +1 -0
  42. attime_star_arquivo_ecommerce_python_sdk-1.1.0/tests/test_block_020.py +32 -0
  43. attime_star_arquivo_ecommerce_python_sdk-1.1.0/tests/test_golden.py +294 -0
@@ -0,0 +1,5 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Seu Nome
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy...
@@ -0,0 +1,25 @@
1
+ Metadata-Version: 2.4
2
+ Name: attime-star-arquivo-ecommerce-python-sdk
3
+ Version: 1.1.0
4
+ Summary: Gerador de remessa ArquivoEcommerce (.grv) + SFTP para ATTime STAR
5
+ Author-email: Filipe Coelho <filipe@fmconsult.com.br>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2025 Seu Nome
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy...
11
+
12
+ Keywords: sdk,attime,star,arquivo-ecommerce,sftp
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Requires-Python: >=3.11
17
+ Description-Content-Type: text/markdown
18
+ License-File: LICENSE
19
+ Requires-Dist: pysftp>=0.2.9
20
+ Requires-Dist: paramiko<3.0
21
+ Provides-Extra: dev
22
+ Requires-Dist: pytest>=7.0; extra == "dev"
23
+ Dynamic: license-file
24
+
25
+ # ATTime STAR ArquivoEcommerce remessa (.grv) + SFTP
@@ -0,0 +1 @@
1
+ # ATTime STAR ArquivoEcommerce remessa (.grv) + SFTP
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "attime-star-arquivo-ecommerce-python-sdk"
7
+ version = "1.1.0"
8
+ description = "Gerador de remessa ArquivoEcommerce (.grv) + SFTP para ATTime STAR"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = {file = "LICENSE"}
12
+ authors = [
13
+ {name = "Filipe Coelho", email = "filipe@fmconsult.com.br"},
14
+ ]
15
+ keywords = ["sdk", "attime", "star", "arquivo-ecommerce", "sftp"]
16
+ classifiers = [
17
+ "Programming Language :: Python :: 3",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Operating System :: OS Independent",
20
+ ]
21
+
22
+ dependencies = [
23
+ "pysftp>=0.2.9",
24
+ "paramiko<3.0",
25
+ ]
26
+
27
+ [project.optional-dependencies]
28
+ dev = ["pytest>=7.0"]
29
+
30
+ [tool.setuptools.packages.find]
31
+ where = ["src"]
32
+ namespaces = true
33
+
34
+ [tool.pytest.ini_options]
35
+ testpaths = ["tests"]
36
+ pythonpath = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,26 @@
1
+ # -*- coding: utf-8 -*-
2
+ from attime.star.arquivo_ecommerce.formatting import BLOCK_SIZES
3
+ from attime.star.arquivo_ecommerce.remessa import (
4
+ RemessaResult,
5
+ build_cancel_remessa,
6
+ build_installment_remessa,
7
+ build_new_contract_remessa,
8
+ build_payment_confirm_remessa,
9
+ )
10
+
11
+ __all__ = [
12
+ 'BLOCK_SIZES',
13
+ 'RemessaResult',
14
+ 'SftpClient',
15
+ 'build_cancel_remessa',
16
+ 'build_installment_remessa',
17
+ 'build_new_contract_remessa',
18
+ 'build_payment_confirm_remessa',
19
+ ]
20
+
21
+
22
+ def __getattr__(name):
23
+ if name == 'SftpClient':
24
+ from attime.star.arquivo_ecommerce.sftp import SftpClient
25
+ return SftpClient
26
+ raise AttributeError(f'module {__name__!r} has no attribute {name!r}')
@@ -0,0 +1,28 @@
1
+ # -*- coding: utf-8 -*-
2
+ from attime.star.arquivo_ecommerce.blocks.block_001 import build_block_001
3
+ from attime.star.arquivo_ecommerce.blocks.block_002 import build_block_002
4
+ from attime.star.arquivo_ecommerce.blocks.block_003 import build_block_003
5
+ from attime.star.arquivo_ecommerce.blocks.block_004 import build_block_004
6
+ from attime.star.arquivo_ecommerce.blocks.block_005 import build_block_005
7
+ from attime.star.arquivo_ecommerce.blocks.block_006 import build_block_006
8
+ from attime.star.arquivo_ecommerce.blocks.block_007 import build_block_007
9
+ from attime.star.arquivo_ecommerce.blocks.block_009 import build_block_009
10
+ from attime.star.arquivo_ecommerce.blocks.block_013 import build_block_013
11
+ from attime.star.arquivo_ecommerce.blocks.block_015 import build_block_015
12
+ from attime.star.arquivo_ecommerce.blocks.block_017 import build_block_017
13
+ from attime.star.arquivo_ecommerce.blocks.block_020 import build_block_020
14
+
15
+ __all__ = [
16
+ 'build_block_001',
17
+ 'build_block_002',
18
+ 'build_block_003',
19
+ 'build_block_004',
20
+ 'build_block_005',
21
+ 'build_block_006',
22
+ 'build_block_007',
23
+ 'build_block_009',
24
+ 'build_block_013',
25
+ 'build_block_015',
26
+ 'build_block_017',
27
+ 'build_block_020',
28
+ ]
@@ -0,0 +1,54 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ import re
5
+
6
+ from attime.star.arquivo_ecommerce.dtos.customer import Customer
7
+ from attime.star.arquivo_ecommerce.formatting import (
8
+ assert_block_size,
9
+ formata_valor,
10
+ pad_left,
11
+ zfill_num,
12
+ )
13
+
14
+
15
+ def build_block_001(customer: Customer) -> str:
16
+ block_number = '001'
17
+ line = block_number
18
+
19
+ line += zfill_num(customer.cpf, 14)
20
+ line += pad_left(str(customer.full_name), 60)
21
+ line += zfill_num(customer.birth_date.strftime('%d%m%Y'), 8)
22
+ line += pad_left('', 50)
23
+
24
+ gender_code = customer.gender_code if customer.gender_code is not None else '01'
25
+ line += zfill_num(gender_code, 2)
26
+ line += pad_left('', 40)
27
+
28
+ marital_status_code = (
29
+ customer.marital_status_code if customer.marital_status_code is not None else '06'
30
+ )
31
+ line += zfill_num(marital_status_code, 2)
32
+ line += '01'
33
+ line += pad_left('', 15)
34
+ line += pad_left('', 15)
35
+ line += zfill_num('', 8)
36
+
37
+ career_code = customer.career_code
38
+ if career_code is not None:
39
+ career_code = str(career_code).split('-')[0].strip()
40
+ else:
41
+ career_code = ''
42
+ line += zfill_num(career_code, 6)
43
+ line += formata_valor(0, 13, 11)
44
+ line += pad_left(str(customer.email_address), 100)
45
+
46
+ social_name = (
47
+ customer.social_name
48
+ if customer.social_name is not None and len(customer.social_name) > 0
49
+ else ''
50
+ )
51
+ line += pad_left(social_name, 60)
52
+
53
+ assert_block_size(block_number, line)
54
+ return (line + '\n').upper()
@@ -0,0 +1,27 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ import re
5
+
6
+ from attime.star.arquivo_ecommerce.dtos.address import Address
7
+ from attime.star.arquivo_ecommerce.dtos.customer import Customer
8
+ from attime.star.arquivo_ecommerce.formatting import assert_block_size, pad_left, zfill_num
9
+
10
+
11
+ def build_block_002(customer: Customer, address: Address) -> str:
12
+ block_number = '002'
13
+ line = block_number
14
+
15
+ line += zfill_num(customer.cpf, 14)
16
+ line += zfill_num(address.type_code, 2)
17
+ line += re.sub(r'\D', '', str(address.cep)).zfill(8)
18
+ line += pad_left(str(address.acronym_federal_unit), 2)
19
+ line += pad_left(str(address.city_name), 40)
20
+ line += pad_left(str(address.name), 50)
21
+ line += pad_left(str(address.number), 10)
22
+ line += pad_left(str(address.complement), 40)
23
+ line += pad_left(str(address.district), 40)
24
+ line += 'S'
25
+
26
+ assert_block_size(block_number, line)
27
+ return (line + '\n').upper()
@@ -0,0 +1,23 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ from attime.star.arquivo_ecommerce.dtos.customer import Customer
5
+ from attime.star.arquivo_ecommerce.dtos.phone import Phone
6
+ from attime.star.arquivo_ecommerce.formatting import assert_block_size, zfill_num
7
+
8
+
9
+ def build_block_003(customer: Customer, phone: Phone) -> str:
10
+ block_number = '003'
11
+ line = block_number
12
+
13
+ line += zfill_num(customer.cpf, 14)
14
+ line += zfill_num(phone.telphone_type_code, 2)
15
+ line += zfill_num(phone.ddd, 2)
16
+
17
+ phone_number = ''.join(filter(str.isdigit, str(phone.number)))
18
+ phone_number = phone_number[-9:].zfill(9)
19
+ line += phone_number
20
+ line += 'S'
21
+
22
+ assert_block_size(block_number, line)
23
+ return (line + '\n').upper()
@@ -0,0 +1,74 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ from attime.star.arquivo_ecommerce.dtos.contract import Contract
5
+ from attime.star.arquivo_ecommerce.formatting import (
6
+ DEFAULT_CONVENIO,
7
+ DEFAULT_SUCURSAL,
8
+ DEFAULT_TIPO_ITEM,
9
+ assert_block_size,
10
+ coalesce,
11
+ formata_valor,
12
+ format_date_ddmmaaaa,
13
+ normalize_product_code,
14
+ pad_left,
15
+ zfill_num,
16
+ )
17
+
18
+
19
+ def build_block_004(contract: Contract) -> str:
20
+ block_number = '004'
21
+ line = block_number
22
+
23
+ product_type_code = normalize_product_code(contract.product_type_code)
24
+ line += product_type_code
25
+
26
+ sucursal = coalesce(contract.sucursal, DEFAULT_SUCURSAL)
27
+ line += sucursal
28
+
29
+ contract_number = contract.contract_number if contract.contract_number is not None else 0
30
+ line += zfill_num(contract_number, 6)
31
+ line += pad_left('A', 1)
32
+ line += pad_left(str(contract.frequency_code), 1)
33
+ line += zfill_num(contract.cpf, 14)
34
+ line += pad_left(str(contract.billing_method_code), 3)
35
+
36
+ convenio = coalesce(contract.convenio, DEFAULT_CONVENIO)
37
+ line += convenio
38
+
39
+ if contract.due_at is not None:
40
+ line += format_date_ddmmaaaa(contract.due_at)
41
+ else:
42
+ line += format_date_ddmmaaaa(contract.created_at)
43
+
44
+ line += format_date_ddmmaaaa(contract.insurance_effective_date)
45
+
46
+ if contract.insurance_end_date is not None:
47
+ line += format_date_ddmmaaaa(contract.insurance_end_date)
48
+ else:
49
+ line += zfill_num('', 8)
50
+
51
+ num_proposta = f'{str(product_type_code).zfill(3)} 1 01 {contract_number}'
52
+ line += pad_left(str(num_proposta), 15)
53
+ line += zfill_num('0', 14)
54
+ line += formata_valor(contract.admin_expense_percent, 8, 3)
55
+ line += formata_valor(contract.profit_tax_percent, 8, 3)
56
+ line += formata_valor(0, 8, 3)
57
+ line += formata_valor(contract.commission_percent, 8, 3)
58
+ line += formata_valor(0, 8, 3)
59
+ line += formata_valor(0, 13, 11)
60
+ line += '0'
61
+
62
+ tipo_item = coalesce(contract.tipo_item, DEFAULT_TIPO_ITEM)
63
+ line += tipo_item
64
+
65
+ line += pad_left('', 10)
66
+ line += pad_left('', 10)
67
+ line += pad_left('', 10)
68
+ line += pad_left('', 10)
69
+ line += pad_left('', 10)
70
+ line += pad_left('', 7)
71
+ line += pad_left(str(contract.legacy_contract_number), 30)
72
+
73
+ assert_block_size(block_number, line)
74
+ return (line + '\n').upper()
@@ -0,0 +1,67 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ from attime.star.arquivo_ecommerce.dtos.contract import Contract
5
+ from attime.star.arquivo_ecommerce.dtos.coverage import Coverage
6
+ from attime.star.arquivo_ecommerce.formatting import (
7
+ DEFAULT_SUCURSAL,
8
+ assert_block_size,
9
+ coalesce,
10
+ formata_valor,
11
+ normalize_product_code,
12
+ zfill_num,
13
+ )
14
+
15
+
16
+ def build_block_005(
17
+ contract: Contract,
18
+ coverage: Coverage,
19
+ *,
20
+ admin_expense_percent: float,
21
+ profit_tax_percent: float,
22
+ commission_percent: float,
23
+ ) -> str:
24
+ block_number = '005'
25
+ line = block_number
26
+
27
+ product_type_code = normalize_product_code(contract.product_type_code)
28
+ line += product_type_code
29
+
30
+ sucursal = coalesce(contract.sucursal, DEFAULT_SUCURSAL)
31
+ line += sucursal
32
+
33
+ contract_number = contract.contract_number if contract.contract_number is not None else 0
34
+ line += zfill_num(contract_number, 6)
35
+
36
+ topping_code = coverage.topping_code if coverage.topping_code is not None else ''
37
+ if len(topping_code) > 4:
38
+ topping_code = topping_code[:4].strip()
39
+ line += str(topping_code).replace(',', '').replace('.', '').zfill(4)
40
+
41
+ insured_amount = coverage.value_insured_coverage_amount
42
+ line += formata_valor(insured_amount, 13, 11)
43
+
44
+ if coverage.coverage_pure_tax is not None:
45
+ pure_tax = (
46
+ (((coverage.coverage_pure_tax / 100) * insured_amount) / 12) / insured_amount
47
+ )
48
+ pure_tax_value = formata_valor(pure_tax, 13, 5)
49
+ line += pure_tax_value
50
+
51
+ clear_net_amount = ((coverage.coverage_pure_tax / 100) * insured_amount) / 12
52
+ clear_net_amount_value = formata_valor(clear_net_amount, 13, 11)
53
+ line += clear_net_amount_value
54
+ else:
55
+ pure_tax_value = formata_valor(coverage.pure_tax or 0, 13, 5)
56
+ line += pure_tax_value
57
+
58
+ clear_net_amount_value = formata_valor(coverage.net_premium_value or 0, 13, 11)
59
+ line += clear_net_amount_value
60
+
61
+ franchise_code = coverage.franchise_code if coverage.franchise_code is not None else ''
62
+ line += zfill_num(str(franchise_code).replace(',', '').replace('.', ''), 3)
63
+ line += formata_valor(coverage.franchise_value or 0, 13, 11)
64
+ line += formata_valor(coverage.franchise_tax or 0, 8, 3)
65
+
66
+ assert_block_size(block_number, line)
67
+ return (line + '\n').upper()
@@ -0,0 +1,46 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ from attime.star.arquivo_ecommerce.dtos.contract import Contract
5
+ from attime.star.arquivo_ecommerce.dtos.service import Service
6
+ from attime.star.arquivo_ecommerce.formatting import (
7
+ DEFAULT_SUCURSAL,
8
+ assert_block_size,
9
+ coalesce,
10
+ formata_valor,
11
+ normalize_product_code,
12
+ pad_left,
13
+ zfill_num,
14
+ )
15
+
16
+
17
+ def build_block_006(contract: Contract, service: Service) -> str:
18
+ """006 — serviço da cobertura (58 chars)."""
19
+ block_number = '006'
20
+ line = block_number
21
+
22
+ product_type_code = normalize_product_code(contract.product_type_code)
23
+ line += product_type_code
24
+
25
+ sucursal = coalesce(contract.sucursal, DEFAULT_SUCURSAL)
26
+ line += sucursal
27
+
28
+ contract_number = contract.contract_number if contract.contract_number is not None else 0
29
+ line += zfill_num(contract_number, 6)
30
+
31
+ service_code = service.service_code if service.service_code is not None else ''
32
+ if len(str(service_code)) > 4:
33
+ service_code = str(service_code)[:4].strip()
34
+ line += str(service_code).replace(',', '').replace('.', '').zfill(4)
35
+
36
+ topping_code = service.topping_code if service.topping_code is not None else ''
37
+ if len(str(topping_code)) > 4:
38
+ topping_code = str(topping_code)[:4].strip()
39
+ line += str(topping_code).replace(',', '').replace('.', '').zfill(4)
40
+
41
+ line += formata_valor(service.value or 0, 13, 11)
42
+ line += pad_left(coalesce(service.raffle_number, ''), 20)
43
+ line += pad_left(coalesce(service.raffle_series, ''), 3)
44
+
45
+ assert_block_size(block_number, line)
46
+ return (line + '\n').upper()
@@ -0,0 +1,51 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ from attime.star.arquivo_ecommerce.dtos.commission import Commission
5
+ from attime.star.arquivo_ecommerce.dtos.contract import Contract
6
+ from attime.star.arquivo_ecommerce.formatting import (
7
+ DEFAULT_COMMISSION_CODE,
8
+ DEFAULT_SUCURSAL,
9
+ assert_block_size,
10
+ coalesce,
11
+ formata_valor,
12
+ normalize_product_code,
13
+ pad_left,
14
+ zfill_num,
15
+ )
16
+
17
+
18
+ def build_block_007(contract: Contract, commission: Commission) -> str:
19
+ block_number = '007'
20
+ line = block_number
21
+
22
+ product_type_code = normalize_product_code(contract.product_type_code)
23
+ line += product_type_code
24
+
25
+ sucursal = coalesce(contract.sucursal, DEFAULT_SUCURSAL)
26
+ line += sucursal
27
+
28
+ contract_number = contract.contract_number if contract.contract_number is not None else 0
29
+ line += zfill_num(contract_number, 6)
30
+
31
+ if commission.reseller_document is not None:
32
+ line += zfill_num(commission.reseller_document, 14)
33
+ else:
34
+ line += zfill_num('0', 14)
35
+
36
+ if commission.internal_code is not None:
37
+ line += pad_left(str(commission.internal_code), 3)
38
+ else:
39
+ line += pad_left('', 3)
40
+
41
+ try:
42
+ commission_code = str(
43
+ commission.commission_codes[str(commission.product_commission_percent)]
44
+ )
45
+ except Exception:
46
+ commission_code = DEFAULT_COMMISSION_CODE
47
+ line += pad_left(commission_code, 5)
48
+ line += formata_valor(100, 8, 3)
49
+
50
+ assert_block_size(block_number, line)
51
+ return (line + '\n').upper()
@@ -0,0 +1,86 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ from attime.star.arquivo_ecommerce.dtos.contract import Contract
5
+ from attime.star.arquivo_ecommerce.dtos.installment import Installment
6
+ from attime.star.arquivo_ecommerce.formatting import (
7
+ DEFAULT_SUCURSAL,
8
+ assert_block_size,
9
+ coalesce,
10
+ formata_valor,
11
+ format_date_ddmmaaaa,
12
+ normalize_product_code,
13
+ pad_left,
14
+ zfill_num,
15
+ )
16
+
17
+
18
+ def build_block_009(contract: Contract, installment: Installment) -> str:
19
+ block_number = '009'
20
+ line = block_number
21
+
22
+ product_type_code = normalize_product_code(contract.product_type_code)
23
+ line += product_type_code
24
+
25
+ sucursal = coalesce(contract.sucursal, DEFAULT_SUCURSAL)
26
+ line += sucursal
27
+
28
+ contract_number = contract.contract_number if contract.contract_number is not None else 0
29
+ line += zfill_num(contract_number, 6)
30
+
31
+ line += format_date_ddmmaaaa(installment.due_at)
32
+ line += format_date_ddmmaaaa(installment.due_at)
33
+
34
+ if installment.confirmed_at is not None:
35
+ line += format_date_ddmmaaaa(installment.confirmed_at)
36
+ else:
37
+ line += zfill_num('', 8)
38
+
39
+ if installment.issued_at is not None:
40
+ line += format_date_ddmmaaaa(installment.issued_at)
41
+ elif installment.created_at is not None:
42
+ line += format_date_ddmmaaaa(installment.created_at)
43
+ else:
44
+ line += zfill_num('', 8)
45
+
46
+ if installment.created_at is not None:
47
+ line += format_date_ddmmaaaa(installment.created_at)
48
+ else:
49
+ line += zfill_num('', 8)
50
+
51
+ line += formata_valor(installment.amount, 13, 2)
52
+ line += formata_valor(0, 11, 2)
53
+ line += formata_valor(0, 11, 2)
54
+ line += formata_valor(0, 11, 2)
55
+ line += formata_valor(0, 11, 2)
56
+ line += formata_valor(0, 11, 2)
57
+ line += formata_valor(0, 11, 2)
58
+ line += formata_valor(0, 11, 2)
59
+
60
+ if installment.due_at is not None:
61
+ line += zfill_num(installment.due_at.strftime('%d'), 2)
62
+ else:
63
+ line += zfill_num('', 2)
64
+
65
+ line += installment.number.zfill(10)
66
+ line += zfill_num('0', 2)
67
+ line += zfill_num('0', 16)
68
+ line += pad_left('', 20)
69
+ line += zfill_num('0', 3)
70
+ line += zfill_num('0', 6)
71
+ line += zfill_num('0', 3)
72
+ line += pad_left('', 30)
73
+ line += zfill_num('0', 5)
74
+ line += pad_left('', 30)
75
+ line += zfill_num('0', 8)
76
+ line += zfill_num('0', 1)
77
+ line += zfill_num('0', 5)
78
+ line += pad_left('', 11)
79
+
80
+ if installment.qrcode_pix is not None:
81
+ line += pad_left(installment.qrcode_pix, 500)
82
+ else:
83
+ line += pad_left('', 500)
84
+
85
+ assert_block_size(block_number, line)
86
+ return (line + '\n').upper()
@@ -0,0 +1,46 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ from attime.star.arquivo_ecommerce.dtos.contract import Contract
5
+ from attime.star.arquivo_ecommerce.dtos.installment import Installment
6
+ from attime.star.arquivo_ecommerce.dtos.payment_confirm import PaymentConfirm
7
+ from attime.star.arquivo_ecommerce.formatting import (
8
+ assert_block_size,
9
+ formata_valor,
10
+ format_date_ddmmaaaa,
11
+ normalize_product_code,
12
+ pad_left,
13
+ zfill_num,
14
+ )
15
+
16
+
17
+ def build_block_013(
18
+ contract: Contract,
19
+ installment: Installment,
20
+ payment_confirm: PaymentConfirm,
21
+ *,
22
+ customer_cpf: int | str,
23
+ legacy_contract_number: str,
24
+ ) -> str:
25
+ block_number = '013'
26
+ line = block_number
27
+
28
+ product_type_code = normalize_product_code(contract.product_type_code)
29
+ line += product_type_code
30
+
31
+ contract_number = contract.contract_number if contract.contract_number is not None else 0
32
+ line += zfill_num(contract_number, 15)
33
+ line += zfill_num(customer_cpf, 11)
34
+ line += zfill_num('1', 3)
35
+ line += zfill_num(payment_confirm.num_parcela, 3)
36
+ line += format_date_ddmmaaaa(installment.due_at)
37
+ line += format_date_ddmmaaaa(installment.confirmed_at)
38
+ line += zfill_num('', 8)
39
+ line += formata_valor(installment.amount, 11, 2)
40
+ line += formata_valor(installment.amount, 11, 2)
41
+ line += pad_left(str(legacy_contract_number), 30)
42
+ line += formata_valor(0, 11, 2)
43
+ line += formata_valor(0, 11, 2)
44
+
45
+ assert_block_size(block_number, line)
46
+ return line.upper()
@@ -0,0 +1,42 @@
1
+ # -*- coding: utf-8 -*-
2
+ from __future__ import annotations
3
+
4
+ from datetime import datetime
5
+
6
+ from attime.star.arquivo_ecommerce.dtos.cancel import Cancel
7
+ from attime.star.arquivo_ecommerce.dtos.contract import Contract
8
+ from attime.star.arquivo_ecommerce.formatting import (
9
+ assert_block_size,
10
+ format_date_ddmmaaaa,
11
+ normalize_product_code,
12
+ pad_left,
13
+ zfill_num,
14
+ )
15
+
16
+
17
+ def build_block_015(
18
+ contract: Contract,
19
+ cancel: Cancel,
20
+ *,
21
+ customer_cpf: int | str,
22
+ ) -> str:
23
+ block_number = '015'
24
+ line = block_number
25
+
26
+ product_type_code = normalize_product_code(contract.product_type_code)
27
+ line += product_type_code
28
+
29
+ contract_number = contract.contract_number if contract.contract_number is not None else 0
30
+ line += zfill_num(contract_number, 15)
31
+ line += zfill_num(customer_cpf, 14)
32
+
33
+ if cancel.canceled_at is not None:
34
+ line += format_date_ddmmaaaa(cancel.canceled_at)
35
+ else:
36
+ line += format_date_ddmmaaaa(datetime.now())
37
+
38
+ motivo = cancel.cancel_reason if cancel.cancel_reason is not None else ''
39
+ line += pad_left(str(motivo), 65)
40
+
41
+ assert_block_size(block_number, line)
42
+ return line.upper()