Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 13 additions & 17 deletions django_afip/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,16 @@ class Meta:
sales_terms = "Credit Card"


class ClientVatConditionFactory(DjangoModelFactory):
class Meta:
model = models.ClientVatCondition
django_get_or_create = ("code",)

code = "5"
description = "Consumidor Final"
cmp_clase = "B,C"


class ReceiptFactory(DjangoModelFactory):
class Meta:
model = models.Receipt
Expand All @@ -146,26 +156,22 @@ class ReceiptWithVatAndTaxFactory(ReceiptFactory):
"""Receipt with a valid Vat and Tax, ready to validate."""

point_of_sales = LazyFunction(lambda: models.PointOfSales.objects.first())
client_vat_condition = SubFactory(ClientVatConditionFactory)

@post_generation
def post(obj: models.Receipt, create: bool, extracted: None, **kwargs) -> None:
VatFactory(vat_type__code=5, receipt=obj)
TaxFactory(tax_type__code=3, receipt=obj)


class ReceiptFCEAWithVatAndTaxFactory(ReceiptFactory):
class ReceiptFCEAWithVatAndTaxFactory(ReceiptWithVatAndTaxFactory):
"""Receipt FCEA with a valid Vat and Tax, ready to validate."""

document_number = 20111111112
point_of_sales = LazyFunction(lambda: models.PointOfSales.objects.first())
receipt_type = SubFactory(ReceiptTypeFactory, code=201)
document_type = SubFactory(DocumentTypeFactory, code=80)
expiration_date = LazyFunction(date.today)

@post_generation
def post(obj: models.Receipt, create: bool, extracted: None, **kwargs) -> None:
VatFactory(vat_type__code=5, receipt=obj)
TaxFactory(tax_type__code=3, receipt=obj)
client_vat_condition = SubFactory(ClientVatConditionFactory, code="1")


class ReceiptFCEAWithVatTaxAndOptionalsFactory(ReceiptFCEAWithVatAndTaxFactory):
Expand Down Expand Up @@ -321,16 +327,6 @@ class Meta:
vat = SubFactory(VatTypeFactory)


class ClientVatConditionFactory(DjangoModelFactory):
class Meta:
model = models.ClientVatCondition
django_get_or_create = ("code",)

code = "5"
description = "Consumidor Final"
cmp_clase = "B,C"


class ReceiptWithClientVatConditionFactory(ReceiptFactory):
"""Receipt with a valid Client VAT Condition, ready to validate."""

Expand Down
2 changes: 1 addition & 1 deletion django_afip/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1960,7 +1960,7 @@ def populate(
check_response(response)

for condition_data in response.ResultGet.CondicionIvaReceptor:
condition, created = cls.objects.update_or_create(
cls.objects.update_or_create(
code=condition_data.Id,
defaults={
"description": condition_data.Desc,
Expand Down
8 changes: 8 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@ Check the `latest tags`_ or `PyPI`_ for the latest stable release.

Any breaking changes which require intervention will be mentioned here.

13.3.0
------

- ``setuptools>=77`` is required. Previous versions would often fail to
properly parse the ``licence`` field.
- Extend supported versions of ``django-renderpdf``, ``qrcode`` and
``cryptography``.

13.2.2
------

Expand Down
9 changes: 4 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,15 @@ classifiers = [
"Typing :: Typed",
]
dependencies = [
"cryptography>=3.2,<40",
"cryptography>=3.2,<47",
"django>=4.2,<5.3",
"django_renderpdf>=3.0.0,<5.0.0",
"django_renderpdf>=3.0.0,<6.0.0",
"lxml>=3.4.4",
"pyopenssl>=16.2.0",
'backports.zoneinfo;python_version<"3.9"',
"setuptools-git>=1.1",
"wheel>=0.24.0",
"zeep>=1.1.0,<5.0.0",
"qrcode[pil]>=6.1,<8.0",
"qrcode[pil]>=6.1,<9.0",
"pyyaml>=5.3.1,<7.0.0",
# zeep depends on requests, but these specific version are incompatible.
# See: https://github.com/WhyNotHugo/django-afip/issues/211
Expand Down Expand Up @@ -90,7 +89,7 @@ funding = "https://github.com/sponsors/WhyNotHugo"
include = ["django_afip*"]

[build-system]
requires = ["setuptools>=45", "wheel", "setuptools_scm>=6.2"]
requires = ["setuptools>=77", "wheel", "setuptools_scm>=6.2"]

[tool.setuptools_scm]
write_to = "django_afip/version.py"
Expand Down
2 changes: 1 addition & 1 deletion tests/test_clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ def test_inexisting_service() -> None:

@pytest.mark.live
def test_insecure_dh_hack_required() -> None:
with pytest.raises(SSLError, match="SSL: DH_KEY_TOO_SMALL. dh key too small"):
with pytest.raises(SSLError, match="SSL: DH_KEY_TOO_SMALL\\] dh key too small"):
requests.get("https://servicios1.afip.gov.ar/wsfev1/service.asmx?WSDL")
2 changes: 1 addition & 1 deletion tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ def test_approximate_date_failure() -> None:

with pytest.raises(
exceptions.DjangoAfipException,
match="Expected to update one receipt, updated 0.",
match="Expected to update one receipt, updated 0\\.",
):
receipt.approximate_date()

Expand Down
6 changes: 4 additions & 2 deletions tests/test_webservices.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def test_authentication_with_bad_cuit() -> None:
with pytest.raises(
exceptions.AfipException,
# Note: AFIP apparently edited this message and added a typo:
match="ValidacionDeToken: No apareci[oó] CUIT en lista de relaciones:",
match=r"ValidacionDeToken: No apareci[oó] CUIT en lista de relaciones:",
):
taxpayer.fetch_points_of_sales()

Expand Down Expand Up @@ -67,7 +67,7 @@ def test_authentication_with_no_active_taxpayer() -> None:
"""Test that no TaxPayers raises an understandable error."""
with pytest.raises(
exceptions.AuthenticationError,
match="There are no taxpayers to generate a ticket.",
match="There are no taxpayers to generate a ticket\\.",
):
models.AuthTicket.objects.get_any_active("wsfe")

Expand Down Expand Up @@ -253,6 +253,7 @@ def test_receipt_queryset_validation_good_without_tax(populated_db: None) -> Non
receipt = factories.ReceiptFactory(
point_of_sales=models.PointOfSales.objects.first(),
total_amount=121,
client_vat_condition=factories.ClientVatConditionFactory(),
)
factories.VatFactory(vat_type__code=5, receipt=receipt)

Expand All @@ -271,6 +272,7 @@ def test_receipt_queryset_validation_good_without_vat(populated_db: None) -> Non
point_of_sales=models.PointOfSales.objects.first(),
receipt_type__code=11,
total_amount=109,
client_vat_condition=factories.ClientVatConditionFactory(),
)
factories.TaxFactory(tax_type__code=3, receipt=receipt)

Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ passenv =
GENTESTCSR

# Hint: quickly run a one-shot container with:
# docker run --rm -e POSTGRES_PASSWORD=postgres -p 5432:5432 -it postgres
# docker run --rm -e POSTGRES_PASSWORD=postgres -p 5432:5432 -it postgres:alpine
[testenv:live]
extras = dev, postgres
commands = pytest -vv -m "live" {posargs}
Expand Down