Skip to content

Commit

Permalink
Merge pull request #117 from cloudblue/feature/LITE-28561-T2-Syns-PPR…
Browse files Browse the repository at this point in the history
…-to-Marketplaces

LITE-28561 Implement sync PPR to marketplaces
  • Loading branch information
akodelia authored Sep 27, 2023
2 parents de6534c + 9ab65b3 commit 2484416
Show file tree
Hide file tree
Showing 8 changed files with 746 additions and 18 deletions.
1 change: 1 addition & 0 deletions connect_ext_ppr/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -528,6 +528,7 @@
}
PPR_FILE_NAME = "PPR_{product_id}_v{version}_{timestamp}.xlsx"
PPR_FILE_NAME_DELEGATION_L2 = "{dr_id}-L2Delegation-{ppr_id}-{timestamp}.xlsx"
PPR_FILE_NAME_UPDATE_MARKETPLACES = "{dr_id}-MkplUpdate-{ppr_id}-{timestamp}.xlsx"
DESCRIPTION_TEMPLATE = """
**Description**
{description}
Expand Down
125 changes: 116 additions & 9 deletions connect_ext_ppr/tasks_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
from sqlalchemy.orm import joinedload, selectinload

from connect_ext_ppr.client.exception import CBCClientError
from connect_ext_ppr.constants import PPR_FILE_NAME_DELEGATION_L2
from connect_ext_ppr.constants import PPR_FILE_NAME_DELEGATION_L2, PPR_FILE_NAME_UPDATE_MARKETPLACES
from connect_ext_ppr.db import get_cbc_extension_db, get_cbc_extension_db_engine, get_db_ctx_manager
from connect_ext_ppr.models.configuration import Configuration
from connect_ext_ppr.models.enums import CBCTaskLogStatus
from connect_ext_ppr.models.enums import (
DeploymentRequestStatusChoices,
Expand All @@ -27,8 +28,11 @@
create_dr_file_to_media,
execute_with_retry,
get_base_workbook,
get_configuration_from_media,
get_file_size,
get_mps_to_update_for_apply_ppr_and_delegate_to_marketplaces,
get_ppr_from_media,
process_ppr_file_for_apply_ppr_and_delegate_to_marketplaces,
process_ppr_file_for_delelegate_l2,
)

Expand Down Expand Up @@ -106,14 +110,27 @@ def prepare_ppr_file_for_task(
deployment_request,
deployment,
process_func,
**process_args,
):
"""Process PPR file and save a processed copy to Media before tasks: delegate to l2,
apply to marketplaces.
:param connect_client: Connect client
:param file_data: Body of PPR file
:param file_name_template: Template to create file name in Media
:param deployment_request: DeploymentRequest model
:param deployment: Deployment model
:param process_func: function, that will be applied to the file
:rtype bool
:raises TaskException
"""
file, writer, wb = get_base_workbook(file_data)

try:
ws_list = []
for sheet_name in wb.sheet_names:
ws = wb.parse(sheet_name)
process_func(sheet_name, ws)
process_func(sheet_name, ws, **process_args)
ws.name = sheet_name
ws_list.append(ws)

Expand Down Expand Up @@ -142,6 +159,8 @@ def prepare_ppr_file_for_task(

except (FileNotFoundError, ValueError, KeyError) as e:
raise TaskException(f'Error while processing PPR file: {e}')
except ClientError as e:
raise TaskException(f'Error while connecting to Connect: {e.message}')


def check_and_update_product(deployment_request, cbc_service, **kwargs):
Expand All @@ -167,7 +186,84 @@ def check_and_update_product(deployment_request, cbc_service, **kwargs):
return True


def apply_ppr_and_delegate_to_marketplaces(deployment_request, **kwargs):
def apply_ppr_and_delegate_to_marketplaces(
deployment_request,
cbc_service,
connect_client,
db,
**kwargs,
):
"""Task sends PPR to the Commerce and updates marketplaces in DB
:param deployment_request: DeploymentRequest model
:param cbc_service: CBC service
:param connect_client: Connect client
:param db: dbsession
:rtype bool
:raises TaskException
"""
dr_marketplaces = db.query(MarketplaceConfiguration).filter_by(
active=True,
deployment_request_id=deployment_request.id,
).all()
dep_marketplaces = db.query(MarketplaceConfiguration).filter_by(
active=True,
deployment_id=deployment_request.deployment_id,
).filter(
MarketplaceConfiguration.marketplace.in_([m.marketplace for m in dr_marketplaces]),
).all()
marketplaces_to_update_dict = {m.marketplace: None for m in dr_marketplaces}

if not deployment_request.manually:
ppr_file_id = deployment_request.ppr.file
deployment = deployment_request.deployment
configuration = (
db.query(Configuration)
.filter_by(
deployment=deployment.id,
state=Configuration.STATE.active,
)
.one_or_none()
)
try:
file_data = get_ppr_from_media(
connect_client,
deployment.account_id,
deployment.id,
ppr_file_id,
)
config_json = get_configuration_from_media(
connect_client, deployment.account_id, deployment.id, configuration.file,
)
except ClientError as e:
raise TaskException(f'Error while connecting to Connect: {e.message}')

marketplaces_to_update_dict = get_mps_to_update_for_apply_ppr_and_delegate_to_marketplaces(
ppr_file_data=file_data,
config_json=config_json,
dr_marketplaces=dr_marketplaces,
)

file = prepare_ppr_file_for_task(
connect_client=connect_client,
file_data=file_data,
file_name_template=PPR_FILE_NAME_UPDATE_MARKETPLACES,
deployment_request=deployment_request,
deployment=deployment,
process_func=process_ppr_file_for_apply_ppr_and_delegate_to_marketplaces,
columns_to_keep=marketplaces_to_update_dict.values(),
)

tracking_id = _send_ppr(cbc_service, file)
file.close()
_check_cbc_task_status(cbc_service, tracking_id)

for marketplace in dr_marketplaces + dep_marketplaces:
if marketplace.marketplace in marketplaces_to_update_dict:
marketplace.ppr_id = deployment_request.ppr_id
db.add(marketplace)

db.commit()
return True


Expand Down Expand Up @@ -248,17 +344,28 @@ def validate_pricelists_task(


def delegate_to_l2(deployment_request, cbc_service, connect_client, **kwargs):
"""Task delegates PPR to L2 in Commerce
:param deployment_request: DeploymentRequest model
:param cbc_service: CBC service
:param connect_client: Connect client
:rtype bool
:raises TaskException
"""
if deployment_request.manually:
return True

ppr_file_id = deployment_request.ppr.file
deployment = deployment_request.deployment
file_data = get_ppr_from_media(
connect_client,
deployment.account_id,
deployment.id,
ppr_file_id,
)
try:
file_data = get_ppr_from_media(
connect_client,
deployment.account_id,
deployment.id,
ppr_file_id,
)
except ClientError as e:
raise TaskException(f'Error while connecting to Connect: {e.message}')

file = prepare_ppr_file_for_task(
connect_client=connect_client,
Expand Down
70 changes: 70 additions & 0 deletions connect_ext_ppr/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,3 +682,73 @@ def execute_with_retry(function, exception_class, args=None, kwargs=None, num_re
except exception_class:
if num_retries == 0:
raise


def get_mps_to_update_for_apply_ppr_and_delegate_to_marketplaces(
ppr_file_data,
config_json,
dr_marketplaces,
):
"""Gets list of marketplaces to update, using the DR, config and PPR file data
:param dr_marketplaces: list of DeploymentRequest models
:param config_json: dict with configuration data
:param ppr_file_data: body of PPR file
:rtype dict
"""
wb = pd.ExcelFile(ppr_file_data)
ws = wb.parse('ServicePlans')

marketplace_mapping = config_json.get('marketplace_mapping', {})
cbc_marketplace_ids_dict = {}
for dr_marketplace in dr_marketplaces:
if cbc_marketplace_id := marketplace_mapping.get(dr_marketplace.marketplace):
cbc_marketplace_ids_dict[cbc_marketplace_id] = dr_marketplace.marketplace

cbc_mp_ids_found = set()
for col in ws.columns.tolist():
if col.startswith('OpUnit_'):
cbc_marketplace_id = col.split('_', 1)[1]
cbc_mp_ids_found.add(cbc_marketplace_id)

marketplaces_to_update_dict = {
cbc_marketplace_ids_dict[cbc_id]: f'OpUnit_{cbc_id}' for cbc_id in cbc_marketplace_ids_dict
if cbc_id in cbc_mp_ids_found
}
# {'MP-06811': 'OpUnit_DE', ...}
return marketplaces_to_update_dict


def process_service_plans_for_apply_ppr_and_delegate_to_marketplaces(
ws,
columns_to_keep,
):
"""Fills with 'False' columns that are not used in current task
:param ws: PPR file worksheet
:param columns_to_keep: set of names of columns to keep
"""
for col in ws.columns.tolist():
if col.startswith('OpUnit_') and col not in columns_to_keep:
ws[col] = 'FALSE'


def process_ppr_file_for_apply_ppr_and_delegate_to_marketplaces(
sheet_name,
ws,
columns_to_keep,
):
"""Processes PPR file's sheet depending on it's name
:param sheet_name: name of current sheet of PPR file
:param ws: body of PPR file worksheet
:param columns_to_keep: set of names of columns to keep
"""
if sheet_name == 'ServicePlans':
process_service_plans_for_apply_ppr_and_delegate_to_marketplaces(
ws,
columns_to_keep,
)

elif sheet_name == 'OpUnitServicePlans':
ws['Published'] = 'FALSE'
Binary file not shown.
34 changes: 34 additions & 0 deletions tests/fixtures/test_PPR_config_file.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{

"marketplace_mapping": {
"MP-54865" : "DE",
"MP-45638": "ME",
"MP-46781": "SE",
"MP-69391": "NZ",
"MP-08767": "FR",
"MP-88074": "IT",
"MP-48301": "NL",
"MP-46128": "AU",
"MP-10517": "UK",
"MP-59053": "BR",
"MP-123": "CO",
"MP-124": "AT",
"MP-125": "US",
"MP-51038": "MI",
"MP-39963": "TR",
"MP-20348": "ES",
"MP-78678": "SG",
"MP-43651": "HK",
"MP-39772": "CH",
"MP-27749": "BE",
"MP-84448": "CasaNet MA",
"MP-17986": "CA",
"MP-77107": "LA",
"MP-90393": "SA",
"MP-37238": "IN",
"MP-90416": "MY",
"MP-16747": "MX",
"MP-73019": "NO",
"MP-10523": "PE"
}
}
Binary file modified tests/fixtures/test_PPR_file_delegate_l2.xlsx
Binary file not shown.
Loading

0 comments on commit 2484416

Please sign in to comment.