feat: Customer Interaction DocType for CRM contact logs from supplemental.xlsx
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2026, Westech and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
// frappe.ui.form.on("Customer Interaction", {
|
||||
// refresh(frm) {
|
||||
|
||||
// },
|
||||
// });
|
||||
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"actions": [],
|
||||
"autoname": "autoincrement",
|
||||
"creation": "2026-05-22 11:58:31.649154",
|
||||
"doctype": "DocType",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"field_order": [
|
||||
"customer",
|
||||
"customer_number",
|
||||
"contact_name",
|
||||
"phone_1",
|
||||
"phone_2",
|
||||
"email_1",
|
||||
"email_2",
|
||||
"address",
|
||||
"city",
|
||||
"zip",
|
||||
"hours",
|
||||
"notes",
|
||||
"red_r2",
|
||||
"dnc",
|
||||
"raw_name",
|
||||
"raw_phone1",
|
||||
"raw_phone2",
|
||||
"raw_email"
|
||||
],
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Customer",
|
||||
"options": "Customer",
|
||||
"reqd": 1
|
||||
},
|
||||
{
|
||||
"fieldname": "customer_number",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 1,
|
||||
"label": "Customer Number"
|
||||
},
|
||||
{
|
||||
"fieldname": "contact_name",
|
||||
"fieldtype": "Data",
|
||||
"in_list_view": 1,
|
||||
"label": "Contact Name"
|
||||
},
|
||||
{
|
||||
"fieldname": "phone_1",
|
||||
"fieldtype": "Data",
|
||||
"label": "Phone 1"
|
||||
},
|
||||
{
|
||||
"fieldname": "phone_2",
|
||||
"fieldtype": "Data",
|
||||
"label": "Phone 2"
|
||||
},
|
||||
{
|
||||
"fieldname": "email_1",
|
||||
"fieldtype": "Data",
|
||||
"label": "Email 1"
|
||||
},
|
||||
{
|
||||
"fieldname": "email_2",
|
||||
"fieldtype": "Data",
|
||||
"label": "Email 2"
|
||||
},
|
||||
{
|
||||
"fieldname": "address",
|
||||
"fieldtype": "Text",
|
||||
"label": "Address"
|
||||
},
|
||||
{
|
||||
"fieldname": "city",
|
||||
"fieldtype": "Data",
|
||||
"label": "City"
|
||||
},
|
||||
{
|
||||
"fieldname": "zip",
|
||||
"fieldtype": "Data",
|
||||
"label": "Zip"
|
||||
},
|
||||
{
|
||||
"fieldname": "hours",
|
||||
"fieldtype": "Data",
|
||||
"label": "Hours"
|
||||
},
|
||||
{
|
||||
"fieldname": "notes",
|
||||
"fieldtype": "Text",
|
||||
"label": "Notes"
|
||||
},
|
||||
{
|
||||
"fieldname": "red_r2",
|
||||
"fieldtype": "Data",
|
||||
"in_standard_filter": 1,
|
||||
"label": "Red R2"
|
||||
},
|
||||
{
|
||||
"default": "0",
|
||||
"fieldname": "dnc",
|
||||
"fieldtype": "Check",
|
||||
"label": "DNC"
|
||||
},
|
||||
{
|
||||
"fieldname": "raw_name",
|
||||
"fieldtype": "Text",
|
||||
"label": "Raw Name"
|
||||
},
|
||||
{
|
||||
"fieldname": "raw_phone1",
|
||||
"fieldtype": "Data",
|
||||
"label": "Raw Phone 1"
|
||||
},
|
||||
{
|
||||
"fieldname": "raw_phone2",
|
||||
"fieldtype": "Data",
|
||||
"label": "Raw Phone 2"
|
||||
},
|
||||
{
|
||||
"fieldname": "raw_email",
|
||||
"fieldtype": "Data",
|
||||
"label": "Raw Email"
|
||||
}
|
||||
],
|
||||
"grid_page_length": 50,
|
||||
"index_web_pages_for_search": 1,
|
||||
"links": [],
|
||||
"modified": "2026-05-22 11:58:31.649154",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Westech R2",
|
||||
"name": "Customer Interaction",
|
||||
"naming_rule": "Autoincrement",
|
||||
"owner": "Administrator",
|
||||
"permissions": [],
|
||||
"row_format": "Dynamic",
|
||||
"rows_threshold_for_grid_search": 20,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"states": [],
|
||||
"title_field": "contact_name",
|
||||
"track_changes": 1,
|
||||
"track_seen": 1
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2026, Westech and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class CustomerInteraction(Document):
|
||||
pass
|
||||
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2026, Westech and Contributors
|
||||
# See license.txt
|
||||
|
||||
# import frappe
|
||||
from frappe.tests.utils import FrappeTestCase
|
||||
|
||||
|
||||
class TestCustomerInteraction(FrappeTestCase):
|
||||
pass
|
||||
@@ -0,0 +1,107 @@
|
||||
import frappe
|
||||
import csv
|
||||
|
||||
def create_customer_interaction_doctype():
|
||||
"""Create Customer Interaction DocType if it doesn't exist"""
|
||||
if frappe.db.exists("DocType", "Customer Interaction"):
|
||||
print("Customer Interaction DocType already exists")
|
||||
return
|
||||
|
||||
doc = frappe.get_doc({
|
||||
"doctype": "DocType",
|
||||
"module": "Westech R2",
|
||||
"name": "Customer Interaction",
|
||||
"title_field": "contact_name",
|
||||
"autoname": "autoincrement",
|
||||
"naming_rule": "Autoincrement",
|
||||
"track_changes": 1,
|
||||
"track_seen": 1,
|
||||
"fields": [
|
||||
{"label": "Customer", "fieldname": "customer", "fieldtype": "Link", "options": "Customer", "in_list_view": 1, "reqd": 1, "in_standard_filter": 1},
|
||||
{"label": "Customer Number", "fieldname": "customer_number", "fieldtype": "Data", "in_list_view": 1, "in_standard_filter": 1},
|
||||
{"label": "Contact Name", "fieldname": "contact_name", "fieldtype": "Data", "in_list_view": 1},
|
||||
{"label": "Phone 1", "fieldname": "phone_1", "fieldtype": "Data"},
|
||||
{"label": "Phone 2", "fieldname": "phone_2", "fieldtype": "Data"},
|
||||
{"label": "Email 1", "fieldname": "email_1", "fieldtype": "Data"},
|
||||
{"label": "Email 2", "fieldname": "email_2", "fieldtype": "Data"},
|
||||
{"label": "Address", "fieldname": "address", "fieldtype": "Text"},
|
||||
{"label": "City", "fieldname": "city", "fieldtype": "Data"},
|
||||
{"label": "Zip", "fieldname": "zip", "fieldtype": "Data"},
|
||||
{"label": "Hours", "fieldname": "hours", "fieldtype": "Data"},
|
||||
{"label": "Notes", "fieldname": "notes", "fieldtype": "Text"},
|
||||
{"label": "Red R2", "fieldname": "red_r2", "fieldtype": "Data", "in_standard_filter": 1},
|
||||
{"label": "DNC", "fieldname": "dnc", "fieldtype": "Check"},
|
||||
{"label": "Raw Name", "fieldname": "raw_name", "fieldtype": "Text"},
|
||||
{"label": "Raw Phone 1", "fieldname": "raw_phone1", "fieldtype": "Data"},
|
||||
{"label": "Raw Phone 2", "fieldname": "raw_phone2", "fieldtype": "Data"},
|
||||
{"label": "Raw Email", "fieldname": "raw_email", "fieldtype": "Data"},
|
||||
]
|
||||
})
|
||||
|
||||
doc.insert()
|
||||
frappe.db.commit()
|
||||
print(f"Created Customer Interaction DocType")
|
||||
|
||||
def import_contacts(csv_path):
|
||||
"""Import contacts from CSV file"""
|
||||
count = 0
|
||||
errors = 0
|
||||
|
||||
with open(csv_path, 'r', encoding='utf-8') as f:
|
||||
reader = csv.DictReader(f)
|
||||
for row in reader:
|
||||
try:
|
||||
# Find customer by customer_number
|
||||
customer = frappe.db.get_value("Customer", {"customer_number": row['customer_number']}, "name")
|
||||
|
||||
if not customer:
|
||||
# Customer doesn't exist yet, skip or create placeholder
|
||||
errors += 1
|
||||
continue
|
||||
|
||||
interaction = frappe.get_doc({
|
||||
"doctype": "Customer Interaction",
|
||||
"customer": customer,
|
||||
"customer_number": row['customer_number'],
|
||||
"contact_name": row.get('contact_name', ''),
|
||||
"phone_1": row.get('phone_1', ''),
|
||||
"phone_2": row.get('phone_2', ''),
|
||||
"email_1": row.get('email_1', ''),
|
||||
"email_2": row.get('email_2', ''),
|
||||
"address": row.get('address', ''),
|
||||
"city": row.get('city', ''),
|
||||
"zip": row.get('zip', ''),
|
||||
"hours": row.get('hours', ''),
|
||||
"notes": row.get('notes', ''),
|
||||
"red_r2": row.get('red_r2', ''),
|
||||
"dnc": 1 if row.get('dnc', '').strip() else 0,
|
||||
"raw_name": row.get('raw_name', ''),
|
||||
"raw_phone1": row.get('raw_phone1', ''),
|
||||
"raw_phone2": row.get('raw_phone2', ''),
|
||||
"raw_email": row.get('raw_email', '')
|
||||
})
|
||||
|
||||
interaction.insert()
|
||||
count += 1
|
||||
|
||||
if count % 500 == 0:
|
||||
frappe.db.commit()
|
||||
print(f"Imported {count} interactions...")
|
||||
|
||||
except Exception as e:
|
||||
errors += 1
|
||||
if errors < 10:
|
||||
print(f"Error importing row {count}: {e}")
|
||||
|
||||
frappe.db.commit()
|
||||
print(f"Import complete: {count} interactions imported, {errors} errors")
|
||||
|
||||
if __name__ == "__main__":
|
||||
frappe.init(site="erpnext.local")
|
||||
frappe.connect()
|
||||
|
||||
try:
|
||||
create_customer_interaction_doctype()
|
||||
import_contacts("/home/frappe/erpnext-bench/apps/westech_r2/westech_r2/crm_contacts_clean.csv")
|
||||
finally:
|
||||
frappe.destroy()
|
||||
Reference in New Issue
Block a user