Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/luisscruza/optiflow/llms.txt

Use this file to discover all available pages before exploring further.

Contacts are central to OptiFlow, representing customers, suppliers, and other business relationships. Proper contact management ensures smooth invoicing, quotations, and reporting.

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:
TypeCodeUsage
CustomercustomerEntities you sell to
SuppliersupplierEntities you buy from
BothbothEntities you both buy from and sell to
Reference: ContactType enum in app/Enums/ContactType.php

Creating a Contact

1

Navigate to Contacts

Go to ContactsCreate ContactReference: ContactController::create() in app/Http/Controllers/ContactController.php:42Requires contacts:create permission.
2

Enter Basic Information

Required Fields:
  • Name: Contact’s full name or business name
  • Contact Type: Customer, Supplier, or Both
Optional Fields:
  • Commercial Name: Trading name (if different from legal name)
  • Email: Primary email address
  • Phone: Primary phone number
  • Mobile: Mobile phone number
  • Website: Company website
// Available contact types loaded in the form
'contact_types' => collect(ContactType::cases())
    ->map(fn ($type) => [
        'value' => $type->value,
        'label' => $type->label(),
    ]);
3

Add Identification

Configure identification documents:Identification Type: Select from:
  • RNC (Registro Nacional de Contribuyentes) - Tax ID
  • Cédula - National ID card
  • Pasaporte - Passport
  • Other identification types
Identification Number: Enter the ID number
For Dominican Republic businesses, RNC is mandatory for proper tax compliance and invoice generation.
Reference: IdentificationType enum defines available ID types
'identification_types' => collect(IdentificationType::cases())
    ->map(fn ($type) => [
        'value' => $type->value,
        'label' => $type->label(),
    ]);
4

Add Address Information

Primary Address (Optional but recommended):
  • Street address
  • City
  • State/Province
  • Postal code
  • Country
The primary address is used for:
  • Invoice billing address
  • Delivery address (default)
  • Correspondence
You can add multiple addresses per contact. The first address created becomes the primary address.
5

Configure Relationships

Link this contact to related contacts:Use Cases:
  • Family members (parent, child, spouse)
  • Business partners
  • Subsidiaries
  • Alternative contacts
To Add Relationship:
  1. Search for existing contact
  2. Select relationship type or add description
  3. Add to relationships list
Benefits:
  • View consolidated activity across related contacts
  • Track family/group purchasing patterns
  • Share notes and history
Reference: Contact relationships are many-to-many with descriptions
// From ContactController::show()
$contactIds = $contact->relatedContactIdsWithSelf();

// Invoices query includes related contacts
$invoices = Invoice::query()
    ->whereIn('contact_id', $contactIds)
    ->get();
6

Save Contact

Click Create ContactThe system:
  1. Validates required fields
  2. Checks for potential duplicates (optional)
  3. Creates contact record
  4. Creates primary address (if provided)
  5. Establishes relationships
  6. Redirects to contact detail page
Reference: CreateContactAction::handle() in app/Actions/CreateContactAction.php

Contact Information Fields

Complete Field List

Identity:
  • Name (required)
  • Commercial name
  • Identification type
  • Identification number
Communication:
  • Email
  • Phone
  • Mobile
  • Website
Classification:
  • Contact type (Customer/Supplier/Both)
  • Tags or categories (if configured)
Address:
  • Multiple addresses supported
  • Primary address designation
  • Full address components
Relationships:
  • Related contacts with descriptions
  • Bidirectional relationships
Financial:
  • Credit limit (optional)
  • Payment terms preference
  • Tax classification

Viewing Contact Details

1

Navigate to Contact

Go to Contacts → Select a contact from the listReference: ContactController::show() in app/Http/Controllers/ContactController.php:82
2

Overview Tab

View contact summary:
  • Basic information
  • Primary address
  • Recent activity
  • Quick statistics
Statistics Shown:
$stats = [
    'total_invoices' => (clone $invoiceQuery)->count(),
    'total_quotations' => (clone $quotationQuery)->count(),
    'total_invoiced' => (clone $invoiceQuery)->sum('total_amount'),
    'total_paid' => /* sum of payments */,
    'pending_amount' => /* outstanding balance */,
];
3

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)
Limited to 10 most recent, with link to see all.
4

Quotations Tab

View all quotations:
  • Quotation number and date
  • Status (Pending, Approved, Converted)
  • Total quoted amount
  • Actions (view, convert to invoice)
5

Activity Tab

Complete activity log:
  • Contact changes
  • Invoice created/paid
  • Quotations sent
  • Payments received
  • Notes added
  • User who performed action
  • Timestamp
6

Comments Tab

Internal notes and comments:
  • Add notes about the contact
  • Communication history
  • Special instructions
  • Threaded discussions
Reference: Contact implements Commentable interface using HasComments trait

Editing Contacts

1

Open Contact Editor

From contact detail page, click Edit ContactReference: ContactController::edit() in app/Http/Controllers/ContactController.php:170Requires contacts:edit permission.
2

Modify Information

Update any contact fields:
  • Basic information
  • Contact type
  • Identification
  • Addresses
  • Relationships
Changing a contact’s identification number may affect tax reporting and compliance. Ensure the change is legitimate and properly documented.
3

Save Changes

Click Update ContactChanges are tracked in the activity log with:
  • Fields changed
  • Old and new values
  • User who made the change
  • Timestamp
Reference: UpdateContactAction::handle()

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

  1. Consolidated Reporting: View all invoices and quotations for a family or group
  2. Shared History: See complete interaction history
  3. Cross-References: Easy navigation between related contacts

Adding Relationships

1

Edit Contact

Navigate to contact and click Edit
2

Search for Related Contact

Use the relationship search field:
  • Type contact name or ID
  • Select from results
  • Contact cannot be related to itself
// Search excludes the current contact
$contactSearch->searchActive(
    (string) $request->string('relationship_search'),
    $contact->id  // Exclude this contact from results
);
3

Add Description

Describe the relationship:
  • “Mother of [contact]”
  • “Alternative phone for [contact]”
  • “Partner”
4

Save

Relationship is bidirectional - appears on both contacts

Importing Contacts

Bulk import contacts from Excel or CSV files.
1

Navigate to Import

Go to ContactsImport ContactsReference: ContactImportController in app/Http/Controllers/ContactImportController.php
2

Upload File

Supported formats:
  • Excel (.xlsx, .xls)
  • CSV (.csv)
Requirements:
  • First row should contain headers
  • At minimum, include contact names
Reference: CreateContactImportAction parses file using ParseExcelFileAction or ParseCsvFileAction
3

Map Columns

Map your file columns to OptiFlow contact fields:Your File ColumnOptiFlow Field
  • “Customer Name” → Name
  • “Tax ID” → Identification Number
  • “Email Address” → Email
  • etc.
Available fields from ContactImport::getAvailableFields():
  • name
  • commercial_name
  • email
  • phone
  • mobile
  • identification_type
  • identification_number
  • contact_type
  • address
  • city
  • state
  • postal_code
  • country
// Preview data shown for verification
'previewData' => array_slice($contactImport->import_data ?? [], 0, 5)
4

Validate Data

Review validation results:
  • ✅ Valid rows (will be imported)
  • ⚠️ Warnings (will import with caution)
  • ❌ Errors (will be skipped)
Common issues:
  • Missing required fields (name)
  • Invalid email formats
  • Duplicate identification numbers
Reference: ValidateContactImportDataAction
5

Process Import

Click Import ContactsSystem processes:
  1. Validates each row
  2. Checks for duplicates
  3. Creates contact records
  4. Creates addresses
  5. Generates import summary
Reference: ProcessContactImportAction::handle()
6

Review Results

Import summary shows:
  • Total rows processed
  • Successfully imported
  • Skipped (with reasons)
  • Duplicates detected
  • Link to imported contacts

Duplicate Detection

When importing, the system checks for duplicates based on:
  • Identification number (if provided)
  • Email address
  • Exact name match
Duplicate handling options:
  • Skip duplicates
  • Update existing contacts
  • Create anyway (with warning)
Reference: CheckContactDuplicatesController provides duplicate checking Efficient contact search throughout OptiFlow:

Search Locations

  1. Contact List Page: Full-text search with filters
  2. Invoice/Quotation Creation: Customer search dropdown
  3. Quick Search: Global search bar

Search Criteria

Contacts can be found by:
  • Name (partial match)
  • Commercial name
  • Identification number
  • Email
  • Phone number
// ContactSearch::searchCustomers() implementation
public function searchCustomers(string $query): array
{
    return Contact::query()
        ->where(function ($q) use ($query) {
            $q->where('name', 'like', "%{$query}%")
              ->orWhere('identification_number', 'like', "%{$query}%")
              ->orWhere('email', 'like', "%{$query}%")
              ->orWhere('phone', 'like', "%{$query}%");
        })
        ->whereIn('type', ['customer', 'both'])
        ->limit(20)
        ->get()
        ->map(fn ($contact) => $this->toOption($contact))
        ->toArray();
}

Search Filters

On contact list page:
  • Contact type (Customer/Supplier/Both)
  • Active/Inactive status
  • Tags or categories
  • Date created

Deleting Contacts

1

Navigate to Contact

Open the contact you want to delete
2

Click Delete

Click Delete Contact buttonReference: ContactController::destroy() - requires contacts:delete permission
3

Confirm 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
Solution for contacts with records:
  • Mark as inactive instead of deleting
  • Or remove as a “soft delete” (if configured)
Reference: DeleteContactAction::handle()
Deleting contacts is permanent and cannot be undone. For contacts with transaction history, consider marking them as inactive instead.

Best Practices

Complete Contact Information: Fill in as much information as possible. Complete contact records improve reporting and customer service.
Use Relationships: Link family members and related businesses to track group purchasing and provide better service.
Regular Cleanup: Periodically review and merge duplicate contacts, update outdated information.
Categorize Contacts: Use consistent contact types and tags for better segmentation and reporting.
Document Interactions: Use comments to record important customer conversations, preferences, and special instructions.

Common Scenarios

Scenario: Family Group Management

Situation: Optometry clinic with family patients
1

Create Primary Contact

Create contact for head of household
2

Create Family Members

Create individual contacts for spouse and children
3

Link Relationships

Add relationships:
  • Spouse relationship
  • Parent-child relationships
4

View Consolidated

From any family member, view complete family history of invoices and quotations

Scenario: Corporate Account

Situation: Business with multiple departments or contacts
1

Create Company Contact

Main business entity with RNC
2

Create Department Contacts

Individual contacts for departments (if needed)
3

Link as Subsidiaries

Relationship: “Department of [Company]“

Troubleshooting

Cannot Create Contact - Duplicate Error

Problem: “A contact with this identification number already exists” Solution:
  1. Search for existing contact
  2. Update existing contact instead
  3. Or use different identification type if legitimately different entity
Problem: Contact exists but doesn’t show in invoice customer search Cause: Contact type is set to “Supplier” only Solution:
  1. Edit the contact
  2. Change type to “Customer” or “Both”
Problem: Invoice was created but doesn’t appear on contact detail page Investigation:
  1. Check if invoice was created for a related contact instead
  2. Verify invoice is in the current workspace

Build docs developers (and LLMs) love