-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
286 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
0.0.4 | ||
0.0.5 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,7 @@ | ||
from procuret.session import Session, Lifecycle, Perspective | ||
from procuret.instalment_link import InstalmentLink, CommunicationOption | ||
from procuret.ancillary.communication_option import CommunicationOption | ||
from procuret.instalment_link import InstalmentLink, InstalmentLinkOpen | ||
from procuret.instalment_link import InstalmentLinkOrderBy | ||
from procuret.data.order import Order | ||
from procuret.ancillary.entity_headline import EntityHeadline | ||
from procuret import errors |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
""" | ||
Procuret Python | ||
Decodable Module | ||
author: [email protected] | ||
""" | ||
from json import loads | ||
from typing import Any, Optional, TypeVar, Type, List | ||
|
||
T = TypeVar('T', bound='Decodable') | ||
|
||
|
||
class Decodable: | ||
"""Abstract protocol defining an interface for decodable classes""" | ||
|
||
@classmethod | ||
def decode(self, data: Any) -> T: | ||
"""Return a JSON-serialisable form of the object""" | ||
raise NotImplementedError | ||
|
||
@classmethod | ||
def optionally_decode(cls: Type[T], data: Optional[Any]) -> Optional[T]: | ||
"""Optionally return a decoded object from serialised data""" | ||
if data is None: | ||
return None | ||
return cls.decode(data) | ||
|
||
@classmethod | ||
def deserialise(cls: Type[T], serial: str) -> T: | ||
"""Return a JSON string representation of the object""" | ||
return cls.decode(loads(serial)) | ||
|
||
@classmethod | ||
def optionally_deserialise( | ||
cls: Type[T], | ||
serial: Optional[str] | ||
) -> Optional[T]: | ||
if serial is None: | ||
return None | ||
return cls.deserialise(serial) | ||
|
||
@classmethod | ||
def decode_many(cls: Type[T], data: Any) -> List[T]: | ||
"""Return list of decoded instances of an object""" | ||
return [cls.decode(d) for d in data] | ||
|
||
@classmethod | ||
def optionally_decode_many( | ||
cls: Type[T], | ||
data: Optional[Any], | ||
default_to_empty_list: bool = False | ||
) -> Optional[List[T]]: | ||
"""Optionally return a list of decoded objects""" | ||
if data is None and default_to_empty_list is True: | ||
return list() | ||
if data is None: | ||
return None | ||
return cls.decode_many(data) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
""" | ||
Procuret Python | ||
Order Enumeration Module | ||
author: [email protected] | ||
""" | ||
from enum import Enum | ||
|
||
|
||
class Order(Enum): | ||
|
||
ASCENDING = 'ascending' | ||
DESCENDING = 'descending' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from procuret.instalment_link.instalment_link import InstalmentLink | ||
from procuret.instalment_link.open import InstalmentLinkOpen | ||
from procuret.instalment_link.instalment_link import ( | ||
OrderBy as InstalmentLinkOrderBy | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,51 +4,70 @@ | |
author: [email protected] | ||
""" | ||
from procuret.ancillary.communication_option import CommunicationOption | ||
from typing import TypeVar, Type, Union | ||
from typing import TypeVar, Type, Union, List | ||
from procuret.data.codable import Codable, CodingDefinition as CD | ||
from procuret.ancillary.entity_headline import EntityHeadline | ||
from procuret.errors.type_error import ProcuretTypeError | ||
from procuret.http.api_request import ApiRequest, HTTPMethod | ||
from procuret.errors.inconsistent import InconsistentState | ||
from procuret.session import Session | ||
from decimal import Decimal | ||
from enum import Enum | ||
from procuret.data.order import Order | ||
from procuret.http.query_parameters import QueryParameter, QueryParameters | ||
from typing import Optional | ||
from procuret.instalment_link.open import InstalmentLinkOpen | ||
|
||
T = TypeVar('T', bound='InstalmentLink') | ||
|
||
Self = TypeVar('Self', bound='InstalmentLink') | ||
|
||
|
||
class OrderBy(Enum): | ||
CREATED = 'created' | ||
|
||
|
||
class InstalmentLink(Codable): | ||
|
||
PATH = '/instalment-link' | ||
path = '/instalment-link' | ||
list_path = path + '/list' | ||
|
||
_LINK_TEMPLATE = 'https://procuret.com/business/signup?supplier_id={entity\ | ||
_id}&presented_invoice_id={invoice_id}&presented_invoice_amount={invoice_amoun\ | ||
t}' | ||
|
||
coding_map = { | ||
'public_id': CD(str), | ||
'supplier': CD(EntityHeadline), | ||
'invoice_amount': CD(Decimal), | ||
'invitee_email': CD(str), | ||
'invoice_identifier': CD(str), | ||
'opens': CD(InstalmentLinkOpen, array=True) | ||
} | ||
|
||
def __init__( | ||
self, | ||
public_id: str, | ||
supplier: EntityHeadline, | ||
invitee_email: str, | ||
invoice_amount: Decimal, | ||
invoice_identifier: str | ||
invoice_identifier: str, | ||
opens: List[InstalmentLinkOpen] | ||
) -> None: | ||
|
||
self._supplier = supplier | ||
self._public_id = public_id | ||
self._invitee_email = invitee_email | ||
self._invoice_amount = invoice_amount | ||
self._invoice_identifier = invoice_identifier | ||
self._opens = opens | ||
|
||
return | ||
|
||
public_id = property(lambda s: s._public_id) | ||
invitee_email = property(lambda s: s._invitee_email) | ||
invoice_amount = property(lambda s: s._invoice_amount) | ||
invoice_identifier = property(lambda s: s._invoice_identifier) | ||
opens = property(lambda s: s._opens) | ||
|
||
url = property(lambda s: s._LINK_TEMPLATE.format( | ||
entity_id=str(s._supplier.entity_id), | ||
|
@@ -58,14 +77,14 @@ def __init__( | |
|
||
@classmethod | ||
def create( | ||
cls: Type[T], | ||
cls: Type[Self], | ||
supplier: Union[int, EntityHeadline], | ||
invoice_amount: Decimal, | ||
invitee_email: str, | ||
invoice_identifier: str, | ||
communication: CommunicationOption, | ||
session: Session | ||
) -> T: | ||
) -> Self: | ||
|
||
def infer_supplier_id(x: Union[int, EntityHeadline]) -> int: | ||
if isinstance(x, int): | ||
|
@@ -113,7 +132,7 @@ def infer_communication(y: CommunicationOption) -> bool: | |
} | ||
|
||
result = ApiRequest.make( | ||
path=cls.PATH, | ||
path=cls.path, | ||
method=HTTPMethod.POST, | ||
data=data, | ||
session=session, | ||
|
@@ -124,3 +143,77 @@ def infer_communication(y: CommunicationOption) -> bool: | |
raise InconsistentState | ||
|
||
return cls.decode(result) | ||
|
||
@classmethod | ||
def retrieve( | ||
cls: Type[Self], | ||
public_id: str, | ||
session: Session | ||
) -> Optional[Self]: | ||
|
||
if not isinstance(public_id, str): | ||
raise TypeError('public_id must be a string') | ||
|
||
result = cls.retrieve_many( | ||
public_id=public_id, | ||
session=session | ||
) | ||
|
||
if len(result) < 1: | ||
return None | ||
|
||
return result[0] | ||
|
||
@classmethod | ||
def retrieve_many( | ||
cls: Type[Self], | ||
session: Session, | ||
public_id: Optional[str] = None, | ||
limit: int = 20, | ||
offset: int = 0, | ||
order: Order = Order.ASCENDING, | ||
order_by: OrderBy = OrderBy.CREATED, | ||
opened: Optional[bool] = None | ||
) -> List[Self]: | ||
|
||
if not isinstance(limit, int): | ||
raise TypeError('limit must be an integer') | ||
|
||
if not isinstance(offset, int): | ||
raise TypeError('offset must be an integer') | ||
|
||
if not isinstance(order, Order): | ||
raise TypeError('order must be of type Order') | ||
|
||
if not isinstance(order_by, OrderBy): | ||
raise TypeError('order must be of type InstalmentLink.OrderBy') | ||
|
||
if not isinstance(session, Session): | ||
raise TypeError('session must be of type Session') | ||
|
||
parameters = [ | ||
QueryParameter('limit', limit), | ||
QueryParameter('offset', offset), | ||
QueryParameter('order', order.value), | ||
QueryParameter('order_by', order_by.value), | ||
] | ||
|
||
if opened is not None: | ||
if not isinstance(opened, bool): | ||
raise TypeError('If supplied, opened must be a bool') | ||
parameters.append(QueryParameter('opened', opened)) | ||
|
||
if public_id is not None: | ||
if not isinstance(public_id, str): | ||
raise TypeError('If supplied, public_id must be str') | ||
parameters.append(QueryParameter('public_id', public_id)) | ||
|
||
result = ApiRequest.make( | ||
path=cls.list_path, | ||
method=HTTPMethod.GET, | ||
data=None, | ||
session=session, | ||
query_parameters=QueryParameters(parameters) | ||
) | ||
|
||
return cls.optionally_decode_many(result, default_to_empty_list=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
""" | ||
Procuret Python | ||
Instalment Link Open Module | ||
author: [email protected] | ||
""" | ||
from procuret.time.time import ProcuretTime | ||
from procuret.data.codable import Codable, CodingDefinition as CD | ||
from typing import TypeVar, Type | ||
from procuret.http.api_request import ApiRequest, HTTPMethod | ||
from procuret.session import Session | ||
from procuret.errors.type_error import ProcuretTypeError | ||
|
||
Self = TypeVar('Self', bound='InstalmentLinkOpen') | ||
|
||
|
||
class InstalmentLinkOpen(Codable): | ||
|
||
path = '/instalment-link/open' | ||
|
||
coding_map = { | ||
'sequence': CD(int), | ||
'created': CD(ProcuretTime) | ||
} | ||
|
||
def __init__( | ||
self, | ||
sequence: int, | ||
created: ProcuretTime | ||
) -> None: | ||
|
||
self._sequence = sequence | ||
self._created = created | ||
|
||
return | ||
|
||
sequence = property(lambda s: s._sequence) | ||
created = property(lambda s: s._created) | ||
|
||
@classmethod | ||
def create( | ||
cls: Type[Self], | ||
link_id: str, | ||
session: Session | ||
) -> None: | ||
|
||
if not isinstance(link_id, str): | ||
raise ProcuretTypeError('str', link_id, 'link_id') | ||
|
||
if not isinstance(session, Session): | ||
raise ProcuretTypeError('Session', session, 'session') | ||
|
||
result = ApiRequest.make( | ||
path=cls.path, | ||
method=HTTPMethod.POST, | ||
data={'link_id': link_id}, | ||
session=session | ||
) | ||
|
||
return None |
Oops, something went wrong.