Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ee2de65
Begin work on UsageFileAutomation
JaviCerveraIngram Mar 20, 2019
d81c203
Merge branch 'tier-config-requests' into usage
JaviCerveraIngram Mar 20, 2019
9399e4c
.
JaviCerveraIngram Mar 20, 2019
88e1366
Merge branch 'tier-config-requests' into usage
JaviCerveraIngram Mar 20, 2019
f315043
Done UsageFileAutomation with tests
JaviCerveraIngram Mar 20, 2019
a26c968
Update test_usage_file.py
JaviCerveraIngram Mar 20, 2019
36b2e37
Merge branch 'tier-config-requests' into usage
JaviCerveraIngram Mar 21, 2019
96d57d7
Update tier_config_request_automation.py
JaviCerveraIngram Mar 21, 2019
279645e
Merge branch 'tier-config-requests' into usage
JaviCerveraIngram Mar 22, 2019
66296f7
Began work on UsageAutomation class
JaviCerveraIngram Mar 25, 2019
ba2adff
Minor refactors
JaviCerveraIngram Mar 25, 2019
bf93d68
Continued work on UsageAutomation
JaviCerveraIngram Mar 26, 2019
23ed94d
Merge branch 'tier-config-requests' into usage
JaviCerveraIngram Mar 27, 2019
e548cce
Removed warnings
JaviCerveraIngram Mar 27, 2019
7aff970
Removed utils.py (since it is not used anymore)
JaviCerveraIngram Mar 27, 2019
4110e63
Used NamedTemporaryFile for spreadsheet generation
JaviCerveraIngram Mar 28, 2019
5daa7b9
Replaced _list_url and _obj_url with url and urljoin
JaviCerveraIngram Mar 28, 2019
b9f27ab
Finished implementation of UsageAutomation?
JaviCerveraIngram Mar 28, 2019
3e3f328
Started UsageAutomation tests
JaviCerveraIngram Mar 28, 2019
d03683c
More tests
JaviCerveraIngram Mar 29, 2019
29293d3
Fixed test_process
JaviCerveraIngram Apr 1, 2019
02307da
More tests
JaviCerveraIngram Apr 1, 2019
06866c6
Updated example and README
JaviCerveraIngram Apr 2, 2019
f3bdb70
Fixed use of NamedTemporaryFile on Windows
JaviCerveraIngram Apr 2, 2019
40fb843
flake8 fixes
JaviCerveraIngram Apr 2, 2019
98f3a33
Trying something...
JaviCerveraIngram Apr 2, 2019
806cbcc
Checking something else...
JaviCerveraIngram Apr 2, 2019
d03ce8e
Fingers crossed....
JaviCerveraIngram Apr 2, 2019
4f5016b
Made changes requested by Vova
JaviCerveraIngram Apr 4, 2019
2215257
Quick fix to UsageAutomation._get_usage_template_download_location():…
JaviCerveraIngram Apr 4, 2019
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class ExampleRequestProcessor(FulfillmentAutomation):
raise Skip()


class ExampleTierConfigRequestProcessor(TierConfigAutomation):
class ExampleTierConfigProcessor(TierConfigAutomation):
def process_request(self, request):
pass

Expand All @@ -92,7 +92,7 @@ if __name__ == '__main__':
request_processor = ExampleRequestProcessor()
request_processor.process()

tier_config_request_processor = ExampleTierConfigRequestProcessor()
tier_config_request_processor.process()
tier_config_processor = ExampleTierConfigProcessor()
tier_config_processor.process()
```

56 changes: 55 additions & 1 deletion connect/models/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
This file is part of the Ingram Micro Cloud Blue Connect SDK.
Copyright (c) 2019 Ingram Micro. All Rights Reserved.
"""
from typing import List
from typing import List, Dict, Any, Optional

from connect.models import Param
from .server_error import ServerError
Expand Down Expand Up @@ -48,6 +48,48 @@ def __init__(self, *args, **kwargs):
self.code = 'skip'


class UsageFileAction(Message):
def __init__(self, message, code, data=None):
# type: (str, str, Optional[Dict[str, Any]]) -> None
super(UsageFileAction, self).__init__(message, code, data)


class AcceptUsageFile(UsageFileAction):
def __init__(self, acceptance_note):
# type: (str) -> None
super(AcceptUsageFile, self).__init__(
'Accept Response is required',
'accept',
{'acceptance_note': acceptance_note})


class CloseUsageFile(UsageFileAction):
def __init__(self, message=None):
# type: (str) -> None
super(CloseUsageFile, self).__init__(message or 'Usage File Closed', 'close')


class DeleteUsageFile(UsageFileAction):
def __init__(self, message=None):
# type: (str) -> None
super(DeleteUsageFile, self).__init__(message or 'Usage File Deleted', 'delete')


class RejectUsageFile(UsageFileAction):
def __init__(self, message=None):
# type: (str) -> None
super(RejectUsageFile, self).__init__(message or 'Accept Response is required', 'reject')


class SubmitUsageFile(UsageFileAction):
def __init__(self, rejection_note):
# type: (str) -> None
super(SubmitUsageFile, self).__init__(
'Usage File Submited',
'submit',
{'rejection_note': rejection_note})


class ServerErrorException(Exception):
message = 'Server error' # type: str

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

super(ServerErrorException, self).__init__(self.message, *args)


class FileCreationError(Message):
def __init__(self, message):
# type: (str) -> None
super(FileCreationError, self).__init__(message, 'filecreation')


class FileRetrievalError(Message):
def __init__(self, message):
# type: (str) -> None
super(FileRetrievalError, self).__init__(message, 'fileretrieval')
2 changes: 2 additions & 0 deletions connect/models/product.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@

class Product(BaseModel):
name = None # type: str
icon = None # type: str


class ProductSchema(BaseSchema):
name = fields.Str()
icon = fields.Str()

@post_load
def make_object(self, data):
Expand Down
142 changes: 142 additions & 0 deletions connect/models/usage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
# -*- coding: utf-8 -*-

"""
This file is part of the Ingram Micro Cloud Blue Connect SDK.
Copyright (c) 2019 Ingram Micro. All Rights Reserved.
"""
from marshmallow import fields, post_load

from connect.models.base import BaseModel, BaseSchema
from connect.models.company import Company, CompanySchema
from connect.models.marketplace import Contract, Marketplace, ContractSchema, MarketplaceSchema
from connect.models.product import Product, ProductSchema


class Records(BaseModel):
valid = None # type: int
invalid = None # type: int


class File(BaseModel):
name = None # type: str
description = None # type: str
note = None # type: str
status = None # type: str
created_by = None # type: str
created_at = None # type: str
product = None # type: Product
contract = None # type: Contract
marketplace = None # type: Marketplace
vendor = None # type: Company
provider = None # type: Company
upload_file_uri = None # type: str
processed_file_uri = None # type: str
acceptance_note = None # type: str
rejection_note = None # type: str
error_detail = None # type: str
records = None # type: Records
uploaded_by = None # type: str
uploaded_at = None # type: str
submitted_by = None # type: str
submitted_at = None # type: str
accepted_by = None # type: str
accepted_at = None # type: str
rejected_by = None # type: str
rejected_at = None # type: str
closed_by = None # type: str
closed_at = None # type: str


class Listing(BaseModel):
status = None # type: str
contract = None # type: Contract
product = None # type: Product
created = None # type: str

# Undocumented fields (they appear in PHP SDK)
vendor = None # type: Company
provider = None # type: Company


class FileUsageRecord(BaseModel):
record_id = None # type: str
item_search_criteria = None # type: str
item_search_value = None # type: str
quantity = None # type: int
start_time_utc = None # type: str
end_time_utc = None # type: str
asset_search_criteria = None # type: str
asset_search_value = None # type: str


class RecordsSchema(BaseSchema):
valid = fields.Int()
invalid = fields.Int()

@post_load
def make_object(self, data):
return Records(**data)


class FileSchema(BaseSchema):
name = fields.Str()
description = fields.Str()
note = fields.Str()
status = fields.Str()
created_by = fields.Str()
created_at = fields.Str()
product = fields.Nested(ProductSchema)
contract = fields.Nested(ContractSchema)
marketplace = fields.Nested(MarketplaceSchema)
vendor = fields.Nested(CompanySchema)
provider = fields.Nested(CompanySchema)
upload_file_uri = fields.Str()
processed_file_uri = fields.Str()
acceptance_note = fields.Str()
rejection_note = fields.Str()
error_detail = fields.Str()
records = fields.Nested(RecordsSchema)
uploaded_by = fields.Str()
uploaded_at = fields.Str()
submitted_by = fields.Str()
submitted_at = fields.Str()
accepted_by = fields.Str()
accepted_at = fields.Str()
rejected_by = fields.Str()
rejected_at = fields.Str()
closed_by = fields.Str()
closed_at = fields.Str()

@post_load
def make_object(self, data):
return File(**data)


class ListingSchema(BaseSchema):
status = fields.Str()
contract = fields.Nested(ContractSchema)
product = fields.Nested(ProductSchema)
created = fields.Str()

# Undocumented fields (they appear in PHP SDK)
vendor = fields.Nested(CompanySchema)
provider = fields.Nested(CompanySchema)

@post_load
def make_object(self, data):
return Listing(**data)


class FileUsageRecordSchema(BaseSchema):
record_id = fields.Str()
item_search_criteria = fields.Str()
item_search_value = fields.Str()
quantity = fields.Int()
start_time_utc = fields.Str()
end_time_utc = fields.Str()
asset_search_criteria = fields.Str()
asset_search_value = fields.Str()

@post_load
def make_object(self, data):
return FileUsageRecord(**data)
4 changes: 4 additions & 0 deletions connect/resource/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,15 @@
from .automation import AutomationResource
from .template import TemplateResource
from .tier_config_automation import TierConfigAutomation
from .usage_automation import UsageAutomation
from .usage_file_automation import UsageFileAutomation


__all__ = [
'FulfillmentAutomation',
'AutomationResource',
'TemplateResource',
'TierConfigAutomation',
'UsageAutomation',
'UsageFileAutomation',
]
21 changes: 10 additions & 11 deletions connect/resource/automation.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,19 @@

from connect.logger import function_log
from connect.models import Param, ActivationTileResponse
from connect.models.base import BaseModel
from .base import BaseResource
from .template import TemplateResource
from .utils import join_url


class AutomationResource(BaseResource):
limit = 1000

def build_filter(self):
# type: () -> Dict[str, Any]
def build_filter(self, status='pending'):
# type: (str) -> Dict[str, Any]
filters = super(AutomationResource, self).build_filter()
filters['status'] = 'pending'
if status:
filters['status'] = status
return filters

def process(self):
Expand All @@ -31,6 +32,7 @@ def process(self):
self.dispatch(request)

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

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

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

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

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

return self.api.put(
url=self._obj_url(pk),
path=pk,
data=json.dumps({'asset': {'params': list_dict}}),
)
Loading