diff --git a/.idea/akaunting-py.iml b/.idea/akaunting-py.iml
index 60b03b1..d6db46e 100644
--- a/.idea/akaunting-py.iml
+++ b/.idea/akaunting-py.iml
@@ -4,6 +4,7 @@
+
diff --git a/akauntingpy/api.py b/akauntingpy/api.py
index 5797247..3848a88 100644
--- a/akauntingpy/api.py
+++ b/akauntingpy/api.py
@@ -4,7 +4,7 @@ from requests.auth import HTTPBasicAuth
from akauntingpy import exceptions
from akauntingpy.helpers import *
-__version__ = "1.0.2"
+__version__ = "1.0.3"
class Client(object):
@@ -18,16 +18,21 @@ class Client(object):
username,
password,
company_id,
+ ssl_verify=True,
currency_code="NZD",
currency_rate="1.0"):
"""
Create a new instance.
Args:
- url (str): The URL to the Akaunting api.
- username (str): The username of the Akaunting credentials.
- password (str): The password of the Akaunting credentials.
+ url (str): The URL to the Akaunting api. ** required **
+ username (str): The username of the Akaunting credentials. ** required **
+ password (str): The password of the Akaunting credentials. ** required **
+ company_id (str): The company ID from Akaunting
+ currency_code (str): The currency code. default is NZD
+ currency_rate (str): The currency rate. default is "1.0"
"""
self.url = url
+ self.ssl_verify = ssl_verify
self.authentication = HTTPBasicAuth(username, password)
self.headers = {
'User-Agent': 'AkauntingPy v' + __version__,
@@ -44,7 +49,8 @@ class Client(object):
url=self.url + "/" + endpoint,
headers=self.headers,
auth=self.authentication,
- params=MergeDict(self.default_params, params)
+ params=MergeDict(self.default_params, params),
+ verify=self.ssl_verify
)
response_ = response.json()
@@ -73,17 +79,45 @@ class Client(object):
if params.get('search', False):
# Check if there is an account returned
- if data['meta']['pagination'].get('count') == 0:
- # No account found
- raise exceptions.AccountNotFound("Sorry, account not found matching search parameters: %s".format(
- params.get('search')
- ))
+ try:
+ if data['meta']['pagination'].get('count') == 0:
+ # No account found
+ raise exceptions.AccountNotFound("Sorry, account not found matching search parameters: %s".format(
+ params.get('search')
+ ))
+ except KeyError as e:
+ # New API 3.0
+ if data['meta']['total'] == 0:
+ raise exceptions.AccountNotFound("Sorry, account not found matching search parameters: %s".format(
+ params.get('search')
+ ))
+
+ return data['data']
+
+ def get_contact(self, **params):
+ data = self.call(endpoint="contacts", **params)
+ print(data)
+ if params.get('search', False):
+ try:
+ # Check if there is an account returned
+ if data['meta']['pagination'].get('count') == 0:
+ # No account found
+ raise exceptions.AccountNotFound("Sorry, contact not found matching search parameters: %s".format(
+ params.get('search')
+ ))
+ except KeyError as e:
+ # New API 3.0
+ if data['meta']['total'] == 0:
+ raise exceptions.AccountNotFound("Sorry, contact not found matching search parameters: %s".format(
+ params.get('search')
+ ))
return data['data']
def create_transaction(self,
transaction_type='income', # Payment method type
account_id=None, # Account ID to assign
+ number="NULL", # Transaction number
category_id=None, # Category ID to assign
contact_id=None, # Contact ID/Client to assign
description=None, # Description
@@ -106,6 +140,7 @@ class Client(object):
data = self.call(endpoint="transactions",
method="POST",
search="type:" + transaction_type,
+ number=number,
type=transaction_type,
account_id=account_id,
category_id=category_id,
@@ -121,18 +156,17 @@ class Client(object):
)
return data
-
def create_transfer(self,
- from_account_id=None, # Account ID to create transfer from
- to_account_id=None, # Account ID to create transfer to
- transferred_at=None, # Date of expense/transfer or income
- payment_method="Bank Transfer", # Payment method
- amount=None, # Amount received/paid
- **params # Any additional parameters
- ):
-
- data = self.call(endpoint="transfers",
- method="POST",
+ from_account_id=None, # Account ID to create transfer from
+ to_account_id=None, # Account ID to create transfer to
+ transferred_at=None, # Date of expense/transfer or income
+ payment_method="Bank Transfer", # Payment method
+ amount=None, # Amount received/paid
+ **params # Any additional parameters
+ ):
+
+ data = self.call(endpoint="transfers",
+ method="POST",
from_account_id=from_account_id,
to_account_id=to_account_id,
transferred_at=transferred_at,
@@ -140,4 +174,4 @@ class Client(object):
amount=EnsurePositiveInteger(amount),
**params
)
- return data
\ No newline at end of file
+ return data
diff --git a/akauntingpy/exceptions.py b/akauntingpy/exceptions.py
index 7f101ca..ec738b1 100644
--- a/akauntingpy/exceptions.py
+++ b/akauntingpy/exceptions.py
@@ -23,6 +23,14 @@ class AccountNotFound(Error):
"""
Account not found
+ Args:
+ Error (_type_): _description_
+ """
+
+class ContactNotFound(Error):
+ """
+ Account not found
+
Args:
Error (_type_): _description_
"""
\ No newline at end of file
diff --git a/tests/api_test.py b/tests/api_test.py
index 3b55e15..e827fe0 100644
--- a/tests/api_test.py
+++ b/tests/api_test.py
@@ -11,24 +11,24 @@ from requests.auth import HTTPBasicAuth
class TestAPI:
@pytest.fixture()
def setUp(self):
- c = akauntingpy.Client("https://akaunting.guise.net.nz/api",
- "aaron@guise.net.nz",
- "L3Tm31N0w",
+ c = akauntingpy.Client("https://someakaunting-url/api",
+ "some-emailaddress@somewhere.com",
+ "aPassWord",
1)
yield c
@pytest.fixture()
def setUpFailed(self):
- c = akauntingpy.Client("https://akaunting.guise.net.nz/api",
- "aaron@guise.net.nz",
- "L3Tm31N0w1",
+ c = akauntingpy.Client("https://someakaunting-url/api",
+ "some-emailaddress@somewhere.com",
+ "aWrongPassWord",
1)
yield c
def test_init(self, setUp):
c = setUp
assert isinstance(c, akauntingpy.Client)
- assert c.url == "https://akaunting.guise.net.nz/api"
+ assert c.url == "https://someakaunting-url/api"
assert isinstance(c.authentication, HTTPBasicAuth)
def test_ping_success(self, setUp, requests_mock):
@@ -55,19 +55,32 @@ class TestAPI:
json=RetrieveJSONFromFile("data/GetAccountsList.json"))
data = c.get_accounts(params={'page': 1, 'limit': 200})
- def test_get_account_search(self, setUp, requests_mock):
+ def test_get_account_search_v2(self, setUp, requests_mock):
c = setUp
- requests_mock.get(c.url + "/accounts?search=number%3A38-9011-0510023-03¶ms=page¶ms=limit&company_id=1",
- json=RetrieveJSONFromFile("data/GetAccountsSearch.json"))
- data = c.get_accounts(search="number:38-9011-0510023-03", params={'page': 1, 'limit': 200})
+ requests_mock.get(c.url + "/accounts?search=number%3A00-0000-0000000-00¶ms=page¶ms=limit&company_id=1",
+ json=RetrieveJSONFromFile("data/v2/GetAccountsSearch.json"))
+ data = c.get_accounts(search="number:00-0000-0000000-00", params={'page': 1, 'limit': 200})
- def test_get_account_search_not_found(self, setUp, requests_mock):
+ def test_get_account_search_v3(self, setUp, requests_mock):
+ c = setUp
+ requests_mock.get(c.url + "/accounts?search=number%3A00-0000-0000000-00¶ms=page¶ms=limit&company_id=1",
+ json=RetrieveJSONFromFile("data/v3/GetAccountsSearch.json"))
+ data = c.get_accounts(search="number:00-0000-0000000-00", params={'page': 1, 'limit': 200})
+
+ def test_get_account_search_not_found_v2(self, setUp, requests_mock):
c = setUp
requests_mock.get(c.url + "/accounts?search=number%3Aarandomvalue&company_id=1",
- json=RetrieveJSONFromFile("data/GetAccountsSearchNotFound.json"))
+ json=RetrieveJSONFromFile("data/v2/GetAccountsSearchNotFound.json"))
with pytest.raises(AccountNotFound):
data = c.get_accounts(search="number:arandomvalue")
+ def test_get_account_search_not_found_v3(self, setUp, requests_mock):
+ c = setUp
+ requests_mock.get(c.url + "/accounts?search=number%3Aarandomvalue&company_id=1",
+ json=RetrieveJSONFromFile("data/v3/GetAccountsSearchNotFound.json"))
+ with pytest.raises(AccountNotFound):
+ data = c.get_accounts(search="number:arandomvalue")
+
def test_create_transaction_income_success(self, setUp, requests_mock,
transaction_type='income', # Payment method type
account_id=2, # Account ID to assign