def get_supplier_ids_not_signed(api_client: DataAPIClient, framework_slug: str) -> List[int]: """ Get a list of supplier IDs who have at least one successful lot entry but have not signed the framework agreement """ return [supplier["supplierId"] for supplier in api_client.find_framework_suppliers_iter(framework_slug, agreement_returned=False, with_declarations=False) if supplier["onFramework"]]
def get_supplier_ids_signed(api_client: DataAPIClient, framework_slug: str) -> List[int]: """ Get a list of supplier IDs who are on `framework_slug` and have signed the framework agreement """ return [ supplier["supplierId"] for supplier in api_client.find_framework_suppliers_iter( framework_slug, agreement_returned=True, with_declarations=False) if supplier["onFramework"] ]
def find_suppliers_on_framework(client: DataAPIClient, framework_slug: str) -> Iterable[Mapping]: return (supplier_framework for supplier_framework in client.find_framework_suppliers_iter( framework_slug, with_declarations=None) if supplier_framework['onFramework'])
def notify_suppliers_of_framework_application_event( data_api_client: DataAPIClient, notify_client: DMNotifyClient, notify_template_id: str, framework_slug: str, stage: str, dry_run: bool, logger: Logger, run_id: Optional[UUID] = None, ) -> int: run_is_new = not run_id run_id = run_id or uuid4() logger.info( f"{'Starting' if run_is_new else 'Resuming'} run id {{run_id}}", extra={"run_id": str(run_id)}) framework = data_api_client.get_framework(framework_slug)["frameworks"] framework_context = { "framework_name": framework["name"], "updates_url": f"{get_web_url_from_stage(stage)}/suppliers/frameworks/{framework['slug']}/updates", "framework_dashboard_url": f"{get_web_url_from_stage(stage)}/suppliers/frameworks/{framework['slug']}/", "clarification_questions_closed": "no" if framework["clarificationQuestionsOpen"] else "yes", **_formatted_dates_from_framework(framework), } failure_count = 0 for supplier_framework in data_api_client.find_framework_suppliers_iter( framework_slug): for user in data_api_client.find_users_iter( supplier_id=supplier_framework["supplierId"]): if user["active"]: # generating ref separately so we can exclude certain parameters from the context dict notify_ref = notify_client.get_reference( user["emailAddress"], notify_template_id, { "framework_slug": framework["slug"], "run_id": str(run_id), }, ) if dry_run: # Use the sent references cache unless we're re-running the script following a failure if notify_client.has_been_sent( notify_ref, use_recent_cache=run_is_new): logger.debug( "[DRY RUN] Would NOT send notification to {email_hash} (already sent)", extra={ "email_hash": hash_string(user["emailAddress"]) }, ) else: logger.info( "[DRY RUN] Would send notification to {email_hash}", extra={ "email_hash": hash_string(user["emailAddress"]) }, ) else: try: # Use the sent references cache unless we're re-running the script following a failure notify_client.send_email( user["emailAddress"], notify_template_id, framework_context, allow_resend=False, reference=notify_ref, use_recent_cache=run_is_new, ) except EmailError as e: failure_count += 1 logger.error( "Failed sending to {email_hash}: {e}", extra={ "email_hash": hash_string(user["emailAddress"]), "e": str(e), }, ) if isinstance(e, EmailTemplateError): raise # do not try to continue return failure_count