imageIdentifierMobile = the-journal-banner-mobile
https://res.cloudinary.com/hirviubsa/image/upload/v1707432624/media/grace-journal-banner-mobile.webp
All Categories .
All Categories .
Bag = (Items: )
VIEW BAGfrom flask import (Blueprint, Response, current_app, json, jsonify, request, make_response) import os import requests import pdb import time import pprint from datetime import datetime import pytz from operator import itemgetter import logging
bp = Blueprint(‘abandoned_cart’, name, url_prefix=’/abandoned_cart’)
USERNAME = current_app.config[‘USERNAME’] PASSWORD = current_app.config[‘PASSWORD’] CONSUMER_KEY = current_app.config[‘CONSUMER_KEY’] CONSUMER_SECRET = current_app.config[‘CONSUMER_SECRET’] path = os.path.dirname(file) access_token = None instance_url = None params = { “grant_type”: “password”, “client_id”: CONSUMER_KEY, # Consumer Key “client_secret”: CONSUMER_SECRET, # Consumer Secret “username”: USERNAME, # The email you use to login “password”: PASSWORD # Concat your password and your security token }
def log_in(): res = requests.post( “https://login.salesforce.com/services/oauth2/token”, params=params) # if you connect to a Sandbox, use test.salesforce.com instead
global access_token
global instance_url
if res.status_code == 200:
access_token = res.json().get("access_token")
instance_url = res.json().get("instance_url")
# pdb.set_trace()
else:
current_app.logger.info('Login failed {}'.format(res.status_code))
@bp.before_request def before_request(): log_in()
def get_local_date():
# Example date in local timezone
local_date = datetime.now() # datetime.datetime(2024, 7, 25, 12, 28, 15, 690673)
# Convert to UTC
# datetime.datetime(2024, 7, 25, 2, 28, 52, 241692, tzinfo=
return formatted_date
def sf_api_call(action, parameters={}, method=’get’, data={}): “”” Helper function to make calls to Salesforce REST API.
Parameters:
- action (str): The URL endpoint for the API action (e.g., '/services/data/v40.0/sobjects/Account/0015g00000Xxxxx')
- parameters (dict): URL parameters (optional, used for GET requests or query parameters)
- method (str): HTTP method ('get', 'post', 'patch', 'delete')
- data (dict): Data payload for POST/PATCH requests (optional)
Returns:
- The response of the API call (either JSON for GET/POST/PATCH, or None for DELETE).
"""
print(access_token) # Debugging line, ensure access token is correct
headers = {
'Content-type': 'application/json',
'Accept-Encoding': 'gzip',
'Authorization': 'Bearer %s' % access_token
}
# Handle the different HTTP methods
if method == 'get':
r = requests.request(method, instance_url + action,
headers=headers, params=parameters, timeout=30)
elif method in ['post', 'patch']:
r = requests.request(method, instance_url + action,
headers=headers, json=data, params=parameters, timeout=10)
elif method == 'delete':
r = requests.delete(instance_url + action, headers=headers, timeout=10)
else:
# Raise an error if an unsupported HTTP method is used
raise ValueError('Method should be get, post, patch, or delete.')
# Log and print the request URL for debugging
print('Debug: API %s call: %s' % (method, r.url))
current_app.logger.info('Debug: API %s call: %s' % (method, r.url))
# Handle the response status
if r.status_code < 300:
if method == 'delete':
return None # For DELETE, we return None as there's no content to return
elif method == 'patch':
return None # PATCH may not return anything useful, so return None
else:
return r.json() # Return the JSON response for GET/POST requests
else:
current_app.logger.error(
'API error when calling %s : %s' % (r.url, r.content))
raise Exception('API error when calling %s : %s' % (r.url, r.content))
def sf_get_single_cart_activity_data(id): query = ‘SELECT Id, Name, P_Session_Id__c, P_Email__c, P_Mobile_c__c, P_Last_User_Activity__c, P_Store__c, P_Checkout_Step__c FROM P_Cart_Activity__c WHERE Id = '’+’‘+id+’' ‘
return json.dumps(sf_api_call('/services/data/v39.0/query/', {'q': query}), indent=2)
def sf_get_single_cart_activity_product_data(id): query = ‘SELECT P_Cart_Activity_Id__c, Name, P_CartActivity_has_email__c, CreatedById, CurrencyIsoCode, LastModifiedById, OwnerId, P_Cart_Activity_Product_Id__c, P_Cart_Activity_Product_Quantity__c, P_Sync_CartActivityProduct_to_SFMC__c FROM P_Cart_Activity_Product__c WHERE Id = '’+’‘+id+’' ‘
return json.dumps(sf_api_call('/services/data/v39.0/query/', {'q': query}), indent=2)
def sf_get_all_cart_activity_data(): query = ‘SELECT Id, Name, P_Session_Id__c, P_Email__c, P_Mobile_c__c, P_Last_User_Activity__c, P_Store__c, P_Checkout_Step__c FROM P_Cart_Activity__c ‘
return json.dumps(sf_api_call('/services/data/v39.0/query/', {'q': query}), indent=2)
def sf_get_cart_activity_products(cart_activity_id): query = ‘SELECT Id, Name, P_Session_Id__c, P_Email__c, P_Mobile_c__c, P_Last_User_Activity__c, P_Store__c, P_Checkout_Step__c FROM P_Cart_Activity__c WHERE Id = '’+’‘+id+’' ‘
return json.dumps(sf_api_call('/services/data/v39.0/query/', {'q': query}), indent=2)
def sf_get_cart_activity_get_single_product(product_id, activity_id): # pdb.set_trace() # query = f”SELECT Id FROM P_Cart_Activity_Product__c WHERE P_Cart_Activity_Product_Id__c = ‘{product_id}’”
query = f"SELECT Id FROM P_Cart_Activity_Product__c WHERE P_Cart_Activity_Product_Id__c = '{product_id}' AND P_Cart_Activity_Id__c = '{activity_id}'"
print("-----------------------------------------------------")
print(
f"sf_get_cart_activity_get_single_product: {product_id, activity_id}")
print(f"query: {query}")
print("-----------------------------------------------------")
return json.dumps(sf_api_call('/services/data/v39.0/query/', {'q': query}), indent=2)
def update_cart_product(product_id, quantity): “”” Updates the quantity of a specific cart activity product.
Args:
product_id (str): The ID of the cart activity product to update.
quantity (int): The new quantity to set.
Returns:
Response: A Flask response object with the result of the operation.
"""
action_endpoint = f'/services/data/v40.0/sobjects/P_Cart_Activity_Product__c/Id/{product_id}'
cart_activity_product_data = {
'P_Cart_Activity_Product_Quantity__c': quantity
}
try:
# Perform the API call to update the cart activity product
sf_api_call(action_endpoint, method='patch',
data=cart_activity_product_data)
current_app.logger.info(
f"Cart activity product updated successfully. ID: {product_id}")
# Return a success response
print("-----------------------------------------------------")
print(f"Cart activity product updated successfully. ID: {product_id}")
print("-----------------------------------------------------")
response = {
"data": "",
"message": "Cart activity product successfully updated.",
"error": False
}
return make_response(jsonify(response), 200)
except Exception as error:
# Log the error and return an error response
error_message = f"Failed to update cart activity product {product_id}: {str(error)}"
print("-----------------------------------------------------")
print(error_message)
print("-----------------------------------------------------")
current_app.logger.error(error_message)
response = {
"data": "",
"message": error_message,
"error": True
}
return make_response(jsonify(response), 500)
def create_salesforce_record(object_name, data): “”” Helper function to create a record in Salesforce using the REST API.
Parameters:
- object_name: The Salesforce object name (e.g., 'P_Cart_Activity__c')
- data: The data to send in the request body
Returns:
- The response from Salesforce (parsed JSON)
"""
try:
# Make the API call to Salesforce to create the record
response = sf_api_call(
f"/services/data/v40.0/sobjects/{object_name}",
method='post',
data=data
)
# Return the response from Salesforce
print("-----------------------------------------------------")
print("inserting new product=====", response)
print("-----------------------------------------------------")
return response
except Exception as e:
print("-----------------------------------------------------")
print("inserting new product ======fail", str(e))
print("-----------------------------------------------------")
current_app.logger.error(
f"Error creating Salesforce record for {object_name}: {str(e)}")
return {"success": False, "message": str(e)}
@bp.route(‘/create_cart_activity’, methods=[‘POST’]) def create_cart_activity(): “”” Process data received from the create cart activity form. “”” if request.method != “POST”: return make_response( jsonify( {“data”: “”, “message”: “Invalid request method.”, “error”: True}), 405 )
data = request.json
required_fields = {
'checkOutStep': data.get('checkOutStep'),
'currentStoreId': data.get('currentStoreId'),
'products': data.get('products')
}
# Validate required fields
for field, value in required_fields.items():
if not value or (field == 'products' and not len(value)):
return make_response(
jsonify({
"data": "score-error",
"message": f"{field} value is missing",
"error": True
}),
400
)
# Extract other fields
email = data.get('email')
mobile = data.get('mobile')
products = data.get('products')
# Debugging breakpoint
# pdb.set_trace()
# Prepare cart activity data
cart_activity_data = {
'P_Session_Id__c': "0000000000000",
'P_Email__c': email,
'P_Mobile_c__c': mobile,
'P_Last_User_Activity__c': get_local_date(),
'P_Store__c': required_fields['currentStoreId'],
'P_Checkout_Step__c': required_fields['checkOutStep']
}
print("-----------------------------------------------------")
print(f"Create cart activity: {cart_activity_data}")
print("-----------------------------------------------------")
# Step 1: Create the Cart Activity in Salesforce
cart_activity_response = create_salesforce_record(
object_name="P_Cart_Activity__c",
data=cart_activity_data
)
if not cart_activity_response.get("success"):
return make_response(
jsonify({
"data": "",
"message": "Failed to create cart activity.",
"error": True
}),
500
)
cart_activity_id = cart_activity_response.get("id")
print("-------------######################-------------------")
print("-----------------------------------------------------")
print(f"Cart Activity created successfully with ID: {cart_activity_id}")
print("-----------------------------------------------------")
print("-------------######################-------------------")
current_app.logger.info(
f"Cart Activity created successfully with ID: {cart_activity_id}"
)
# Step 2: Create related Cart Activity Products in Salesforce
for product in products:
cart_activity_product_data = {
'P_Cart_Activity_Id__c': cart_activity_id,
'P_Cart_Activity_Product_Id__c': product.get('product_id'),
'P_Cart_Activity_Product_Quantity__c': product.get('product_quantity')
}
cart_activity_product_response = create_salesforce_record(
object_name="P_Cart_Activity_Product__c",
data=cart_activity_product_data
)
if not cart_activity_product_response.get("success"):
return make_response(
jsonify({
"data": "",
"message": "Failed to create cart activity product.",
"error": True
}),
500
)
print(
f"Cart Activity Product created successfully with ID: {cart_activity_product_response.get('id')}")
current_app.logger.info(
f"Cart Activity Product created successfully with ID: {cart_activity_product_response.get('id')}"
)
# Return success response
return make_response(
jsonify({
"data": {"sessionId": cart_activity_id, "savedEmail": email},
"message": "Cart activity and products successfully created.",
"error": False
}),
200
)
@bp.route(‘/delete_cart_activity/
# Fetch associated CartActivityProduct records
associated_products = sf_api_call(
'/services/data/v40.0/query',
{'q': associated_products_query}
)
# Loop through and delete each associated CartActivityProduct record
for product in associated_products['records']:
product_id = product['Id']
sf_api_call(
f'/services/data/v40.0/sobjects/P_Cart_Activity_Product__c/{product_id}', method='delete')
# Step 2: Delete the CartActivity parent record
action = f'/services/data/v40.0/sobjects/P_Cart_Activity__c/{activity_id}'
# No need to check result.status_code here
sf_api_call(action, method='delete')
# Return success response
return make_response(
jsonify({
"data": "",
"message": f"Record with ID {activity_id} and its associated products were successfully deleted.",
"error": False
}),
200
)
except Exception as e:
# Log and return error response
current_app.logger.error('Error in delete_cart_activity: %s' % str(e))
return make_response(
jsonify({
"data": "",
"message": f"Failed to delete the Cart Activity record: {str(e)}",
"error": True
}),
500
)
@bp.route(‘/update_cart_activity/
# Get JSON data from the request
data = request.json or {}
email = data.get('email')
phone = data.get('phone')
step = data.get('step')
# Validate input: at least one field (email, phone, or step) is required
if not any([email, phone, step]):
error_message = f"At least one of email, phone, or step is required to update cart activity {id}."
current_app.logger.error(error_message)
return make_response(
jsonify({
"data": "",
"message": error_message,
"error": True
}),
400
)
# Prepare cart activity data
cart_activity_data = {}
if email:
cart_activity_data['P_Email__c'] = email
if phone:
cart_activity_data['P_Mobile_c__c'] = phone
if step:
cart_activity_data['P_Checkout_Step__c'] = step
try:
# Update the cart activity record via API call
action = f'/services/data/v40.0/sobjects/P_Cart_Activity__c/Id/{id}'
sf_api_call(action, method='patch', data=cart_activity_data)
current_app.logger.info(
f"Cart activity updated successfully with ID: {id}")
# Return success response
return make_response(
jsonify({
"data": {"savedEmail": email},
"message": "Cart activity updated successfully.",
"error": False
}),
200
)
except Exception as e:
# Handle and log exceptions
error_message = f"Failed to update cart activity {id}: {str(e)}"
current_app.logger.error(error_message)
return make_response(
jsonify({
"data": "",
"message": error_message,
"error": True
}),
500
)
@bp.route(‘/create_cart_activity_product/
Args:
activity_id (str): The ID of the cart activity to associate the product with.
Returns:
Response: A Flask response object indicating the result of the operation.
"""
if not activity_id:
return make_response(
jsonify(
{"data": "", "message": "Activity ID is required.", "error": True}),
400
)
if request.method == "POST":
data = request.json
if not data:
return make_response(
jsonify(
{"data": "", "message": "Request payload is missing.", "error": True}),
400
)
product_id = data.get("product_id")
product_quantity = data.get("product_quantity")
if not product_id or not product_quantity:
return make_response(
jsonify(
{"data": "", "message": "Product ID and quantity are required.", "error": True}),
400
)
# Check if the product already exists in Salesforce
# pdb.set_trace()
print("-----------------------------------------------------")
print(f"create_cart_activity_product: {product_id, activity_id}")
print("-----------------------------------------------------")
response_data = sf_get_cart_activity_get_single_product(
product_id, activity_id)
records = json.loads(response_data).get('records', [])
product_exists = len(records) > 0
if product_exists:
product_sf_id = records[0]['Id']
current_app.logger.info(
f"Updating existing product with ID: {product_sf_id}")
print("-----------------------------------------------------")
print(f"Updating existing product with ID: {product_sf_id}")
print("-----------------------------------------------------")
update_cart_product(product_sf_id, product_quantity)
message = "Cart activity product successfully updated."
else:
print("-----------------------------------------------------")
print("inserting new product")
print("-----------------------------------------------------")
current_app.logger.info("Inserting new cart activity product")
# Create related Cart Activity Product in Salesforce
cart_activity_product_data = {
'P_Cart_Activity_Id__c': activity_id,
'P_Cart_Activity_Product_Id__c': product_id,
'P_Cart_Activity_Product_Quantity__c': product_quantity
}
cart_activity_product_response = create_salesforce_record(
object_name="P_Cart_Activity_Product__c",
data=cart_activity_product_data
)
if not cart_activity_product_response.get("success"):
current_app.logger.error(
f"Failed to create cart activity product for activity ID: {activity_id}")
return make_response(
jsonify(
{"data": "", "message": "Failed to create cart activity product.", "error": True}),
500
)
current_app.logger.info(
f"Cart activity product created successfully with ID: {cart_activity_product_response.get('id')}"
)
message = "Cart activity product successfully created."
# Return success response
return make_response(
jsonify({"data": "", "message": message, "error": False}),
200
)
return make_response(
jsonify(
{"data": "", "message": "Invalid request method. Only POST is allowed.", "error": True}),
405
)
@bp.route(‘/update_cart_activity_product/
Args:
activity_id (str): The ID of the cart activity to associate the product with.
Returns:
Response: A Flask response object indicating the result of the operation.
"""
if not activity_id:
return make_response(
jsonify(
{"data": "", "message": "Activity ID is required.", "error": True}),
400
)
if request.method == "POST":
data = request.json
if not data:
return make_response(
jsonify(
{"data": "", "message": "Request payload is missing.", "error": True}),
400
)
product_id = data.get("product_id")
product_quantity = data.get("product_quantity")
if not product_id or not product_quantity:
return make_response(
jsonify(
{"data": "", "message": "Product ID and quantity are required.", "error": True}),
400
)
# Check if the product already exists in Salesforce
response_data = sf_get_cart_activity_get_single_product(
product_id, activity_id)
records = json.loads(response_data).get('records', [])
product_exists = len(records) > 0
if product_exists:
product_sf_id = records[0]['Id']
current_app.logger.info(
f"Updating existing product with ID: {product_sf_id}")
print("-----------------------------------------------------")
print(f"Updating existing product with ID: {product_sf_id}")
print("-----------------------------------------------------")
update_cart_product(product_sf_id, product_quantity)
message = "Cart activity product successfully updated."
else:
current_app.logger.error(
f"Failed to update cart activity product for activity ID: {activity_id} : Product missing")
return make_response(
jsonify(
{"data": "", "message": "Failed to update cart activity product. Product missing", "error": True}),
500
)
# Return success response
return make_response(
jsonify({"data": "", "message": message, "error": False}),
200
)
return make_response(
jsonify(
{"data": "", "message": "Invalid request method. Only POST is allowed.", "error": True}),
405
)
@bp.route(‘/delete_cart_activity_product/
Args:
activity_id (str): The ID of the activity associated with the product.
Returns:
Response: Flask response indicating success or failure of the operation.
"""
if request.method == "POST":
data = request.json
if not data:
return make_response(
jsonify(
{"data": "", "message": "Request payload is missing.", "error": True}),
400
)
product_id = data.get("product_id")
if not product_id:
return make_response(
jsonify(
{"data": "", "message": "Product ID is required.", "error": True}),
400
)
try:
# Step 1: Query for the Cart Activity Product to confirm existence
product_query = sf_get_cart_activity_get_single_product(
product_id, activity_id)
records = json.loads(product_query).get('records', [])
product_exists = len(records) > 0
if not product_exists:
print("-----------------------------------------------------")
print(f"No Cart Activity Product found with ID {product_id}")
print("-----------------------------------------------------")
current_app.logger.info(
f"No Cart Activity Product found with ID {product_id}")
return make_response(
jsonify(
{"data": "", "message": f"No Cart Activity Product found with ID {product_id}.", "error": True}),
404
)
# Step 2: Delete the Cart Activity Product
product_sf_id = records[0]['Id']
sf_api_call(
f'/services/data/v40.0/sobjects/P_Cart_Activity_Product__c/{product_sf_id}', method='delete'
)
print("-----------------------------------------------------")
print(
f"Cart Activity Product with ID {product_sf_id} successfully deleted.")
print("-----------------------------------------------------")
current_app.logger.info(
f"Cart Activity Product with ID {product_sf_id} successfully deleted.")
return make_response(
jsonify(
{"data": "", "message": f"Cart Activity Product with ID {product_sf_id} successfully deleted.", "error": False}),
200
)
except Exception as e:
current_app.logger.error(
f"Error in delete_cart_activity_product: {str(e)}")
return make_response(
jsonify(
{"data": "", "message": f"Failed to delete the Cart Activity Product: {str(e)}", "error": True}),
500
)
return make_response(
jsonify(
{"data": "", "message": "Invalid request method. Only POST is allowed.", "error": True}),
405
)
@bp.route(‘/delete_all_cart_activity_products/
# Fetch associated CartActivityProduct records
associated_products = sf_api_call(
'/services/data/v40.0/query',
{'q': associated_products_query}
)
# Loop through and delete each associated CartActivityProduct record
for product in associated_products['records']:
product_id = product['Id']
sf_api_call(
f'/services/data/v40.0/sobjects/P_Cart_Activity_Product__c/{product_id}', method='delete')
# Return success response
return make_response(
jsonify({
"data": "",
"message": f"Record with this ID {activity_id} :successfully deleted all associated products.",
"error": False
}),
200
)
except Exception as e:
# Log and return error response
current_app.logger.error(
'Error in delete_cart_activity associated products: %s' % str(e))
return make_response(
jsonify({
"data": "",
"message": f"Failed to delete the Cart Activity associated products: {str(e)}",
"error": True
}),
500
)
Simply place a Grace order during the Black Friday Sale and automatically go in the draw to win a full refund of your order. Make sure you are subscribed to find out if you are a winner!
By clicking submit, you consent to receive marketing communications and can unsubscribe at any time. See competition T&C's.
Christmas gifts for everyone on your list! Explore our Grace Gift Guide today.
Shop