Overview
Contact management features:- Unified customer and supplier database
- Multiple contact types (customer, supplier, both)
- Contact relationships (family members, business partners)
- Comprehensive contact information (addresses, IDs, phones, emails)
- Activity history (invoices, quotations, payments)
- Bulk import from Excel/CSV
- Duplicate detection
Contact Types
OptiFlow supports different contact classifications:| Type | Code | Usage |
|---|---|---|
| Customer | customer | Entities you sell to |
| Supplier | supplier | Entities you buy from |
| Both | both | Entities you both buy from and sell to |
ContactType enum in app/Enums/ContactType.php
Creating a Contact
Navigate to Contacts
Go to Contacts → Create ContactReference:
ContactController::create() in app/Http/Controllers/ContactController.php:42Requires contacts:create permission.Enter Basic Information
Required Fields:
- Name: Contact’s full name or business name
- Contact Type: Customer, Supplier, or Both
- Commercial Name: Trading name (if different from legal name)
- Email: Primary email address
- Phone: Primary phone number
- Mobile: Mobile phone number
- Website: Company website
Add Identification
Configure identification documents:Identification Type: Select from:Reference:
- RNC (Registro Nacional de Contribuyentes) - Tax ID
- Cédula - National ID card
- Pasaporte - Passport
- Other identification types
For Dominican Republic businesses, RNC is mandatory for proper tax compliance and invoice generation.
IdentificationType enum defines available ID typesAdd Address Information
Primary Address (Optional but recommended):
- Street address
- City
- State/Province
- Postal code
- Country
- Invoice billing address
- Delivery address (default)
- Correspondence
Configure Relationships
Link this contact to related contacts:Use Cases:
- Family members (parent, child, spouse)
- Business partners
- Subsidiaries
- Alternative contacts
- Search for existing contact
- Select relationship type or add description
- Add to relationships list
- View consolidated activity across related contacts
- Track family/group purchasing patterns
- Share notes and history
Save Contact
Click Create ContactThe system:
- Validates required fields
- Checks for potential duplicates (optional)
- Creates contact record
- Creates primary address (if provided)
- Establishes relationships
- Redirects to contact detail page
CreateContactAction::handle() in app/Actions/CreateContactAction.phpContact Information Fields
Complete Field List
Identity:- Name (required)
- Commercial name
- Identification type
- Identification number
- Phone
- Mobile
- Website
- Contact type (Customer/Supplier/Both)
- Tags or categories (if configured)
- Multiple addresses supported
- Primary address designation
- Full address components
- Related contacts with descriptions
- Bidirectional relationships
- Credit limit (optional)
- Payment terms preference
- Tax classification
Viewing Contact Details
Navigate to Contact
Go to Contacts → Select a contact from the listReference:
ContactController::show() in app/Http/Controllers/ContactController.php:82Overview Tab
View contact summary:
- Basic information
- Primary address
- Recent activity
- Quick statistics
Invoices Tab
View all invoices for this contact:
- Invoice number and date
- Total amount
- Status (Paid, Pending, Overdue)
- Payment status
- Quick actions (view, download PDF)
Quotations Tab
View all quotations:
- Quotation number and date
- Status (Pending, Approved, Converted)
- Total quoted amount
- Actions (view, convert to invoice)
Activity Tab
Complete activity log:
- Contact changes
- Invoice created/paid
- Quotations sent
- Payments received
- Notes added
- User who performed action
- Timestamp
Editing Contacts
Open Contact Editor
From contact detail page, click Edit ContactReference:
ContactController::edit() in app/Http/Controllers/ContactController.php:170Requires contacts:edit permission.Modify Information
Update any contact fields:
- Basic information
- Contact type
- Identification
- Addresses
- Relationships
Contact Relationships
Setting Up Relationships
Contact relationships allow linking related individuals or businesses: Relationship Types (custom descriptions):- “Parent” / “Child”
- “Spouse”
- “Business Partner”
- “Subsidiary”
- “Primary Contact” / “Alternative Contact”
- “Referral Source”
Benefits of Relationships
- Consolidated Reporting: View all invoices and quotations for a family or group
- Shared History: See complete interaction history
- Cross-References: Easy navigation between related contacts
Adding Relationships
Search for Related Contact
Use the relationship search field:
- Type contact name or ID
- Select from results
- Contact cannot be related to itself
Add Description
Describe the relationship:
- “Mother of [contact]”
- “Alternative phone for [contact]”
- “Partner”
Importing Contacts
Bulk import contacts from Excel or CSV files.Navigate to Import
Go to Contacts → Import ContactsReference:
ContactImportController in app/Http/Controllers/ContactImportController.phpUpload File
Supported formats:
- Excel (.xlsx, .xls)
- CSV (.csv)
- First row should contain headers
- At minimum, include contact names
CreateContactImportAction parses file using ParseExcelFileAction or ParseCsvFileActionMap Columns
Map your file columns to OptiFlow contact fields:Your File Column → OptiFlow Field
- “Customer Name” → Name
- “Tax ID” → Identification Number
- “Email Address” → Email
- etc.
ContactImport::getAvailableFields():- name
- commercial_name
- phone
- mobile
- identification_type
- identification_number
- contact_type
- address
- city
- state
- postal_code
- country
Validate Data
Review validation results:
- ✅ Valid rows (will be imported)
- ⚠️ Warnings (will import with caution)
- ❌ Errors (will be skipped)
- Missing required fields (name)
- Invalid email formats
- Duplicate identification numbers
ValidateContactImportDataActionProcess Import
Click Import ContactsSystem processes:
- Validates each row
- Checks for duplicates
- Creates contact records
- Creates addresses
- Generates import summary
ProcessContactImportAction::handle()Duplicate Detection
When importing, the system checks for duplicates based on:- Identification number (if provided)
- Email address
- Exact name match
- Skip duplicates
- Update existing contacts
- Create anyway (with warning)
CheckContactDuplicatesController provides duplicate checking
Contact Search
Efficient contact search throughout OptiFlow:Search Locations
- Contact List Page: Full-text search with filters
- Invoice/Quotation Creation: Customer search dropdown
- Quick Search: Global search bar
Search Criteria
Contacts can be found by:- Name (partial match)
- Commercial name
- Identification number
- Phone number
Search Filters
On contact list page:- Contact type (Customer/Supplier/Both)
- Active/Inactive status
- Tags or categories
- Date created
Deleting Contacts
Click Delete
Click Delete Contact buttonReference:
ContactController::destroy() - requires contacts:delete permissionConfirm Deletion
System checks if contact can be deleted:Cannot delete if:
- Contact has invoices
- Contact has quotations
- Contact has payments
- Contact has other related records
- Mark as inactive instead of deleting
- Or remove as a “soft delete” (if configured)
DeleteContactAction::handle()Best Practices
Common Scenarios
Scenario: Family Group Management
Situation: Optometry clinic with family patientsScenario: Corporate Account
Situation: Business with multiple departments or contactsTroubleshooting
Cannot Create Contact - Duplicate Error
Problem: “A contact with this identification number already exists” Solution:- Search for existing contact
- Update existing contact instead
- Or use different identification type if legitimately different entity
Contact Not Appearing in Search
Problem: Contact exists but doesn’t show in invoice customer search Cause: Contact type is set to “Supplier” only Solution:- Edit the contact
- Change type to “Customer” or “Both”
Related Invoices Not Showing
Problem: Invoice was created but doesn’t appear on contact detail page Investigation:- Check if invoice was created for a related contact instead
- Verify invoice is in the current workspace