Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.
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
4 changes: 2 additions & 2 deletions agilize/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from agilize.agilize import (Agilize, Company, Competence, Prolabore, # noqa
Prolabores, Tax, Taxes)
from agilize.agilize import (Agilize, Company, Competence, Invoice, # noqa
Invoices, Prolabore, Prolabores, Tax, Taxes)
from agilize.client import Client # noqa
54 changes: 53 additions & 1 deletion agilize/agilize.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from attrs import define, field

from agilize.client import Client
from agilize.client import AnonymousClient, Client


class Agilize:
Expand Down Expand Up @@ -79,12 +79,38 @@ def __iter__(self):
yield from t.values()


@define(kw_only=True)
class Invoices:
client: Client
company_id: str
_invoices: dict = field(factory=dict)

def get(self, competence):
if competence not in self._invoices:
self.fetch(competence.year)

return self._invoices[competence]

def fetch(self, year):
data = self.client.invoices(self.company_id, year)

for d in data:
if not d['nfses']:
continue
invoice = Invoice.from_data(d)
self._invoices[invoice.competence] = invoice

def __iter__(self):
yield from self._invoices.values()


@define
class Company:
id: str
cnpj: str
name: str
client: Client
_invoices: Optional[Invoices] = None
_prolabores: Optional[Prolabores] = None
_taxes: Optional[Taxes] = None

Expand All @@ -97,6 +123,12 @@ def from_data(cls, data, client):
client=client,
)

@property
def invoices(self):
if not self._invoices:
self._invoices = Invoices(client=self.client, company_id=self.id)
return self._invoices

@property
def prolabores(self):
if not self._prolabores:
Expand Down Expand Up @@ -179,3 +211,23 @@ def from_data(cls, data, company_id, client):

def download(self):
return self.client.download_tax(self.company_id, self.id)


@define
class Invoice:
competence: Competence
url_nfse: str

@classmethod
def from_data(cls, data):
return cls(
competence=Competence.from_data(data['competence']),
url_nfse=data['nfses'][0]['nfseUrl'],
)

@property
def url_nfse_image(self):
return self.url_nfse.replace('notaprint.aspx', 'notaprintimg.aspx')

def download_nfse(self):
return AnonymousClient.download(self.url_nfse_image)
11 changes: 8 additions & 3 deletions agilize/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
from agilize.keycloak import Keycloak


class Client:
class AnonymousClient:
@staticmethod
def download(url):
return requests.get(url).content


class Client(AnonymousClient):
AUTH_URL = 'https://sso.agilize.com.br/auth/'
CLIENT_ID = 'agilize-legacy-client'
REALM_NAME = 'AgilizeAPPs'
Expand Down Expand Up @@ -93,8 +99,7 @@ def download_tax(self, company_id, tax_id):
url=self.url(self.PATH_DOWNLOAD_TAX, company_id=company_id, tax_id=tax_id),
headers=self.headers,
)
file_url = response.json()['url']
return requests.get(file_url).content
return self.download(response.json()['url'])

def invoices(self, company_id, year):
response = requests.get(
Expand Down
7 changes: 6 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,12 @@ def invoices_data(faker):
'naturezaOperacao': 1,
'nfseAuthUrl': faker.url(),
'nfseKey': faker.pystr(),
'nfseUrl': faker.url(),
'nfseUrl': (
'https://nfse.salvador.ba.gov.br/site/contribuinte/nota/notaprint.aspx'
f'?nf={faker.pyint()}'
f'&inscricao={faker.pyint()}'
f'&verificacao={faker.pystr()}'
),
'numero': str(faker.pyint()),
'numeroAndSerieDescription': f'{faker.pyint()} (Série: )',
'numeroSerie': str(faker.pyint()),
Expand Down
11 changes: 11 additions & 0 deletions tests/test_anonymous_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import responses

from agilize.client import AnonymousClient


@responses.activate
def test_download(faker):
url, file = faker.url(), b''
responses.add(responses.GET, url, body=file)

assert AnonymousClient.download(url) == file
15 changes: 14 additions & 1 deletion tests/test_model_company.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from agilize import Company, Competence, Prolabore, Tax
from agilize import Company, Competence, Invoice, Prolabore, Tax


def test_from_data(company_data):
Expand Down Expand Up @@ -47,3 +47,16 @@ def test_taxes(company, taxes_data):
competence=Competence.from_data(data['competence']),
id=data['__identity'],
)


def test_invoices(company, invoices_data):
company.client.invoices.return_value = invoices_data
data = invoices_data[0]
competence = Competence.from_data(data['competence'])

invoice = company.invoices.get(competence)

assert invoice == Invoice(
competence=competence,
url_nfse=data['nfses'][0]['nfseUrl'],
)
39 changes: 39 additions & 0 deletions tests/test_model_invoice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import pytest

from agilize import Competence, Invoice


@pytest.fixture
def invoice(faker):
return Invoice(
competence=Competence(faker.year(), faker.month()),
url_nfse=faker.url(),
)


def test_from_data(invoices_data):
data = invoices_data[0]

invoice = Invoice.from_data(data)

assert invoice.competence == Competence.from_data(data['competence'])
assert invoice.url_nfse == data['nfses'][0]['nfseUrl']


def test_url_nfse_image(invoice, faker):
invoice.url_nfse = (
'https://nfse.salvador.ba.gov.br/site/contribuinte/nota/notaprint.aspx'
f'?nf={faker.pyint()}'
f'&inscricao={faker.pyint()}'
f'&verificacao={faker.pystr()}'
)

assert invoice.url_nfse_image == invoice.url_nfse.replace('notaprint', 'notaprintimg')


def test_download_nfse(invoice, mocker):
anonymous_client_mock = mocker.patch('agilize.agilize.AnonymousClient')

invoice.download_nfse()

anonymous_client_mock.download.assert_called_once_with(invoice.url_nfse_image)
86 changes: 86 additions & 0 deletions tests/test_model_invoices.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from uuid import uuid4

import pytest

from agilize import Competence, Invoice, Invoices


@pytest.fixture
def invoices(client_mock):
return Invoices(company_id=str(uuid4()), client=client_mock)


def test_init():
client, company_id = object, str(uuid4())

invoices = Invoices(company_id=company_id, client=client)

assert invoices.client == client
assert invoices.company_id == company_id
assert invoices._invoices == {}


def test_iter(invoices):
invoice1, invoice2 = object, object

invoices._invoices = {'a': invoice1, 'b': invoice2}

assert list(invoices) == [invoice1, invoice2]


class TestFetch:
def test_call_client(self, invoices):
year = 2022

invoices.fetch(year)

invoices.client.invoices.assert_called_once_with(
invoices.company_id,
year,
)

def test_create_invoices(self, invoices, invoices_data):
invoices.client.invoices.return_value = invoices_data

invoices.fetch(2022)

assert list(invoices) == [Invoice.from_data(d) for d in invoices_data]

def test_ignore_invoices_without_nfse(self, invoices, invoices_data):
data = [{**invoices_data[0], 'nfses': []}]
invoices.client.invoices.return_value = data

invoices.fetch(2022)

assert list(invoices) == []


class TestGet:
def test_get(self, invoices, invoices_data):
data = invoices_data[0]
another_data = {**data, 'competence': '2022-06-01T00:00:00-0300'}

invoices.client.invoices.return_value = [data, another_data]
competence = Competence.from_data(data['competence'])

assert invoices.get(competence) == Invoice.from_data(data)

def test_call_client(self, invoices, invoices_data):
invoices.client.invoices.return_value = invoices_data
competence = Competence.from_data(invoices_data[0]['competence'])

invoices.get(competence)

invoices.client.invoices.assert_called_once_with(
invoices.company_id,
competence.year,
)

def test_cache(self, invoices, invoices_data):
invoices.client.invoices.return_value = invoices_data
competence = Competence.from_data(invoices_data[0]['competence'])

invoices.get(competence)
invoices.get(competence)

invoices.client.invoices.assert_called_once()