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

activation-detail-prospecting-metadata-grouping-api #86

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
13 changes: 13 additions & 0 deletions client/src/components/Api/Api.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,19 @@ export const fetchSalesforceTasksByUserIds = async (userIds) => {
return { ...response.data, statusCode: response.status };
};

/**
* Fetches the prospecting activity type groupings for a given activation
* @param {string} activationId
* @returns {Promise<ApiResponse>}
*/
export const fetchProspectingActivityTypeGroupings = async (activationId) => {
const response = await api.get("/get_prospecting_activity_type_groupings", {
params: { activation_id: activationId },
validateStatus: () => true,
});
return { ...response.data, statusCode: response.status };
};

/**
* Fetches Salesforce events from the Salesforce API
* @param {string[]} userIds
Expand Down
3 changes: 3 additions & 0 deletions client/src/pages/Prospecting/Prospecting.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
getLoggedInUser,
getUserTimezone,
getPaginatedProspectingActivities,
fetchProspectingActivityTypeGroupings
} from "src/components/Api/Api";
import AccountDetail from "../../components/ProspectingActiveAccount/AccountDetail";
import CustomSelect from "src/components/CustomSelect/CustomSelect";
Expand Down Expand Up @@ -227,6 +228,8 @@ const Prospecting = () => {
if (response.statusCode === 200 && response.success) {
setSummaryData(response.data[0].summary);
setRawData(response.data[0].raw_data || []);
const testPmGroup = await fetchProspectingActivityTypeGroupings(response.data[0].raw_data[0].id);
console.log(testPmGroup);
setOriginalRawData(response.data[0].raw_data || []);
} else if (response.statusCode === 401) {
navigate("/");
Expand Down
24 changes: 24 additions & 0 deletions server/app/database/activation_selector.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,27 @@ def load_active_activations_paginated_with_search(
return ApiResponse(
success=False, message=f"Failed to load activations: {str(error_msg)}"
)

def load_single_activation_by_id(activation_id: str) -> ApiResponse:
supabase_client = get_supabase_admin_client()

try:
response = (
supabase_client.table("Activations")
.select("*")
.eq("id", activation_id)
.limit(1)
.execute()
)
if response.data:
activation = supabase_dict_to_python_activation(response.data[0])
return ApiResponse(data=[activation], success=True)
else:
return ApiResponse(data=[], success=False, message="Activation not found")
except Exception as e:
error_msg = format_error_message(e)
logging.error(f"Error in load_single_activation_by_id: {error_msg}")
return ApiResponse(
success=False, message=f"Failed to load activation: {str(error_msg)}"
)

62 changes: 7 additions & 55 deletions server/app/helpers/activation_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -759,60 +759,12 @@ def get_inbound_tasks_within_period(inbound_tasks, start_date, period_days):
]


def get_prospecting_metadata_direction(
task_id: str, activation: Activation, settings: Settings
) -> str:
for metadata in activation.prospecting_metadata:
if task_id in metadata.task_ids:
for criterion in settings.criteria:
if criterion.name == metadata.name:
return (
criterion.direction or "outbound"
) # Default to outbound if direction is not specified
return "matching_criteria_not_found"

def set_effort_and_results_by_full_user_name(
activations: List[Activation], settings: Settings
) -> List[Activation]:
for activation in activations:
outbound_metadata = defaultdict(lambda: defaultdict(list))
inbound_metadata = defaultdict(lambda: defaultdict(list))

for task in activation.tasks:
direction = get_prospecting_metadata_direction(
task["Id"], activation, settings
)
metadata_dict = (
outbound_metadata if direction.lower() == "outbound" else inbound_metadata
)

owner_id = task["OwnerId"]
criterion_name = next(
(
m.name
for m in activation.prospecting_metadata
if task["Id"] in m.task_ids
),
None,
)

if criterion_name:
metadata_dict[owner_id][criterion_name].append(task["Id"])

activation.outbound_prospecting_metadata_by_user = {
owner_id: [
ProspectingMetadata(name=name, task_ids=set(ids), total=len(ids))
for name, ids in criteria.items()
]
for owner_id, criteria in outbound_metadata.items()
}
def fetch_prospecting_activity_type_groupings(
activation: Activation
) -> List[ProspectingMetadata]:
if not activation.prospecting_metadata:
return []

activation.inbound_prospecting_metadata_by_user = {
owner_id: [
ProspectingMetadata(name=name, task_ids=set(ids), total=len(ids))
for name, ids in criteria.items()
]
for owner_id, criteria in inbound_metadata.items()
}
sorted_metadata = sorted(activation.prospecting_metadata, key=lambda x: x.total)

return activations
return sorted_metadata
24 changes: 20 additions & 4 deletions server/app/routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from app.utils import format_error_message, log_error, get_salesforce_team_ids
from app.database.activation_selector import (
load_active_activations_minimal_by_ids,
load_single_activation_by_id,
load_activations_by_period,
load_active_activations_paginated_by_ids,
load_active_activations_paginated_with_search,
Expand All @@ -25,7 +26,7 @@
)
from app.helpers.activation_helper import (
generate_summary,
set_effort_and_results_by_full_user_name,
fetch_prospecting_activity_type_groupings
)
from app.services.setting_service import define_criteria_from_events_or_tasks
from app.engine.activation_engine import update_activation_states
Expand Down Expand Up @@ -330,9 +331,6 @@ def get_paginated_prospecting_activities():

if result.success:
full_activations = result.data["activations"]
full_activations = set_effort_and_results_by_full_user_name(
full_activations, load_settings()
)
response.data = [
{
"raw_data": [
Expand Down Expand Up @@ -642,6 +640,24 @@ def get_event_fields():

return jsonify(response.__dict__), get_status_code(response)

@bp.route("/get_prospecting_activity_type_groupings", methods=["GET"])
@authenticate
def get_prospecting_activity_type_groupings():
from app.data_models import ApiResponse
activation_id = request.args.get("activation_id")
response = ApiResponse(data=[], message="", success=False)
try:
activation = load_single_activation_by_id(activation_id)
if not activation.success:
raise Exception(activation.message)
response.data = fetch_prospecting_activity_type_groupings(activation.data[0])
response.success = True
except Exception as e:
log_error(e)
response.message = f"Failed to retrieve prospecting activity type groupings: {format_error_message(e)}"

return jsonify(response.to_dict()), get_status_code(response)


@bp.route("/get_task_query_count", methods=["POST"])
@authenticate
Expand Down
Loading