Files
hub/app/Http/Controllers/Seller/Crm/AccountController.php
kelly 11c67f491c feat: MySQL data import and parallel test fixes
- Import Cannabrands data from MySQL to PostgreSQL (strains, categories,
  companies, locations, contacts, products, images, invoices)
- Make migrations idempotent for parallel test execution
- Add ParallelTesting setup for separate test databases per process
- Update product type constraint for imported data
- Keep MysqlImport seeders for reference (data already in PG)
2025-12-04 19:26:38 -07:00

180 lines
5.4 KiB
PHP

<?php
namespace App\Http\Controllers\Seller\Crm;
use App\Http\Controllers\Controller;
use App\Models\Activity;
use App\Models\Business;
use App\Models\Crm\CrmEvent;
use App\Models\Crm\CrmTask;
use App\Models\SalesOpportunity;
use App\Models\SendMenuLog;
use Illuminate\Http\Request;
class AccountController extends Controller
{
/**
* Display accounts listing
*/
public function index(Request $request, Business $business)
{
$accounts = Business::where('type', 'buyer')
->where('status', 'approved')
->with(['contacts'])
->orderBy('name')
->paginate(25);
return view('seller.crm.accounts.index', compact('business', 'accounts'));
}
/**
* Show account details
*/
public function show(Request $request, Business $business, Business $account)
{
$account->load(['contacts']);
// Get orders for this account from this seller
$orders = $account->orders()
->whereHas('items.product.brand', function ($q) use ($business) {
$q->where('business_id', $business->id);
})
->latest()
->limit(10)
->get();
// Get opportunities for this account from this seller
// SalesOpportunity uses business_id for the buyer
$opportunities = SalesOpportunity::where('seller_business_id', $business->id)
->where('business_id', $account->id)
->with(['stage', 'brand'])
->latest()
->get();
// Get tasks related to this account
// CrmTask uses business_id for the buyer
$tasks = CrmTask::where('seller_business_id', $business->id)
->where('business_id', $account->id)
->whereNull('completed_at')
->with('assignee')
->orderBy('due_at')
->limit(5)
->get();
// Get conversation events for this account
$conversationEvents = CrmEvent::where('seller_business_id', $business->id)
->where('buyer_business_id', $account->id)
->latest('occurred_at')
->limit(20)
->get();
// Get menu send history for this account
$sendHistory = SendMenuLog::where('business_id', $business->id)
->where('customer_id', $account->id)
->with(['menu', 'brand'])
->latest('sent_at')
->limit(10)
->get();
// Get activity log for this account
$activities = Activity::where('seller_business_id', $business->id)
->where('business_id', $account->id)
->with(['causer'])
->latest()
->limit(20)
->get();
// Compute stats for this account (orders from this seller)
$ordersQuery = $account->orders()
->whereHas('items.product.brand', function ($q) use ($business) {
$q->where('business_id', $business->id);
});
$pipelineValue = $opportunities->where('status', 'open')->sum('value');
$stats = [
'total_orders' => $ordersQuery->count(),
'total_revenue' => $ordersQuery->sum('total') ?? 0,
'open_opportunities' => $opportunities->where('status', 'open')->count(),
'pipeline_value' => $pipelineValue ?? 0,
];
return view('seller.crm.accounts.show', compact(
'business',
'account',
'stats',
'orders',
'opportunities',
'tasks',
'conversationEvents',
'sendHistory',
'activities'
));
}
/**
* Show account contacts
*/
public function contacts(Request $request, Business $business, Business $account)
{
$contacts = $account->contacts()->paginate(25);
return view('seller.crm.accounts.contacts', compact('business', 'account', 'contacts'));
}
/**
* Show account opportunities
*/
public function opportunities(Request $request, Business $business, Business $account)
{
return view('seller.crm.accounts.opportunities', compact('business', 'account'));
}
/**
* Show account orders
*/
public function orders(Request $request, Business $business, Business $account)
{
return view('seller.crm.accounts.orders', compact('business', 'account'));
}
/**
* Show account activity
*/
public function activity(Request $request, Business $business, Business $account)
{
return view('seller.crm.accounts.activity', compact('business', 'account'));
}
/**
* Show account tasks
*/
public function tasks(Request $request, Business $business, Business $account)
{
return view('seller.crm.accounts.tasks', compact('business', 'account'));
}
/**
* Store a note for an account
*/
public function storeNote(Request $request, Business $business, Business $account)
{
$request->validate([
'note' => 'required|string|max:5000',
]);
CrmEvent::log(
sellerBusinessId: $business->id,
eventType: 'note_added',
summary: $request->input('note'),
buyerBusinessId: $account->id,
userId: auth()->id(),
channel: 'system'
);
return redirect()
->route('seller.business.crm.accounts.show', [$business->slug, $account->slug])
->with('success', 'Note added successfully.');
}
}