Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LITE-28561 Implement sync PPR to marketplaces #117

Merged
merged 1 commit into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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