Sales order Ack feature implemented

main
vrashank 9 months ago
parent b34d72dedf
commit 18bed4e7fa

@ -0,0 +1,8 @@
// Copyright (c) 2025, UnifyXperts and contributors
// For license information, please see license.txt
// frappe.ui.form.on("Acknowledgement Type", {
// refresh(frm) {
// },
// });

@ -0,0 +1,50 @@
{
"actions": [],
"allow_rename": 1,
"autoname": "field:type",
"creation": "2025-04-24 01:59:12.184305",
"doctype": "DocType",
"engine": "InnoDB",
"field_order": [
"type",
"description"
],
"fields": [
{
"fieldname": "type",
"fieldtype": "Data",
"label": "Type",
"unique": 1
},
{
"fieldname": "description",
"fieldtype": "Data",
"label": "Description"
}
],
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-04-24 02:03:12.556191",
"modified_by": "Administrator",
"module": "SPS Integration",
"name": "Acknowledgement Type",
"naming_rule": "By fieldname",
"owner": "Administrator",
"permissions": [
{
"create": 1,
"delete": 1,
"email": 1,
"export": 1,
"print": 1,
"read": 1,
"report": 1,
"role": "System Manager",
"share": 1,
"write": 1
}
],
"sort_field": "modified",
"sort_order": "DESC",
"states": []
}

@ -0,0 +1,9 @@
# Copyright (c) 2025, UnifyXperts and contributors
# For license information, please see license.txt
# import frappe
from frappe.model.document import Document
class AcknowledgementType(Document):
pass

@ -0,0 +1,9 @@
# Copyright (c) 2025, UnifyXperts and Contributors
# See license.txt
# import frappe
from frappe.tests.utils import FrappeTestCase
class TestAcknowledgementType(FrappeTestCase):
pass

@ -2,8 +2,11 @@ import requests
import json
import frappe
from datetime import datetime, timedelta
from frappe.utils import get_datetime, now_datetime
from .oauth import refresh_access_token
from frappe.utils import now
def format_sales_order_ack(data: dict) -> dict:
def format_sales_order_ack(data: dict, schedule_shipped_date: str, ack_typ: str) -> dict:
"""
Format sales order acknowledgment for SPS Commerce API.
@ -26,22 +29,29 @@ def format_sales_order_ack(data: dict) -> dict:
purchase_order_date = datetime.strptime(purchase_order_date_str, "%Y-%m-%d")
acknowledgment_date = (purchase_order_date + timedelta(days=1)).strftime("%Y-%m-%d")
except ValueError:
acknowledgment_date = (datetime.utcnow() + timedelta(days=1)).strftime("%Y-%m-%d")
print("f")
# acknowledgment_date = (datetime.utcnow() + timedelta(days=1)).strftime("%Y-%m-%d")
acknowledgement_payload = {
"meta": {
"transactionType": "855"
},
"Header": {
"OrderHeader": {
"tradingPartnerId": order_header.get("TradingPartnerId", ""),
"purchaseOrderNumber": order_header.get("PurchaseOrderNumber"),
"acknowledgmentType": "AK",
"acknowledgmentDate": acknowledgment_date,
"purchaseOrderDate": purchase_order_date_str,
"vendor": order_header.get("Vendor")
}
"TradingPartnerId": order_header.get("TradingPartnerId", ""),
"AurchaseOrderNumber": order_header.get("PurchaseOrderNumber"),
"AcknowledgmentType": ack_typ,
"AcknowledgmentDate": acknowledgment_date,
"PurchaseOrderDate": purchase_order_date_str,
"Vendor": order_header.get("Vendor")
},
},
"Dates" : [ {
"DateTimeQualifier" : "068",
"Date" : schedule_shipped_date,
# "Time" : "14:22:14"
"Time" : now().split(" ")[1]
} ],
"lineItems": [
{
"lineSequenceNumber": item.get("OrderLine", {}).get("LineSequenceNumber"),
@ -55,7 +65,7 @@ def format_sales_order_ack(data: dict) -> dict:
"ItemStatusCode": "IA",
"ItemScheduleQty": item.get("OrderLine", {}).get("OrderQty", 0),
"ItemScheduleUOM": item.get("OrderLine", {}).get("OrderQtyUOM", ""),
"ItemScheduleQualifier": "064",
"ItemScheduleQualifier": "068",
"ItemScheduleDate": acknowledgment_date
}
]
@ -84,7 +94,7 @@ def format_sales_order_ack(data: dict) -> dict:
def sales_order_acknowledgement(data: dict):
def sales_order_acknowledgement(data: dict , path: str):
"""Send Sales Order Acknowledgment to SPS Commerce API."""
try:
doc = frappe.get_doc("SPS Integration Settings", "Develop")
@ -99,13 +109,68 @@ def sales_order_acknowledgement(data: dict):
if not formatted_data:
return
response = requests.post(url=doc.order_acknowledgement_url, headers=headers, data=json.dumps(formatted_data))
url = f"{doc.order_acknowledgement_url}ACK_" + path.split("_")[1]
response = requests.post(url=url, headers=headers, data=json.dumps(formatted_data))
print(response)
if response.status_code in [200, 201]:
frappe.log_error(title="SO Acknowledgment Success", message=f"{response.text}")
else:
frappe.log_error(title="SO Acknowledgment Failure", message=f"{response.text}")
return response.json()
except Exception as e:
frappe.log_error(title="SO Acknowledgment Error", message=str(frappe.get_traceback()))
@frappe.whitelist(allow_guest=True)
def submit_order_acknowledgement(path: str, schedule_shipped_date: str, ack_type: str, sales_order: str):
"""
Acknowledge the sales order
args:
path (str): ID for sales order to get payload from sps
schedule_shipped_date (str): Date for ack order
ack_type (str): Ack Type
returns:
Returns the ack sales order ID
"""
try:
doc = frappe.get_doc("SPS Integration Settings", "Develop")
url = f"{doc.get_sales_order_url}/{path}"
expires_on = get_datetime(doc.expires_on)
current_time = now_datetime()
access_token = ""
if expires_on <= current_time or (expires_on - current_time).total_seconds() <= 300:
refresh_access_token(setting_doc_name=doc)
access_token = doc.get_password("access_token")
frappe.log_error("SPS Token Refresh", "Token refreshed")
else:
access_token = doc.get_password("access_token")
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
response = requests.get(url=url, headers=headers)
if response.status_code == 200:
frappe.log_error(title="Payload for Ord ACK",message=f"{response.json()}")
formatted_data = format_sales_order_ack(response.json(),schedule_shipped_date, ack_type)
frappe.log_error(title="Formatted SO Ack Payload", message=f"{formatted_data}")
# Sales order ack functionality
ack_response = sales_order_acknowledgement(data=formatted_data,path=path)
# ack_response = {
# "path":"/in/ACK_a86e370c-43b9-3db1-b6bd-6289a132448f}-d76e3c43e0024359960669e9855509ce.dat",
# "url":"https://api.spscommerce.com/transactions/v5/data/in/ACK_a86e370c-43b9-3db1-b6bd-6289a132448f}-d76e3c43e0024359960669e9855509ce.dat"}
if ack_response:
ack_path = ack_response.get("path")
if frappe.db.exists("Sales Order", {"name": sales_order, "docstatus": 1}):
so_doc = frappe.get_doc("Sales Order", sales_order)
so_doc.custom_sales_order_ack_path = ack_path
so_doc.save()
frappe.db.commit()
frappe.log_error(title="Sales order ack path", message=f"{ack_path}")
else:
frappe.log_error(title="Payload for Ord ACK error",message=f"{response.json()}")
frappe.log_error(title="Testing functionality order ack", message=f"Order Ack Required Stuff: {path}\\n{schedule_shipped_date}\\n{ack_type}")
except Exception as e:
frappe.log_error(title="Error while ack the order through button", message=f"{str(e)}")

@ -2,10 +2,8 @@ import frappe
import datetime
from .orders_utills import (check_customer_if_exists,
create_address_contact,
get_sps_market_place_order_ID,
create_sps_sales_order_item_row,
check_and_create_contact,
create_customer_if_not_exists,
get_path_to_skip,
exclude_skipped_file_paths)
# from .order_acknowledgement import get_sales_order_pyload
@ -79,19 +77,10 @@ def enqueue_sps_sync_order(doc:str):
# """
# try:
# data = retrieve_sps_order_urls(setting_doc_name=doc)
# frappe.log_error(title="Get SPS Sales Order Polling", message=f"{data}")
# sales_orders = frappe.get_all("Sales Order", fields = ["name", "custom_sales_order_path"])
# filtered_sales_orders = {order["custom_sales_order_path"] for order in sales_orders if order["custom_sales_order_path"]}
# frappe.log_error(
# title = "Previously Synced Sales Order",
# message = f"{filtered_sales_orders}"
# )
# results = data.get("results", [])
# access_token = ""
# failed_requests = []
# skipped_sales_orders = []
# setting_doc = frappe.get_doc("SPS Integration Settings", doc)
# SPS_URL = setting_doc.get_sales_order_url
# expires_on = get_datetime(setting_doc.expires_on)
# current_time = now_datetime()
# if expires_on <= current_time or (expires_on - current_time).total_seconds() <= 300:
@ -99,23 +88,19 @@ def enqueue_sps_sync_order(doc:str):
# access_token = setting_doc.get_password("access_token")
# else:
# access_token = setting_doc.get_password("access_token")
# order_url_path = retrieve_sps_order_urls(setting_doc_name=doc).get("results", [])
# headers = {
# "Authorization": f"Bearer {access_token}",
# "Content-Type": "application/json"
# }
# for record in results:
# so_url = record.get("url")
# path = record.get("path", "").split("/")[-1]
# if path in filtered_sales_orders:
# skipped_sales_orders.append(path)
# continue
# if so_url:
# # Filtered path url for sales order to avoid duplicates
# filtered_url_path = exclude_skipped_file_paths(paths=[d.get("path").split("/")[-1] for d in order_url_path])
# for path in filtered_url_path:
# # path = record.get("path", "").split("/")[-1]
# url = f"{SPS_URL}{path}"
# if url:
# try:
# response = requests.get(url=so_url, headers=headers)
# response = requests.get(url=url, headers=headers)
# if response.status_code == 200:
# sales_order = create_sps_sales_order(
# data=response.json(),
@ -123,38 +108,26 @@ def enqueue_sps_sync_order(doc:str):
# path=path
# )
# if frappe.db.exists("Sales Order", {"name": sales_order, "docstatus":1}):
# sales_order_acknowledgement(data=response.json())
# # Once the sales order sync in ERPNext will ack the sales order
# # sales_order_acknowledgement(data=response.json())
# path_to_skip = frappe.new_doc("Paths to Skip")
# path_to_skip.file_path = path
# path_to_skip.save()
# frappe.db.commit()
# else:
# failed_requests.append(so_url)
# failed_requests.append(url)
# except requests.RequestException as e:
# failed_requests.append(so_url)
# frappe.log_error(title="Request Error", message=str(e))
# api_info = {
# "Total Sales Order Payload": len(results),
# "Failed Requests": failed_requests
# "Total sales order payload": len(filtered_url_path),
# "Failed sales order": failed_requests
# }
# frappe.log_error(title="Skipped Synced Sales Order", message=f"{skipped_sales_orders}")
# frappe.log_error(title="API Detail Info", message=f"{api_info}")
# except Exception as e:
# frappe.log_error(title="Enqueuing Error", message=f"{frappe.get_traceback()}")
# frappe.log_error(title="Error while sales order sycing", message=f"{frappe.get_traceback()}")
@frappe.whitelist(allow_guest=True)
def get_sps_sales_order(doc: str):
"""
Calls the SPS API to retrieve a list of all Sales Order URLs.
Iterates through the URLs, fetches the corresponding payloads,
syncs them into ERPNext, and stores the Sales Order URL paths.
Args:
doc (str): The settings document.
Returns:
None
"""
try:
access_token = ""
failed_requests = []
@ -162,48 +135,59 @@ def get_sps_sales_order(doc: str):
SPS_URL = setting_doc.get_sales_order_url
expires_on = get_datetime(setting_doc.expires_on)
current_time = now_datetime()
if expires_on <= current_time or (expires_on - current_time).total_seconds() <= 300:
refresh_access_token(setting_doc_name=doc)
access_token = setting_doc.get_password("access_token")
frappe.log_error("SPS Token Refresh", "Token refreshed")
else:
access_token = setting_doc.get_password("access_token")
order_url_path = retrieve_sps_order_urls(setting_doc_name=doc).get("results", [])
frappe.log_error("SPS URL Fetch", f"Fetched URLs: {order_url_path}")
headers = {
"Authorization": f"Bearer {access_token}",
"Content-Type": "application/json"
}
# Filtered path url for sales order to avoid duplicates
filtered_url_path = exclude_skipped_file_paths(paths=[d.get("path").split("/")[-1] for d in order_url_path])
frappe.log_error("Filtered Paths", f"{filtered_url_path}")
for path in filtered_url_path:
# path = record.get("path", "").split("/")[-1]
url = f"{SPS_URL}{path}"
if url:
try:
response = requests.get(url=url, headers=headers)
if response.status_code == 200:
try:
response = requests.get(url=url, headers=headers)
if response.status_code == 200:
try:
sales_order = create_sps_sales_order(
data=response.json(),
setting_doc=doc,
path=path
)
if frappe.db.exists("Sales Order", {"name": sales_order, "docstatus":1}):
# Once the sales order sync in ERPNext will ack the sales order
# sales_order_acknowledgement(data=response.json())
if frappe.db.exists("Sales Order", {"name": sales_order, "docstatus": 1}):
# Order ack
sales_order_acknowledgement(data=response.json(),path=path)
path_to_skip = frappe.new_doc("Paths to Skip")
path_to_skip.file_path = path
path_to_skip.save()
frappe.db.commit()
else:
failed_requests.append(url)
except requests.RequestException as e:
frappe.log_error(title="Request Error", message=str(e))
except Exception as inner_e:
frappe.log_error("Error in create_sps_sales_order", frappe.get_traceback())
else:
failed_requests.append(url)
frappe.log_error("Non-200 SPS Response", f"{url} returned {response.status_code}")
except requests.RequestException as e:
frappe.log_error(title="Request Error", message=f"{str(e)}\nURL: {url}")
api_info = {
"Total sales order payload": len(filtered_url_path),
"Failed sales order": failed_requests
}
frappe.log_error(title="API Detail Info", message=f"{api_info}")
except Exception as e:
frappe.log_error(title="Error while sales order sycing", message=f"{frappe.get_traceback()}")
frappe.log_error(title="Error while sales order syncing", message=frappe.get_traceback())
@ -333,10 +317,130 @@ def create_sps_sales_order(data: dict, setting_doc: str, path: str) -> None:
error_msg = frappe.get_traceback()
frappe.log_error(
title="Sales Order Creation Error",
message=f"Marketplace: SPS\n\nTraceback:\n{error_msg}",
message=f"Marketplace: SPS\n\nTraceback:\n{error_msg}\\Order not synced:{data}",
)
def create_sps_sales_order_console(data: dict, setting_doc: str, path: str) -> None:
print("🔍 Step 1: Fetching order header from payload...")
order_header = data.get("Header", {}).get("OrderHeader", {})
po_no = order_header.get("PurchaseOrderNumber")
consumer_order_number = order_header.get("CustomerOrderNumber")
po_date = order_header.get("PurchaseOrderDate")
print(f"➡️ PO No: {po_no}, Customer Order No: {consumer_order_number}, PO Date: {po_date}")
print("🔧 Step 2: Fetching SPS Integration Settings...")
try:
doc = frappe.get_doc("SPS Integration Settings", setting_doc)
print(f"✅ Settings fetched for: {setting_doc}")
except Exception as e:
print(f"❌ Failed to fetch SPS Integration Settings: {e}")
return
print("📅 Step 3: Extracting delivery date from header...")
try:
delivery_date = next(
(date.get("Date") for date in data.get("Header", {}).get("Dates", [])
if date.get("DateTimeQualifier") == "001"), None
)
print(f"➡️ Delivery Date (001): {delivery_date}")
except Exception as e:
print(f"❌ Failed to extract delivery date: {e}")
return
print("👤 Step 4: Checking/creating customer...")
try:
_, customer_name = check_customer_if_exists(data)
print(f"✅ Customer resolved: {customer_name}")
except Exception as e:
print(f"❌ Error while checking/creating customer: {e}")
return
print("📞 Step 5: Checking/creating contact...")
try:
contact_name = check_and_create_contact(data, setting_doc)
print(f"✅ Contact created/found: {contact_name}")
except Exception as e:
print(f"❌ Error while creating contact: {e}")
return
print("🏠 Step 6: Creating billing and shipping addresses...")
try:
billing_address, shipping_address = create_address_contact(data, customer_name)
print(f"✅ Billing: {billing_address}, Shipping: {shipping_address}")
except Exception as e:
print(f"❌ Error while creating addresses: {e}")
return
print("🛒 Step 7: Validating marketplace...")
marketplace_name = doc.marketplace
if not marketplace_name:
print("❌ No wholesale marketplace configured in settings.")
frappe.log_error("SPS Order Error", "No wholesale marketplace found.")
return
print(f"➡️ Marketplace: {marketplace_name}")
try:
series_name = frappe.get_value("Marketplace", marketplace_name, "naming_series")
print(f"✅ Naming Series: {series_name}")
except Exception as e:
print(f"❌ Failed to get naming series for marketplace: {e}")
return
print("📝 Step 8: Creating new Sales Order document...")
try:
sales_order = frappe.new_doc("Sales Order")
sales_order.naming_series = series_name
sales_order.customer = customer_name
sales_order.custom_spss_purchase_order = po_no
sales_order.po_no = consumer_order_number
sales_order.transaction_date = datetime.datetime.strptime(po_date, "%Y-%m-%d").date()
sales_order.marketplace = marketplace_name
sales_order.delivery_date = frappe.utils.add_to_date(po_date, days=doc.days)
sales_order.customer_address = billing_address
sales_order.shipping_address_name = shipping_address
sales_order.custom_sales_order_path = path
if contact_name:
sales_order.contact_person = contact_name
print("✅ Sales Order initialized.")
except Exception as e:
print(f"❌ Failed to create Sales Order document: {e}")
return
print("📦 Step 9: Adding items to Sales Order...")
try:
for idx, item in enumerate(data.get("LineItem", []), start=1):
line_item = item.get("OrderLine", {})
sku = line_item.get("VendorPartNumber")
quantity = line_item.get("OrderQty", 0)
uom = line_item.get("OrderQtyUOM")
amount = line_item.get("PurchasePrice", 0.0)
description = next(
(desc.get("ProductDescription") for desc in item.get("ProductOrItemDescription", [])), ""
)
print(f" Item {idx}: SKU: {sku}, Qty: {quantity}, UOM: {uom}, Price: {amount}")
item_row = create_sps_sales_order_item_row(sku, quantity, amount, uom, description, setting_doc)
sales_order.append("items", item_row)
print("✅ All items added to Sales Order.")
except Exception as e:
print(f"❌ Failed while adding items to Sales Order: {e}")
return
print("💾 Step 10: Saving and submitting Sales Order...")
try:
sales_order.save()
sales_order.submit()
frappe.db.commit()
print(f"🎉 Sales Order '{sales_order.name}' created and submitted successfully!")
return sales_order.name
except Exception as e:
error_msg = frappe.get_traceback()
print(f"❌ Error during saving/submitting Sales Order: {e}")
frappe.log_error(
title="Sales Order Creation Error",
message=f"Marketplace: SPS\n\nTraceback:\n{error_msg}\\Order not synced:{data}",
)

@ -75,25 +75,25 @@ def get_sps_item_code_if_exists(order_uom: str, description: str, sku: str, sett
if frappe.db.exists("Item", {"item_code": sku}):
return sku
item_doc = frappe.new_doc("Item")
item_doc.update({
"item_code": sku,
"item_name": description,
"stock_uom": get_uom(order_uom) if order_uom != "EA" and order_uom != None else frappe.get_value("SPS Integration Settings", setting_doc, "default_uom"),
"item_group": frappe.get_value("SPS Integration Settings", setting_doc, "default_item_group"),
"custom_item_shipping_category": frappe.get_value("SPS Integration Settings", setting_doc, "shipping_category")
})
try:
item_doc.save()
frappe.db.commit()
except:
frappe.log_error(
title="Item creation",
message=f"{frappe.get_traceback()}"
)
return item_doc.name
# item_doc = frappe.new_doc("Item")
# item_doc.update({
# "item_code": sku,
# "item_name": description,
# "stock_uom": get_uom(order_uom) if order_uom != "EA" and order_uom != None else frappe.get_value("SPS Integration Settings", setting_doc, "default_uom"),
# "item_group": frappe.get_value("SPS Integration Settings", setting_doc, "default_item_group"),
# "custom_item_shipping_category": frappe.get_value("SPS Integration Settings", setting_doc, "shipping_category")
# })
# try:
# item_doc.save()
# frappe.db.commit()
# except:
# frappe.log_error(
# title="Item creation",
# message=f"{frappe.get_traceback()}"
# )
# return item_doc.name
def get_uom(uom: str) -> str:
"""Get or create UOM."""
@ -157,111 +157,121 @@ def get_link_row(docname: str, link_name: str) -> Dict:
return row
# def check_and_create_contact(data, setting_doc):
# """Check if contacts exist, else create new contacts"""
# addresses = data.get('Header', {}).get('Address', [])
# contacts = None
# for address in addresses:
# if address.get("AddressTypeCode") == "BT" and address.get("Contacts"):
# contacts = address["Contacts"]
# break # Stop once billing contacts are found
# if not contacts:
# for address in addresses:
# if address.get("AddressTypeCode") == "ST" and address.get("Contacts"):
# contacts = address["Contacts"]
# break # Stop once shipping contacts are found
# if not contacts:
# return None
# # Check if customer exists
# customer_exists, customer_name = check_customer_if_exists(data)
# if customer_exists:
# # Check if the contact email already exists
# email_id = contacts[0].get("PrimaryEmail", "")
# if frappe.db.exists("Contact Email", {"email_id": email_id}):
# contact_name = frappe.get_value(
# "Contact Email", {"email_id": email_id}, "parent"
# )
# else:
# doc = frappe.new_doc("Contact")
# doc.first_name = customer_name
# if email_id:
# email_row = {
# "email_id": email_id,
# "is_primary": 1
# }
# doc.append("email_ids", email_row)
# phone_number = contacts[0].get("PrimaryPhone", "")
# if phone_number:
# num_row = {
# "phone": phone_number,
# "is_primary_phone": 1
# }
# doc.append("phone_nos", num_row)
# link_row = get_link_row("Customer", customer_name)
# doc.append("links", link_row)
# doc.save()
# frappe.db.commit()
# contact_name = doc.name
# return contact_name
# Made the fixes related to assignment error of contact_name variable
def check_and_create_contact(data, setting_doc):
"""Check if contacts exist, else create new contacts"""
addresses = data.get('Header', {}).get('Address', [])
contacts = None
for address in addresses:
if address.get("AddressTypeCode") == "BT" and address.get("Contacts"):
contacts = address["Contacts"]
break # Stop once billing contacts are found
break
if not contacts:
for address in addresses:
if address.get("AddressTypeCode") == "ST" and address.get("Contacts"):
contacts = address["Contacts"]
break # Stop once shipping contacts are found
break
if not contacts:
if not contacts or len(contacts) == 0:
return None
# Check if customer exists
customer_exists, customer_name = check_customer_if_exists(data)
if not customer_exists:
return None
if customer_exists:
# Check if the contact email already exists
email_id = contacts[0].get("PrimaryEmail", "")
if frappe.db.exists("Contact Email", {"email_id": email_id}):
contact_name = frappe.get_value(
"Contact Email", {"email_id": email_id}, "parent"
)
else:
doc = frappe.new_doc("Contact")
doc.first_name = customer_name
if email_id:
email_row = {
"email_id": email_id,
"is_primary": 1
}
doc.append("email_ids", email_row)
phone_number = contacts[0].get("PrimaryPhone", "")
if phone_number:
num_row = {
"phone": phone_number,
"is_primary_phone": 1
}
doc.append("phone_nos", num_row)
link_row = get_link_row("Customer", customer_name)
doc.append("links", link_row)
doc.save()
frappe.db.commit()
contact_name = doc.name
return contact_name
def create_customer_if_not_exists(data: dict, setting_doc: str) -> str:
"""
Create new customer if not exists.
Args:
data (Dict): Payload from webhook
setting_doc (str): setting doc name
Returns:
customer_name (str): Return customer name after creation of customer.
"""
trading_id = data.get("Header", {}).get("OrderHeader", {}).get("TradingPartnerId")
addresses = data.get("Header", {}).get("Address", [])
address_names = [address.get("AddressName") for address in addresses]
contact_name = None
first_contact = contacts[0]
email_id = first_contact.get("PrimaryEmail", "")
if frappe.db.exists("Customer", {"custom_trading_partner_id": trading_id}):
customer_name = frappe.get_value(
"Customer",
{"custom_trading_partner_id": trading_id},
"name"
if frappe.db.exists("Contact Email", {"email_id": email_id}):
contact_name = frappe.get_value(
"Contact Email", {"email_id": email_id}, "parent"
)
else:
doc = frappe.new_doc("Customer")
doc.custom_trading_partner_id = trading_id
doc.customer_name = address_names[0].capitalize()
doc.customer_type = frappe.get_value(
"SPS Integration Settings", setting_doc, "customer_type"
)
doc = frappe.new_doc("Contact")
doc.first_name = customer_name
if email_id:
doc.append("email_ids", {
"email_id": email_id,
"is_primary": 1
})
phone_number = first_contact.get("PrimaryPhone", "")
if phone_number:
doc.append("phone_nos", {
"phone": phone_number,
"is_primary_phone": 1
})
doc.append("links", get_link_row("Customer", customer_name))
doc.save()
frappe.db.commit()
contact_name = doc.name
for address in addresses:
address_type = address.get("AddressTypeCode")
if address_type == "BT":
doc.customer_primary_contact = create_or_update_address(address, "Billing", doc.name)
doc.save()
frappe.db.commit()
return contact_name
return doc.name
def get_path_to_skip():
"""Function to get all paths to skip"""
@ -290,4 +300,23 @@ def exclude_skipped_file_paths(paths: List[str]) -> List[str]:
title="Error while excluding skipped file paths",
message=frappe.get_traceback()
)
return []
return []
def get_unsyced_sps_orders_urls(unsyced_path: list) -> list:
"""Returns list of sps unsyced sales order's urls"""
syced_sps_orders_path = get_path_to_skip()
cleaned_unsyced_path = [item["path"].split("/")[2] for item in unsyced_path]
unsyced_urls = []
count = 0
for path in cleaned_unsyced_path:
if path not in syced_sps_orders_path:
count += 1
unsyced_urls.append(path)
print(f"Total unsynced sales orders: {count}")
frappe.log_error(
title="Unsyced SPS SO URLs",
message=f"Total unsyced sales order: {count}\\n Paths:{unsyced_urls}"
)
Loading…
Cancel
Save