Skip to content

Commit

Permalink
Merge pull request #43 from JaviCerveraIngram/CPS-22-conversation
Browse files Browse the repository at this point in the history
CPS-22-conversation
  • Loading branch information
vgrebenschikov committed May 28, 2019
2 parents 4df3da4 + ddd1c43 commit c94ef38
Show file tree
Hide file tree
Showing 8 changed files with 335 additions and 12 deletions.
3 changes: 3 additions & 0 deletions connect/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from .company import Company, User
from .connection import Connection
from .contact import Contact, ContactInfo, PhoneNumber
from .conversation import Conversation, ConversationMessage
from .event import EventInfo, Events
from .fulfillment import Fulfillment
from .hub import Hub, HubInstance, ExtIdHub, HubStats
Expand All @@ -34,6 +35,8 @@
'Contact',
'ContactInfo',
'Contract',
'Conversation',
'ConversationMessage',
'CustomerUiSettings',
'Document',
'DownloadLink',
Expand Down
70 changes: 70 additions & 0 deletions connect/models/conversation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-

# This file is part of the Ingram Micro Cloud Blue Connect SDK.
# Copyright (c) 2019 Ingram Micro. All Rights Reserved.

import datetime

from typing import List

from .base import BaseModel
from .company import User
from connect.models.schemas import ConversationMessageSchema, ConversationSchema


class ConversationMessage(BaseModel):
""" Message in a :py:class:`.Conversation`. """

_schema = ConversationMessageSchema()

conversation = None # type: str
""" (str) Primary ID of Conversation object. """

created = None # type: datetime.datetime
""" (datetime.datetime) Date of the Message creation. """

creator = None # type: User
""" (:py:class:`.User`) :py:class:`.User` that created the message. """

text = None # type: str
""" (str) Actual message. """


class Conversation(BaseModel):
""" Conversation. """

_schema = ConversationSchema()

instance_id = None # type: str
""" (str) The id of object based on which discussion is made, e.g. listing request.
It can be any object.
"""

created = None # type: datetime.datetime
""" (datetime.datetime) Date of the Conversation creation. """

topic = None # type: str
""" (str) Conversation topic. """

messages = None # type: List[ConversationMessage]
""" (List[:py:class:`.ConversationMessage`]) List of :py:class:`.ConversationMessage`
objects.
"""

creator = None # type: User
""" (:py:class:`.User`) Creator of the conversation. """

def add_message(self, message, config=None):
""" Adds a message to the conversation.
:param str message: Message to add.
:param Config config: Configuration, or ``None`` to use the environment config (default).
:return: The added message.
:rtype: ConversationMessage
:raises TypeError: Raised if the message cannot be deserialized.
"""

from connect.resources.base import ApiClient
response, _ = ApiClient(config, base_path='conversations/' + self.id + '/messages')\
.post(json={'text': message})
return ConversationMessage.deserialize(response)
21 changes: 21 additions & 0 deletions connect/models/fulfillment.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from .asset import Asset
from .base import BaseModel
from .conversation import Conversation
from .marketplace import Contract, Marketplace
from connect.models.schemas import FulfillmentSchema

Expand Down Expand Up @@ -113,3 +114,23 @@ def needs_migration(self, migration_key='migration_info'):
:rtype: bool
"""
return self.asset.get_param_by_id(migration_key) is not None

def get_conversation(self, config=None):
"""
:param Config config: Configuration, or ``None`` to use the environment config (default).
:return: The conversation for this request, or ``None`` if there is none.
:rtype: Conversation|None
"""
from connect.resources.base import ApiClient

client = ApiClient(config, base_path='conversations')
response, _ = client.get(params={'instance_id': self.id})
try:
conversations = Conversation.deserialize(response)
if conversations and conversations[0].id:
response, _ = client.get(conversations[0].id)
return Conversation.deserialize(response)
else:
return None
except ValueError:
return None
25 changes: 25 additions & 0 deletions connect/models/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -567,3 +567,28 @@ class UsageRecordSchema(BaseSchema):
def make_object(self, data):
from connect.models import UsageRecord
return UsageRecord(**data)


class ConversationMessageSchema(BaseSchema):
conversation = fields.Str()
created = fields.DateTime()
creator = fields.Nested(UserSchema)
text = fields.Str()

@post_load
def make_object(self, data):
from connect.models import ConversationMessage
return ConversationMessage(**data)


class ConversationSchema(BaseSchema):
instance_id = fields.Str()
created = fields.DateTime()
topic = fields.Str()
messages = fields.Nested(ConversationMessageSchema, many=True)
creator = fields.Nested(UserSchema)

@post_load
def make_object(self, data):
from connect.models import Conversation
return Conversation(**data)
58 changes: 46 additions & 12 deletions connect/resources/fulfillment_automation.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,35 +50,69 @@ def filters(self, status='pending', **kwargs):

def dispatch(self, request):
# type: (Fulfillment) -> str

conversation = request.get_conversation(self.config)

try:
if self.config.products \
and request.asset.product.id not in self.config.products:
return 'Invalid product'

logger.info('Start request process / ID request - {}'.format(request.id))
result = self.process_request(request)
process_result = self.process_request(request)

if not result:
if not process_result:
logger.info('Method `process_request` did not return result')
return ''

params = {}
if isinstance(result, ActivationTileResponse):
params = {'activation_tile': result.tile}
elif isinstance(result, ActivationTemplateResponse):
params = {'template_id': result.template_id}

return self.approve(request.id, params)
if isinstance(process_result, ActivationTileResponse):
message = 'Activated using custom activation tile.'
approved = self.approve(request.id, {'activation_tile': process_result.tile})
elif isinstance(process_result, ActivationTemplateResponse):
message = 'Activated using template {}.'.format(process_result.template_id)
approved = self.approve(request.id, {'template_id': process_result.template_id})
else:
# We should not get here
message = ''
approved = ''

if conversation:
try:
conversation.add_message(message)
except TypeError as ex:
logger.error('Error updating conversation for request {}: {}'
.format(request.id, ex))
return approved

except InquireRequest as inquire:
self.update_parameters(request.id, inquire.params)
return self.inquire(request.id)
inquired = self.inquire(request.id)
try:
conversation.add_message(str(inquire))
except TypeError as ex:
logger.error('Error updating conversation for request {}: {}'
.format(request.id, ex))
return inquired

except FailRequest as fail:
return self.fail(request.id, reason=str(fail))
# PyCharm incorrectly detects unreachable code here, so disable
# noinspection PyUnreachableCode
failed = self.fail(request.id, reason=str(fail))
try:
conversation.add_message(str(fail))
except TypeError as ex:
logger.error('Error updating conversation for request {}: {}'
.format(request.id, ex))
return failed

except SkipRequest as skip:
return skip.code
skipped = skip.code
try:
conversation.add_message(str(skip))
except TypeError as ex:
logger.error('Error updating conversation for request {}: {}'
.format(request.id, ex))
return skipped

@deprecated(deprecated_in='16.0', details='Use ``TierConfig.get`` instead.')
def get_tier_config(self, tier_id, product_id):
Expand Down
10 changes: 10 additions & 0 deletions tests/data/add_message_response.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"id": "ME-000-000-000",
"conversation": "CO-000-000-000",
"created": "2018-12-18T13:03:30+00:00",
"creator": {
"id": "UR-000-000-000",
"name": "Some User"
},
"text": "Hi, please see my listing request"
}
22 changes: 22 additions & 0 deletions tests/data/conversation.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"id": "CO-750-033-356",
"instance_id": "LST-038-662-242",
"created": "2018-12-18T12:49:34+00:00",
"topic": "Topic",
"messages": [
{
"id": "ME-506-258-087",
"conversation": "CO-750-033-356",
"created": "2018-12-18T13:03:30+00:00",
"creator": {
"id": "UR-922-977-649",
"name": "Some User"
},
"text": "Hi, check out"
}
],
"creator": {
"id": "UR-922-977-649",
"name": "Some User"
}
}

0 comments on commit c94ef38

Please sign in to comment.