Skip to content

Commit

Permalink
LITE-28568 task for price list uploading
Browse files Browse the repository at this point in the history
  • Loading branch information
zzzevaka committed Sep 25, 2023
1 parent 36f9c58 commit ccc9d0e
Show file tree
Hide file tree
Showing 28 changed files with 1,117 additions and 370 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM cloudblueconnect/connect-extension-runner:29.0
FROM cloudblueconnect/connect-extension-runner:28.10

COPY pyproject.toml /install_temp/.
COPY poetry.* /install_temp/.
Expand Down
6 changes: 3 additions & 3 deletions connect_ext_ppr/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from requests_oauthlib import OAuth1

from connect_ext_ppr.client.auth import APSTokenAuth
from connect_ext_ppr.client.exception import ClientError
from connect_ext_ppr.client.exception import CBCClientError
from connect_ext_ppr.client.ns import (
Collection,
Resource,
Expand Down Expand Up @@ -88,13 +88,13 @@ def execute_request(

except Exception as e:
if response is not None:
raise ClientError(
raise CBCClientError(
message=f'{type(e).__name__} : {str(e)}',
response=response,
cause=e,
)
else:
raise ClientError(
raise CBCClientError(
message=f'{type(e).__name__} : {str(e)}',
cause=e,
)
Expand Down
2 changes: 1 addition & 1 deletion connect_ext_ppr/client/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from requests import Response


class ClientError(RuntimeError):
class CBCClientError(RuntimeError):
def __init__(
self,
message: str,
Expand Down
11 changes: 11 additions & 0 deletions connect_ext_ppr/client/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from connect_ext_ppr.services.cbc_extension import get_hub_credentials
from connect_ext_ppr.services.cbc_hub import CBCService
from connect_ext_ppr.errors import ExtensionHttpError


def get_cbc_service(hub_id, cbc_db, verify_certificate=False):
hub_credentials = get_hub_credentials(hub_id, cbc_db)
if not hub_credentials:
raise ExtensionHttpError.EXT_012(format_kwargs={'hub_id': hub_id})

return CBCService(hub_credentials, verify_certificate)
2 changes: 1 addition & 1 deletion connect_ext_ppr/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ def get_cbc_extension_db(engine: Engine = Depends(get_cbc_extension_db_engine)):
)
db: Session = SessionMaker(bind=engine)
try:
yield db
return db
finally:
db.close()

Expand Down
49 changes: 34 additions & 15 deletions connect_ext_ppr/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
from connect.client import ClientError


class ValidationError(ClientError):
pass


class Error:
def __init__(self, message, error_code):
def __init__(self, message, error_code, error_cls=None):
self.message = message
self.error_code = error_code
self.error_cls = error_cls or ClientError

def __call__(self, **kwds: Dict[str, Any]) -> ClientError:
def __call__(self, **kwds: Dict[str, Any]) -> Exception:
format_kwargs = kwds.get('format_kwargs', {})
status_code = kwds.get('status_code') or 400
message = self.message.format(**format_kwargs)
Expand All @@ -19,7 +24,7 @@ def __call__(self, **kwds: Dict[str, Any]) -> ClientError:
if not isinstance(errors, list):
errors = [errors]

return ClientError(
return self.error_cls(
message=message,
status_code=status_code,
error_code=self.error_code,
Expand Down Expand Up @@ -78,19 +83,9 @@ class ExtensionHttpError(ExtensionErrorBase):
5: "Configuration `{obj_id}` cannot be deleted, because related deployment is not synced.",
6: "Can not autogenerate a new PPR for deployment {deployment_id}:"
" There must be one `active` configuration file.",
7: "Pricing Batch with ID '{batch_id}' s¡is not found.",
8: "More than file found of Pricing Batch '{batch_id}'.",
9: "Deployment Hub {hub_id} does not serve Marketplace "
"{marketplace_id} associated with the batch {batch_id}",
10: "Not able to find out Reseller ID for Marketplace {marketplace_id} and Hub {hub_id}.",
11: "Deployment {deployment_id} Product ID {d_product_id} and Batch "
"{batch_id} Product ID {b_product_id} does not match.",
# Placeholder 7 - 11
12: "Hub Credentials not found for Hub ID {hub_id}.",
13: "Effective Date field not found in Batch {batch_id}.",
14: "Effective date {date} is either not found or invalid"
" for first row in Batch {batch_id}.",
15: 'No Marketplace is linked with Deployment Hub {hub_id}',
16: "Pricing Batch '{batch_id}' does not have any file.",
# Placeholder 13 - 16
17: "Cannot create a new request, an open one already exists.",
18: "Deployment request `{dep_request_id}` can not be retried, newer requests were"
" created for related deployment `{deployment_id}`: {new_requests}.",
Expand All @@ -109,3 +104,27 @@ class ExtensionValidationError(ExtensionErrorBase):
" '{target}', allowed {field_name} sources for '{target}' are '{allowed}'.",
6: "Pricing batches invalid: {ids}.",
}


class PriceUpdateError(ExtensionErrorBase):
PREFIX = 'PLT'
ERRORS = {
1: "Pricing Batch with ID '{batch_id}' s¡is not found.",
2: "More than file found of Pricing Batch '{batch_id}'.",
3: "Deployment Hub {hub_id} does not serve Marketplace "
"{marketplace_id} associated with the batch {batch_id}.",
4: "Not able to find out Reseller ID for Marketplace {marketplace_id} "
"and Hub {hub_id}.",
5: "Pricing Batch output '{batch_id}' does not contain "
"either Cost or Price column.",
6: "Effective date '{date}' is either not found or invalid "
"for first row in Batch {batch_id}.",
7: "Pricing Batch '{batch_id}' does not have any file.",
8: 'No Marketplace is linked with Deployment Hub {hub_id}.',
9: "Deployment {deployment_id} Product ID {d_product_id} and Batch "
"{batch_id} Product ID {b_product_id} does not match.",
10: "Pricing Batch output '{batch_id}' does not contain "
"mandatory column: {col_name}.",
11: "Pricing Batch output '{batch_id}' contains invalid value at "
"column '{column}' of row '{row}'.",
}
2 changes: 2 additions & 0 deletions connect_ext_ppr/models/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class TaskTypesChoices(str, enum.Enum):
product_setup = 'product_setup'
apply_and_delegate = 'apply_ppr_and_delegate_to_marketplace'
delegate_to_l2 = 'delegate_to_l2'
validate_pricelists = 'validate_pricelists'
apply_pricelist = 'apply_pricelist'


class MimeTypeChoices(str, enum.Enum):
Expand Down
4 changes: 3 additions & 1 deletion connect_ext_ppr/models/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

from connect_ext_ppr.db import Model
from connect_ext_ppr.models.enums import TasksStatusChoices, TaskTypesChoices
from connect_ext_ppr.models.deployment import DeploymentRequest
from connect_ext_ppr.models.deployment import DeploymentRequest, MarketplaceConfiguration
from connect_ext_ppr.models.models_utils import transition


Expand All @@ -23,6 +23,7 @@ class Task(Model):
default=STATUSES.pending,
)
deployment_request_id = db.Column(db.ForeignKey(DeploymentRequest.id))
marketplace_id = db.Column(db.ForeignKey(MarketplaceConfiguration.id), nullable=True)
title = db.Column(db.String(100))
error_message = db.Column(db.String(4000))
type = db.Column(db.Enum(TaskTypesChoices, validate_strings=True))
Expand All @@ -35,6 +36,7 @@ class Task(Model):
aborted_by = db.Column(db.String(20), nullable=True)

deployment_request = relationship(DeploymentRequest, foreign_keys='Task.deployment_request_id')
marketplace = relationship(MarketplaceConfiguration, foreign_keys='Task.marketplace_id')

@transition('status', target=STATUSES.aborted, sources=[STATUSES.pending])
def abort(self, by):
Expand Down
17 changes: 0 additions & 17 deletions connect_ext_ppr/schemas.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
from datetime import datetime

from pydantic import BaseModel, Field, root_validator
from fastapi import status

from typing import Dict, List, Optional, Union

from connect_ext_ppr.errors import ExtensionValidationError
from connect_ext_ppr.models.enums import (
ConfigurationStateChoices,
DeploymentRequestStatusChoices,
Expand Down Expand Up @@ -69,17 +67,6 @@ class ReferenceSchema(NonNullSchema):
icon: Optional[str]


class ChoicesSchema(BaseModel):
choices: Optional[List[PrimaryKeyReference]] = []
all: bool

@root_validator
def check_choices_exists_if_all_is_false(cls, values):
if not values.get('all') and not values.get('choices'):
raise ExtensionValidationError.VAL_003(status_code=status.HTTP_400_BAD_REQUEST)
return values


class ProductSchema(NonNullSchema):
id: str
name: str
Expand Down Expand Up @@ -200,10 +187,6 @@ class BatchSchema(NonNullSchema):
stream_updated: Optional[bool]


class BatchProcessResponseSchema(NonNullSchema):
task_info: str


class MarketplaceSchema(NonNullSchema):
id: str
name: str
Expand Down
30 changes: 30 additions & 0 deletions connect_ext_ppr/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ def add_new_deployment_request(db, dr_data, deployment, account_id, logger):
db.add(mc)

tasks = []

tasks.append(Task(
deployment_request_id=deployment_request.id,
title='Product check up and update',
Expand All @@ -348,6 +349,35 @@ def add_new_deployment_request(db, dr_data, deployment, account_id, logger):
type=Task.TYPES.apply_and_delegate,
created_by=account_id,
))

dep_marketplaces = {m.marketplace: m for m in deployment.marketplaces}
req_marketplaces = {m.marketplace: m for m in deployment_request.marketplaces}

update_prices = False
for mp_name, marketplace in req_marketplaces.items():
if (
(not marketplace.pricelist_id)
or (marketplace.pricelist_id == dep_marketplaces[mp_name].pricelist_id)
):
continue

tasks.append(Task(
deployment_request=deployment_request,
title=f'Apply price list to marketplace {marketplace.marketplace}',
marketplace=marketplace,
type=Task.TYPES.apply_pricelist,
created_by=account_id,
))
update_prices = True

if update_prices:
tasks.insert(0, Task(
deployment_request_id=deployment_request.id,
title='Validate price lists',
type=Task.TYPES.validate_pricelists,
created_by=account_id,
))

if deployment_request.delegate_l2:
tasks.append(Task(
deployment_request_id=deployment_request.id,
Expand Down
6 changes: 4 additions & 2 deletions connect_ext_ppr/services/cbc_hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from connect_ext_ppr.client import CBCClient
from connect_ext_ppr.client.auth import APSTokenAuth
from connect_ext_ppr.client.exception import ClientError
from connect_ext_ppr.client.exception import CBCClientError
from connect_ext_ppr.models.cbc_extenstion import HubCredential


Expand Down Expand Up @@ -55,7 +55,7 @@ def __validate_client(self):
method='GET',
path=f'{self.hub_credential.controller_url}/aps',
)
except ClientError:
except CBCClientError:
raise ValueError('hub_credential are not valid!')

@cached_property
Expand Down Expand Up @@ -192,6 +192,8 @@ def parse_price_file(
'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
}

file.seek(0)

fcs = self.get_flat_catalog_service(account_id)
return fcs.flat_catalog.price_import_wizard.action(
name=f'upload?vendorId={vendor_id}',
Expand Down
Loading

0 comments on commit ccc9d0e

Please sign in to comment.