Skip to content

Commit 18c21c1

Browse files
Merge pull request #24 from JaviCerveraIngram/usage
Usage Automation support
2 parents 7db1965 + 2215257 commit 18c21c1

23 files changed

+1108
-110
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ class ExampleRequestProcessor(FulfillmentAutomation):
8383
raise Skip()
8484

8585

86-
class ExampleTierConfigRequestProcessor(TierConfigAutomation):
86+
class ExampleTierConfigProcessor(TierConfigAutomation):
8787
def process_request(self, request):
8888
pass
8989

@@ -92,7 +92,7 @@ if __name__ == '__main__':
9292
request_processor = ExampleRequestProcessor()
9393
request_processor.process()
9494

95-
tier_config_request_processor = ExampleTierConfigRequestProcessor()
96-
tier_config_request_processor.process()
95+
tier_config_processor = ExampleTierConfigProcessor()
96+
tier_config_processor.process()
9797
```
9898

connect/models/exception.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
This file is part of the Ingram Micro Cloud Blue Connect SDK.
55
Copyright (c) 2019 Ingram Micro. All Rights Reserved.
66
"""
7-
from typing import List
7+
from typing import List, Dict, Any, Optional
88

99
from connect.models import Param
1010
from .server_error import ServerError
@@ -48,6 +48,48 @@ def __init__(self, *args, **kwargs):
4848
self.code = 'skip'
4949

5050

51+
class UsageFileAction(Message):
52+
def __init__(self, message, code, data=None):
53+
# type: (str, str, Optional[Dict[str, Any]]) -> None
54+
super(UsageFileAction, self).__init__(message, code, data)
55+
56+
57+
class AcceptUsageFile(UsageFileAction):
58+
def __init__(self, acceptance_note):
59+
# type: (str) -> None
60+
super(AcceptUsageFile, self).__init__(
61+
'Accept Response is required',
62+
'accept',
63+
{'acceptance_note': acceptance_note})
64+
65+
66+
class CloseUsageFile(UsageFileAction):
67+
def __init__(self, message=None):
68+
# type: (str) -> None
69+
super(CloseUsageFile, self).__init__(message or 'Usage File Closed', 'close')
70+
71+
72+
class DeleteUsageFile(UsageFileAction):
73+
def __init__(self, message=None):
74+
# type: (str) -> None
75+
super(DeleteUsageFile, self).__init__(message or 'Usage File Deleted', 'delete')
76+
77+
78+
class RejectUsageFile(UsageFileAction):
79+
def __init__(self, message=None):
80+
# type: (str) -> None
81+
super(RejectUsageFile, self).__init__(message or 'Accept Response is required', 'reject')
82+
83+
84+
class SubmitUsageFile(UsageFileAction):
85+
def __init__(self, rejection_note):
86+
# type: (str) -> None
87+
super(SubmitUsageFile, self).__init__(
88+
'Usage File Submited',
89+
'submit',
90+
{'rejection_note': rejection_note})
91+
92+
5193
class ServerErrorException(Exception):
5294
message = 'Server error' # type: str
5395

@@ -64,3 +106,15 @@ def __init__(self, error=None, *args, **kwargs):
64106
self.message = self.__class__.message
65107

66108
super(ServerErrorException, self).__init__(self.message, *args)
109+
110+
111+
class FileCreationError(Message):
112+
def __init__(self, message):
113+
# type: (str) -> None
114+
super(FileCreationError, self).__init__(message, 'filecreation')
115+
116+
117+
class FileRetrievalError(Message):
118+
def __init__(self, message):
119+
# type: (str) -> None
120+
super(FileRetrievalError, self).__init__(message, 'fileretrieval')

connect/models/product.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212

1313
class Product(BaseModel):
1414
name = None # type: str
15+
icon = None # type: str
1516

1617

1718
class ProductSchema(BaseSchema):
1819
name = fields.Str()
20+
icon = fields.Str()
1921

2022
@post_load
2123
def make_object(self, data):

connect/models/usage.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# -*- coding: utf-8 -*-
2+
3+
"""
4+
This file is part of the Ingram Micro Cloud Blue Connect SDK.
5+
Copyright (c) 2019 Ingram Micro. All Rights Reserved.
6+
"""
7+
from marshmallow import fields, post_load
8+
9+
from connect.models.base import BaseModel, BaseSchema
10+
from connect.models.company import Company, CompanySchema
11+
from connect.models.marketplace import Contract, Marketplace, ContractSchema, MarketplaceSchema
12+
from connect.models.product import Product, ProductSchema
13+
14+
15+
class Records(BaseModel):
16+
valid = None # type: int
17+
invalid = None # type: int
18+
19+
20+
class File(BaseModel):
21+
name = None # type: str
22+
description = None # type: str
23+
note = None # type: str
24+
status = None # type: str
25+
created_by = None # type: str
26+
created_at = None # type: str
27+
product = None # type: Product
28+
contract = None # type: Contract
29+
marketplace = None # type: Marketplace
30+
vendor = None # type: Company
31+
provider = None # type: Company
32+
upload_file_uri = None # type: str
33+
processed_file_uri = None # type: str
34+
acceptance_note = None # type: str
35+
rejection_note = None # type: str
36+
error_detail = None # type: str
37+
records = None # type: Records
38+
uploaded_by = None # type: str
39+
uploaded_at = None # type: str
40+
submitted_by = None # type: str
41+
submitted_at = None # type: str
42+
accepted_by = None # type: str
43+
accepted_at = None # type: str
44+
rejected_by = None # type: str
45+
rejected_at = None # type: str
46+
closed_by = None # type: str
47+
closed_at = None # type: str
48+
49+
50+
class Listing(BaseModel):
51+
status = None # type: str
52+
contract = None # type: Contract
53+
product = None # type: Product
54+
created = None # type: str
55+
56+
# Undocumented fields (they appear in PHP SDK)
57+
vendor = None # type: Company
58+
provider = None # type: Company
59+
60+
61+
class FileUsageRecord(BaseModel):
62+
record_id = None # type: str
63+
item_search_criteria = None # type: str
64+
item_search_value = None # type: str
65+
quantity = None # type: int
66+
start_time_utc = None # type: str
67+
end_time_utc = None # type: str
68+
asset_search_criteria = None # type: str
69+
asset_search_value = None # type: str
70+
71+
72+
class RecordsSchema(BaseSchema):
73+
valid = fields.Int()
74+
invalid = fields.Int()
75+
76+
@post_load
77+
def make_object(self, data):
78+
return Records(**data)
79+
80+
81+
class FileSchema(BaseSchema):
82+
name = fields.Str()
83+
description = fields.Str()
84+
note = fields.Str()
85+
status = fields.Str()
86+
created_by = fields.Str()
87+
created_at = fields.Str()
88+
product = fields.Nested(ProductSchema)
89+
contract = fields.Nested(ContractSchema)
90+
marketplace = fields.Nested(MarketplaceSchema)
91+
vendor = fields.Nested(CompanySchema)
92+
provider = fields.Nested(CompanySchema)
93+
upload_file_uri = fields.Str()
94+
processed_file_uri = fields.Str()
95+
acceptance_note = fields.Str()
96+
rejection_note = fields.Str()
97+
error_detail = fields.Str()
98+
records = fields.Nested(RecordsSchema)
99+
uploaded_by = fields.Str()
100+
uploaded_at = fields.Str()
101+
submitted_by = fields.Str()
102+
submitted_at = fields.Str()
103+
accepted_by = fields.Str()
104+
accepted_at = fields.Str()
105+
rejected_by = fields.Str()
106+
rejected_at = fields.Str()
107+
closed_by = fields.Str()
108+
closed_at = fields.Str()
109+
110+
@post_load
111+
def make_object(self, data):
112+
return File(**data)
113+
114+
115+
class ListingSchema(BaseSchema):
116+
status = fields.Str()
117+
contract = fields.Nested(ContractSchema)
118+
product = fields.Nested(ProductSchema)
119+
created = fields.Str()
120+
121+
# Undocumented fields (they appear in PHP SDK)
122+
vendor = fields.Nested(CompanySchema)
123+
provider = fields.Nested(CompanySchema)
124+
125+
@post_load
126+
def make_object(self, data):
127+
return Listing(**data)
128+
129+
130+
class FileUsageRecordSchema(BaseSchema):
131+
record_id = fields.Str()
132+
item_search_criteria = fields.Str()
133+
item_search_value = fields.Str()
134+
quantity = fields.Int()
135+
start_time_utc = fields.Str()
136+
end_time_utc = fields.Str()
137+
asset_search_criteria = fields.Str()
138+
asset_search_value = fields.Str()
139+
140+
@post_load
141+
def make_object(self, data):
142+
return FileUsageRecord(**data)

connect/resource/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,15 @@
99
from .automation import AutomationResource
1010
from .template import TemplateResource
1111
from .tier_config_automation import TierConfigAutomation
12+
from .usage_automation import UsageAutomation
13+
from .usage_file_automation import UsageFileAutomation
1214

1315

1416
__all__ = [
1517
'FulfillmentAutomation',
1618
'AutomationResource',
1719
'TemplateResource',
1820
'TierConfigAutomation',
21+
'UsageAutomation',
22+
'UsageFileAutomation',
1923
]

connect/resource/automation.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,19 @@
1111

1212
from connect.logger import function_log
1313
from connect.models import Param, ActivationTileResponse
14+
from connect.models.base import BaseModel
1415
from .base import BaseResource
1516
from .template import TemplateResource
16-
from .utils import join_url
1717

1818

1919
class AutomationResource(BaseResource):
2020
limit = 1000
2121

22-
def build_filter(self):
23-
# type: () -> Dict[str, Any]
22+
def build_filter(self, status='pending'):
23+
# type: (str) -> Dict[str, Any]
2424
filters = super(AutomationResource, self).build_filter()
25-
filters['status'] = 'pending'
25+
if status:
26+
filters['status'] = status
2627
return filters
2728

2829
def process(self):
@@ -31,6 +32,7 @@ def process(self):
3132
self.dispatch(request)
3233

3334
def dispatch(self, request):
35+
# type: (BaseModel) -> str
3436
raise NotImplementedError('Please implement `{}.dispatch` method'
3537
.format(self.__class__.__name__))
3638

@@ -41,20 +43,17 @@ def process_request(self, request):
4143
@function_log
4244
def approve(self, pk, data):
4345
# type: (str, dict) -> str
44-
url = join_url(self._obj_url(pk), 'approve/')
45-
return self.api.post(url=url, data=json.dumps(data if data else {}))
46+
return self.api.post(path=pk + '/approve/', data=data if data else {})
4647

4748
@function_log
4849
def inquire(self, pk):
4950
# type: (str) -> str
50-
url = join_url(self._obj_url(pk), 'inquire/')
51-
return self.api.post(url=url, data=json.dumps({}))
51+
return self.api.post(path=pk + '/inquire/', data={})
5252

5353
@function_log
5454
def fail(self, pk, reason):
5555
# type: (str, str) -> str
56-
url = join_url(self._obj_url(pk), 'fail/')
57-
return self.api.post(url=url, data=json.dumps({'reason': reason}))
56+
return self.api.post(path=pk + '/fail/', data={'reason': reason})
5857

5958
@function_log
6059
def render_template(self, pk, template_id):
@@ -69,6 +68,6 @@ def update_parameters(self, pk, params):
6968
list_dict.append(_.__dict__ if isinstance(_, Param) else _)
7069

7170
return self.api.put(
72-
url=self._obj_url(pk),
71+
path=pk,
7372
data=json.dumps({'asset': {'params': list_dict}}),
7473
)

0 commit comments

Comments
 (0)