add: full multi-tenancy control
This commit is contained in:
734
packages/Webkul/Admin/src/Http/Controllers/Lead/LeadController.php
Executable file
734
packages/Webkul/Admin/src/Http/Controllers/Lead/LeadController.php
Executable file
@@ -0,0 +1,734 @@
|
||||
<?php
|
||||
|
||||
namespace Webkul\Admin\Http\Controllers\Lead;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
|
||||
use Illuminate\Support\Facades\Event;
|
||||
use Illuminate\Support\Facades\Validator;
|
||||
use Illuminate\View\View;
|
||||
use Prettus\Repository\Criteria\RequestCriteria;
|
||||
use Webkul\Admin\DataGrids\Lead\LeadDataGrid;
|
||||
use Webkul\Admin\Http\Controllers\Controller;
|
||||
use Webkul\Admin\Http\Requests\LeadForm;
|
||||
use Webkul\Admin\Http\Requests\MassDestroyRequest;
|
||||
use Webkul\Admin\Http\Requests\MassUpdateRequest;
|
||||
use Webkul\Admin\Http\Resources\LeadResource;
|
||||
use Webkul\Admin\Http\Resources\StageResource;
|
||||
use Webkul\Attribute\Repositories\AttributeRepository;
|
||||
use Webkul\Contact\Repositories\PersonRepository;
|
||||
use Webkul\Lead\Helpers\MagicAI;
|
||||
use Webkul\Lead\Repositories\LeadRepository;
|
||||
use Webkul\Lead\Repositories\PipelineRepository;
|
||||
use Webkul\Lead\Repositories\ProductRepository;
|
||||
use Webkul\Lead\Repositories\SourceRepository;
|
||||
use Webkul\Lead\Repositories\StageRepository;
|
||||
use Webkul\Lead\Repositories\TypeRepository;
|
||||
use Webkul\Lead\Services\MagicAIService;
|
||||
use Webkul\Tag\Repositories\TagRepository;
|
||||
use Webkul\User\Repositories\UserRepository;
|
||||
|
||||
class LeadController extends Controller
|
||||
{
|
||||
/**
|
||||
* Const variable for supported types.
|
||||
*/
|
||||
const SUPPORTED_TYPES = 'pdf,bmp,jpeg,jpg,png,webp';
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(
|
||||
protected UserRepository $userRepository,
|
||||
protected AttributeRepository $attributeRepository,
|
||||
protected SourceRepository $sourceRepository,
|
||||
protected TypeRepository $typeRepository,
|
||||
protected PipelineRepository $pipelineRepository,
|
||||
protected StageRepository $stageRepository,
|
||||
protected LeadRepository $leadRepository,
|
||||
protected ProductRepository $productRepository,
|
||||
protected PersonRepository $personRepository
|
||||
) {
|
||||
request()->request->add(['entity_type' => 'leads']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
if (request()->ajax()) {
|
||||
return datagrid(LeadDataGrid::class)->process();
|
||||
}
|
||||
|
||||
if (request('pipeline_id')) {
|
||||
$pipeline = $this->pipelineRepository->find(request('pipeline_id'));
|
||||
} else {
|
||||
$pipeline = $this->pipelineRepository->getDefaultPipeline();
|
||||
}
|
||||
|
||||
return view('admin::leads.index', [
|
||||
'pipeline' => $pipeline,
|
||||
'columns' => $this->getKanbanColumns(),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a listing of the resource.
|
||||
*/
|
||||
public function get(): JsonResponse
|
||||
{
|
||||
if (request()->query('pipeline_id')) {
|
||||
$pipeline = $this->pipelineRepository->find(request()->query('pipeline_id'));
|
||||
} else {
|
||||
$pipeline = $this->pipelineRepository->getDefaultPipeline();
|
||||
}
|
||||
|
||||
if ($stageId = request()->query('pipeline_stage_id')) {
|
||||
$stages = $pipeline->stages->where('id', request()->query('pipeline_stage_id'));
|
||||
} else {
|
||||
$stages = $pipeline->stages;
|
||||
}
|
||||
|
||||
foreach ($stages as $stage) {
|
||||
/**
|
||||
* We have to create a new instance of the lead repository every time, which is
|
||||
* why we're not using the injected one.
|
||||
*/
|
||||
$query = app(LeadRepository::class)
|
||||
->pushCriteria(app(RequestCriteria::class))
|
||||
->where([
|
||||
'lead_pipeline_id' => $pipeline->id,
|
||||
'lead_pipeline_stage_id' => $stage->id,
|
||||
]);
|
||||
|
||||
if ($userIds = bouncer()->getAuthorizedUserIds()) {
|
||||
$query->whereIn('leads.user_id', $userIds);
|
||||
}
|
||||
|
||||
$stage->lead_value = (clone $query)->sum('lead_value');
|
||||
|
||||
$data[$stage->sort_order] = (new StageResource($stage))->jsonSerialize();
|
||||
|
||||
$data[$stage->sort_order]['leads'] = [
|
||||
'data' => LeadResource::collection($paginator = $query->with([
|
||||
'tags',
|
||||
'type',
|
||||
'source',
|
||||
'user',
|
||||
'person',
|
||||
'person.organization',
|
||||
'pipeline',
|
||||
'pipeline.stages',
|
||||
'stage',
|
||||
'attribute_values',
|
||||
])->paginate(10)),
|
||||
|
||||
'meta' => [
|
||||
'current_page' => $paginator->currentPage(),
|
||||
'from' => $paginator->firstItem(),
|
||||
'last_page' => $paginator->lastPage(),
|
||||
'per_page' => $paginator->perPage(),
|
||||
'to' => $paginator->lastItem(),
|
||||
'total' => $paginator->total(),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return response()->json($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create(): View
|
||||
{
|
||||
return view('admin::leads.create');
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(LeadForm $request): RedirectResponse|JsonResponse
|
||||
{
|
||||
Event::dispatch('lead.create.before');
|
||||
|
||||
$data = request()->all();
|
||||
|
||||
$data['status'] = 1;
|
||||
|
||||
if (! empty($data['lead_pipeline_stage_id'])) {
|
||||
$stage = $this->stageRepository->findOrFail($data['lead_pipeline_stage_id']);
|
||||
|
||||
$data['lead_pipeline_id'] = $stage->lead_pipeline_id;
|
||||
} else {
|
||||
if (empty($data['lead_pipeline_id'])) {
|
||||
$pipeline = $this->pipelineRepository->getDefaultPipeline();
|
||||
|
||||
$data['lead_pipeline_id'] = $pipeline->id;
|
||||
} else {
|
||||
$pipeline = $this->pipelineRepository->findOrFail($data['lead_pipeline_id']);
|
||||
}
|
||||
|
||||
$stage = $pipeline->stages()->first();
|
||||
|
||||
$data['lead_pipeline_stage_id'] = $stage->id;
|
||||
}
|
||||
|
||||
if (in_array($stage->code, ['won', 'lost'])) {
|
||||
$data['closed_at'] = Carbon::now();
|
||||
}
|
||||
|
||||
$lead = $this->leadRepository->create($data);
|
||||
|
||||
if (request()->ajax()) {
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.create-success'),
|
||||
'data' => new LeadResource($lead),
|
||||
]);
|
||||
}
|
||||
|
||||
Event::dispatch('lead.create.after', $lead);
|
||||
|
||||
session()->flash('success', trans('admin::app.leads.create-success'));
|
||||
|
||||
if (! empty($data['lead_pipeline_id'])) {
|
||||
$params['pipeline_id'] = $data['lead_pipeline_id'];
|
||||
}
|
||||
|
||||
return redirect()->route('admin.leads.index', $params ?? []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(int $id): View
|
||||
{
|
||||
$lead = $this->leadRepository->findOrFail($id);
|
||||
|
||||
return view('admin::leads.edit', compact('lead'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a resource.
|
||||
*/
|
||||
public function view(int $id)
|
||||
{
|
||||
$lead = $this->leadRepository->findOrFail($id);
|
||||
|
||||
$userIds = bouncer()->getAuthorizedUserIds();
|
||||
|
||||
if (
|
||||
$userIds
|
||||
&& ! in_array($lead->user_id, $userIds)
|
||||
) {
|
||||
return redirect()->route('admin.leads.index');
|
||||
}
|
||||
|
||||
return view('admin::leads.view', compact('lead'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(LeadForm $request, int $id): RedirectResponse|JsonResponse
|
||||
{
|
||||
Event::dispatch('lead.update.before', $id);
|
||||
|
||||
$data = $request->all();
|
||||
|
||||
if (isset($data['lead_pipeline_stage_id'])) {
|
||||
$stage = $this->stageRepository->findOrFail($data['lead_pipeline_stage_id']);
|
||||
|
||||
$data['lead_pipeline_id'] = $stage->lead_pipeline_id;
|
||||
} else {
|
||||
$pipeline = $this->pipelineRepository->getDefaultPipeline();
|
||||
|
||||
$stage = $pipeline->stages()->first();
|
||||
|
||||
$data['lead_pipeline_id'] = $pipeline->id;
|
||||
|
||||
$data['lead_pipeline_stage_id'] = $stage->id;
|
||||
}
|
||||
|
||||
$lead = $this->leadRepository->update($data, $id);
|
||||
|
||||
Event::dispatch('lead.update.after', $lead);
|
||||
|
||||
if (request()->ajax()) {
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.update-success'),
|
||||
]);
|
||||
}
|
||||
|
||||
session()->flash('success', trans('admin::app.leads.update-success'));
|
||||
|
||||
if (request()->has('closed_at')) {
|
||||
return redirect()->back();
|
||||
} else {
|
||||
return redirect()->route('admin.leads.index', $data['lead_pipeline_id']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the lead attributes.
|
||||
*/
|
||||
public function updateAttributes(int $id)
|
||||
{
|
||||
$data = request()->all();
|
||||
|
||||
$attributes = $this->attributeRepository->findWhere([
|
||||
'entity_type' => 'leads',
|
||||
['code', 'NOTIN', ['title', 'description']],
|
||||
]);
|
||||
|
||||
Event::dispatch('lead.update.before', $id);
|
||||
|
||||
$lead = $this->leadRepository->update($data, $id, $attributes);
|
||||
|
||||
Event::dispatch('lead.update.after', $lead);
|
||||
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.update-success'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the lead stage.
|
||||
*/
|
||||
public function updateStage(int $id)
|
||||
{
|
||||
$this->validate(request(), [
|
||||
'lead_pipeline_stage_id' => 'required',
|
||||
]);
|
||||
|
||||
$lead = $this->leadRepository->findOrFail($id);
|
||||
|
||||
$stage = $lead->pipeline->stages()
|
||||
->where('id', request()->input('lead_pipeline_stage_id'))
|
||||
->firstOrFail();
|
||||
|
||||
Event::dispatch('lead.update.before', $id);
|
||||
|
||||
$payload = request()->merge([
|
||||
'entity_type' => 'leads',
|
||||
'lead_pipeline_stage_id' => $stage->id,
|
||||
])->only([
|
||||
'closed_at',
|
||||
'lost_reason',
|
||||
'lead_pipeline_stage_id',
|
||||
'entity_type',
|
||||
]);
|
||||
|
||||
$lead = $this->leadRepository->update($payload, $id, ['lead_pipeline_stage_id']);
|
||||
|
||||
Event::dispatch('lead.update.after', $lead);
|
||||
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.update-success'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Search person results.
|
||||
*/
|
||||
public function search(): AnonymousResourceCollection
|
||||
{
|
||||
if ($userIds = bouncer()->getAuthorizedUserIds()) {
|
||||
$results = $this->leadRepository
|
||||
->pushCriteria(app(RequestCriteria::class))
|
||||
->findWhereIn('user_id', $userIds);
|
||||
} else {
|
||||
$results = $this->leadRepository
|
||||
->pushCriteria(app(RequestCriteria::class))
|
||||
->all();
|
||||
}
|
||||
|
||||
return LeadResource::collection($results);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(int $id): JsonResponse
|
||||
{
|
||||
$this->leadRepository->findOrFail($id);
|
||||
|
||||
try {
|
||||
Event::dispatch('lead.delete.before', $id);
|
||||
|
||||
$this->leadRepository->delete($id);
|
||||
|
||||
Event::dispatch('lead.delete.after', $id);
|
||||
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.destroy-success'),
|
||||
]);
|
||||
} catch (\Exception $exception) {
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.destroy-failed'),
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mass update the specified resources.
|
||||
*/
|
||||
public function massUpdate(MassUpdateRequest $massUpdateRequest): JsonResponse
|
||||
{
|
||||
$leads = $this->leadRepository->findWhereIn('id', $massUpdateRequest->input('indices'));
|
||||
|
||||
try {
|
||||
foreach ($leads as $lead) {
|
||||
Event::dispatch('lead.update.before', $lead->id);
|
||||
|
||||
$lead = $this->leadRepository->find($lead->id);
|
||||
|
||||
$lead?->update(['lead_pipeline_stage_id' => $massUpdateRequest->input('value')]);
|
||||
|
||||
Event::dispatch('lead.update.before', $lead->id);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.update-success'),
|
||||
]);
|
||||
} catch (\Exception $th) {
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.update-failed'),
|
||||
], 400);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mass delete the specified resources.
|
||||
*/
|
||||
public function massDestroy(MassDestroyRequest $massDestroyRequest): JsonResponse
|
||||
{
|
||||
$leads = $this->leadRepository->findWhereIn('id', $massDestroyRequest->input('indices'));
|
||||
|
||||
try {
|
||||
foreach ($leads as $lead) {
|
||||
Event::dispatch('lead.delete.before', $lead->id);
|
||||
|
||||
$this->leadRepository->delete($lead->id);
|
||||
|
||||
Event::dispatch('lead.delete.after', $lead->id);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.destroy-success'),
|
||||
]);
|
||||
} catch (\Exception $exception) {
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.destroy-failed'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach product to lead.
|
||||
*/
|
||||
public function addProduct(int $leadId): JsonResponse
|
||||
{
|
||||
$product = $this->productRepository->updateOrCreate(
|
||||
[
|
||||
'lead_id' => $leadId,
|
||||
'product_id' => request()->input('product_id'),
|
||||
],
|
||||
array_merge(
|
||||
request()->all(),
|
||||
[
|
||||
'lead_id' => $leadId,
|
||||
'amount' => request()->input('price') * request()->input('quantity'),
|
||||
],
|
||||
)
|
||||
);
|
||||
|
||||
return response()->json([
|
||||
'data' => $product,
|
||||
'message' => trans('admin::app.leads.update-success'),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove product attached to lead.
|
||||
*/
|
||||
public function removeProduct(int $id): JsonResponse
|
||||
{
|
||||
try {
|
||||
Event::dispatch('lead.product.delete.before', $id);
|
||||
|
||||
$this->productRepository->deleteWhere([
|
||||
'lead_id' => $id,
|
||||
'product_id' => request()->input('product_id'),
|
||||
]);
|
||||
|
||||
Event::dispatch('lead.product.delete.after', $id);
|
||||
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.destroy-success'),
|
||||
]);
|
||||
} catch (\Exception $exception) {
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.destroy-failed'),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Kanban lookup.
|
||||
*/
|
||||
public function kanbanLookup()
|
||||
{
|
||||
$params = $this->validate(request(), [
|
||||
'column' => ['required'],
|
||||
'search' => ['required', 'min:2'],
|
||||
]);
|
||||
|
||||
/**
|
||||
* Finding the first column from the collection.
|
||||
*/
|
||||
$column = collect($this->getKanbanColumns())->where('index', $params['column'])->firstOrFail();
|
||||
|
||||
/**
|
||||
* Fetching on the basis of column options.
|
||||
*/
|
||||
return app($column['filterable_options']['repository'])
|
||||
->select([$column['filterable_options']['column']['label'].' as label', $column['filterable_options']['column']['value'].' as value'])
|
||||
->where($column['filterable_options']['column']['label'], 'LIKE', '%'.$params['search'].'%')
|
||||
->get()
|
||||
->map
|
||||
->only('label', 'value');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get columns for the kanban view.
|
||||
*/
|
||||
private function getKanbanColumns(): array
|
||||
{
|
||||
return [
|
||||
[
|
||||
'index' => 'id',
|
||||
'label' => trans('admin::app.leads.index.kanban.columns.id'),
|
||||
'type' => 'integer',
|
||||
'searchable' => false,
|
||||
'search_field' => 'in',
|
||||
'filterable' => true,
|
||||
'filterable_type' => null,
|
||||
'filterable_options' => [],
|
||||
'allow_multiple_values' => true,
|
||||
'sortable' => true,
|
||||
'visibility' => true,
|
||||
],
|
||||
[
|
||||
'index' => 'lead_value',
|
||||
'label' => trans('admin::app.leads.index.kanban.columns.lead-value'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'search_field' => 'in',
|
||||
'filterable' => true,
|
||||
'filterable_type' => null,
|
||||
'filterable_options' => [],
|
||||
'allow_multiple_values' => true,
|
||||
'sortable' => true,
|
||||
'visibility' => true,
|
||||
],
|
||||
[
|
||||
'index' => 'user_id',
|
||||
'label' => trans('admin::app.leads.index.kanban.columns.sales-person'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'search_field' => 'in',
|
||||
'filterable' => true,
|
||||
'filterable_type' => 'searchable_dropdown',
|
||||
'filterable_options' => [
|
||||
'repository' => UserRepository::class,
|
||||
'column' => [
|
||||
'label' => 'name',
|
||||
'value' => 'id',
|
||||
],
|
||||
],
|
||||
'allow_multiple_values' => true,
|
||||
'sortable' => true,
|
||||
'visibility' => true,
|
||||
],
|
||||
[
|
||||
'index' => 'person.id',
|
||||
'label' => trans('admin::app.leads.index.kanban.columns.contact-person'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'search_field' => 'in',
|
||||
'filterable' => true,
|
||||
'filterable_options' => [],
|
||||
'allow_multiple_values' => true,
|
||||
'sortable' => true,
|
||||
'visibility' => true,
|
||||
'filterable_type' => 'searchable_dropdown',
|
||||
'filterable_options' => [
|
||||
'repository' => PersonRepository::class,
|
||||
'column' => [
|
||||
'label' => 'name',
|
||||
'value' => 'id',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
'index' => 'lead_type_id',
|
||||
'label' => trans('admin::app.leads.index.kanban.columns.lead-type'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'search_field' => 'in',
|
||||
'filterable' => true,
|
||||
'filterable_type' => 'dropdown',
|
||||
'filterable_options' => $this->typeRepository->all(['name as label', 'id as value'])->toArray(),
|
||||
'allow_multiple_values' => true,
|
||||
'sortable' => true,
|
||||
'visibility' => true,
|
||||
],
|
||||
[
|
||||
'index' => 'lead_source_id',
|
||||
'label' => trans('admin::app.leads.index.kanban.columns.source'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'search_field' => 'in',
|
||||
'filterable' => true,
|
||||
'filterable_type' => 'dropdown',
|
||||
'filterable_options' => $this->sourceRepository->all(['name as label', 'id as value'])->toArray(),
|
||||
'allow_multiple_values' => true,
|
||||
'sortable' => true,
|
||||
'visibility' => true,
|
||||
],
|
||||
[
|
||||
'index' => 'tags.name',
|
||||
'label' => trans('admin::app.leads.index.kanban.columns.tags'),
|
||||
'type' => 'string',
|
||||
'searchable' => false,
|
||||
'search_field' => 'in',
|
||||
'filterable' => true,
|
||||
'filterable_options' => [],
|
||||
'allow_multiple_values' => true,
|
||||
'sortable' => true,
|
||||
'visibility' => true,
|
||||
'filterable_type' => 'searchable_dropdown',
|
||||
'filterable_options' => [
|
||||
'repository' => TagRepository::class,
|
||||
'column' => [
|
||||
'label' => 'name',
|
||||
'value' => 'name',
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Create lead with specified AI.
|
||||
*/
|
||||
public function createByAI()
|
||||
{
|
||||
$leadData = [];
|
||||
|
||||
$errorMessages = [];
|
||||
|
||||
foreach (request()->file('files') as $file) {
|
||||
$lead = $this->processFile($file);
|
||||
|
||||
if (
|
||||
isset($lead['status'])
|
||||
&& $lead['status'] === 'error'
|
||||
) {
|
||||
$errorMessages[] = $lead['message'];
|
||||
} else {
|
||||
$leadData[] = $lead;
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($errorMessages[0]['code'])) {
|
||||
return response()->json(MagicAI::errorHandler($errorMessages[0]['message']));
|
||||
}
|
||||
|
||||
if (
|
||||
empty($leadData)
|
||||
&& ! empty($errorMessages)
|
||||
) {
|
||||
return response()->json(MagicAI::errorHandler(implode(', ', $errorMessages)), 400);
|
||||
}
|
||||
|
||||
if (empty($leadData)) {
|
||||
return response()->json(MagicAI::errorHandler(trans('admin::app.leads.no-valid-files')), 400);
|
||||
}
|
||||
|
||||
return response()->json([
|
||||
'message' => trans('admin::app.leads.create-success'),
|
||||
'leads' => $this->createLeads($leadData),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Process file.
|
||||
*
|
||||
* @param mixed $file
|
||||
*/
|
||||
private function processFile($file)
|
||||
{
|
||||
$validator = Validator::make(
|
||||
['file' => $file],
|
||||
['file' => 'required|extensions:'.str_replace(' ', '', self::SUPPORTED_TYPES)]
|
||||
);
|
||||
|
||||
if ($validator->fails()) {
|
||||
return MagicAI::errorHandler($validator->errors()->first());
|
||||
}
|
||||
|
||||
$base64Pdf = base64_encode(file_get_contents($file->getRealPath()));
|
||||
|
||||
$extractedData = MagicAIService::extractDataFromFile($base64Pdf);
|
||||
|
||||
$lead = MagicAI::mapAIDataToLead($extractedData);
|
||||
|
||||
return $lead;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create multiple leads.
|
||||
*/
|
||||
private function createLeads($rawLeads): array
|
||||
{
|
||||
$leads = [];
|
||||
|
||||
foreach ($rawLeads as $rawLead) {
|
||||
Event::dispatch('lead.create.before');
|
||||
|
||||
foreach ($rawLead['person']['emails'] as $email) {
|
||||
$person = $this->personRepository
|
||||
->whereJsonContains('emails', [['value' => $email['value']]])
|
||||
->first();
|
||||
|
||||
if ($person) {
|
||||
$rawLead['person']['id'] = $person->id;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$pipeline = $this->pipelineRepository->getDefaultPipeline();
|
||||
|
||||
$stage = $pipeline->stages()->first();
|
||||
|
||||
$lead = $this->leadRepository->create(array_merge($rawLead, [
|
||||
'lead_pipeline_id' => $pipeline->id,
|
||||
'lead_pipeline_stage_id' => $stage->id,
|
||||
]));
|
||||
|
||||
Event::dispatch('lead.create.after', $lead);
|
||||
|
||||
$leads[] = $lead;
|
||||
}
|
||||
|
||||
return $leads;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user