commonUtil = $commonUtil;
$this->moduleUtil = $moduleUtil;
$this->crmUtil = $crmUtil;
$this->status_bg = [
'scheduled' => 'bg-yellow',
'open' => 'bg-blue',
'canceled' => 'bg-red',
'cancelled' => 'bg-red',
'completed' => 'bg-green',
];
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
$business_id = request()->session()->get('user.business_id');
$can_access_all_schedule = auth()->user()->can('crm.access_all_schedule');
$can_access_own_schedule = auth()->user()->can('crm.access_own_schedule');
if (!(auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'crm_module')) || !($can_access_all_schedule || $can_access_own_schedule)) {
abort(403, 'Unauthorized action.');
}
if (request()->ajax()) {
$schedules = Schedule::leftjoin('contacts', 'crm_schedules.contact_id', '=', 'contacts.id')
->leftjoin('users as U', 'crm_schedules.created_by', '=', 'U.id')
->leftjoin('categories as C', 'crm_schedules.followup_category_id', '=', 'C.id')
->with(['users'])
->where('crm_schedules.business_id', $business_id)
->select(
'crm_schedules.*',
'contacts.name as contact',
'contacts.supplier_business_name as biz_name',
'U.surname',
'U.first_name',
'U.last_name',
'crm_schedules.status as status',
'crm_schedules.created_at as added_on',
'contacts.type as contact_type',
'contacts.id as contact_id',
'C.name as followup_category'
);
if (request()->input('is_recursive') == 1) {
$schedules->where('crm_schedules.is_recursive', 1);
} else {
$schedules->where('crm_schedules.is_recursive', 0);
}
if (!empty(request()->input('contact_id'))) {
$schedules->where('crm_schedules.contact_id', request()->input('contact_id'));
}
if (!empty(request()->input('assgined_to'))) {
$user_id = request()->input('assgined_to');
$schedules->whereHas('users', function ($q) use ($user_id) {
$q->where('user_id', $user_id);
});
}
if (!empty(request()->input('status'))) {
if (request()->input('status') == 'none') {
$schedules->whereNull('crm_schedules.status');
} else {
$schedules->where('crm_schedules.status', request()->input('status'));
}
}
if (!empty(request()->input('schedule_type'))) {
$schedules->where('crm_schedules.schedule_type', request()->input('schedule_type'));
}
if (!empty(request()->input('followup_category_id'))) {
$schedules->where('crm_schedules.followup_category_id', request()->input('followup_category_id'));
}
if (!empty(request()->input('start_date_time')) && !empty(request()->input('end_date_time'))) {
$start_date = request()->input('start_date_time');
$end_date = request()->input('end_date_time');
$schedules->whereBetween(DB::raw('date(start_datetime)'), [$start_date, $end_date]);
}
if (!empty(request()->input('follow_up_by'))) {
$schedules->where('crm_schedules.follow_up_by', request()->input('follow_up_by'));
}
if (!auth()->user()->can('superadmin') && !$can_access_all_schedule) {
$user_id = auth()->user()->id;
$schedules->whereHas('users', function ($q) use ($user_id) {
$q->where('user_id', $user_id);
});
}
return Datatables::of($schedules)
->addColumn('action', function ($row) {
$html = '
';
return $html;
})
->editColumn('start_datetime', ' @if(!empty($start_datetime))
@format_datetime($start_datetime)
({{$start_datetime}}) @endif
')
->editColumn('end_datetime', '
@if(!empty($end_datetime))@format_datetime($end_datetime) @endif
')
->editColumn('contact', '
@if(!empty($biz_name)) {{$biz_name}},
@endif {{$contact}}
@if($contact_type == "lead")
@else
@endif
')
->addColumn('added_by', function ($row) {
return "{$row->surname} {$row->first_name} {$row->last_name}";
})
->addColumn('additional_info', function ($row) {
$html = '';
$infos = $row->followup_additional_info;
if (!empty($infos)) {
foreach ($infos as $key => $value) {
$html .= $key . ' : ' . $value . '
';
}
}
return $html;
})
->editColumn('added_on', '
@format_datetime($added_on)
')
->editColumn('schedule_type', function ($row) {
$html = '';
if (!empty($row->schedule_type)) {
$html = '
' . __('crm::lang.' . $row->schedule_type) .
'
';
}
return $html;
})
->editColumn('users', function ($row) {
$html = ' ';
if ($row->users->count() > 0) {
foreach ($row->users as $user) {
if (isset($user->media->display_url)) {
$html .= '
';
} else {
$html .= '
';
}
}
}
return $html;
})
->editColumn('status', function ($row) {
$html = '';
if (!empty($row->status)) {
$html = '
' . __('crm::lang.' . $row->status) .
'';
}
return $html;
})
->editColumn('follow_up_by', function ($row) {
$follow_up_by = '';
if ($row->follow_up_by == 'payment_status') {
$follow_up_by = __('sale.payment_status') . ' - ' . __('lang_v1.' . $row->follow_up_by_value);
} elseif ($row->follow_up_by == 'orders') {
$follow_up_by = __('restaurant.orders') . ' - ' . __('crm::lang.has_no_transactions');
}
return $follow_up_by;
})
->removeColumn('id')
->rawColumns([
'action', 'start_datetime', 'end_datetime', 'users', 'contact', 'added_on',
'additional_info', 'schedule_type', 'status', 'description',
])
->make(true);
}
$leads = CrmContact::leadsDropdown($business_id, false);
$contacts = Contact::customersDropdown($business_id, false)->toArray();
foreach ($contacts as $key => $value) {
$contacts[$key] = $value . ' (' . __('contact.customer') . ')';
}
foreach ($leads as $key => $value) {
$contacts[$key] = $value . ' (' . __('crm::lang.lead') . ')';
}
$assigned_to = User::forDropdown($business_id, false);
$statuses = Schedule::statusDropdown(true);
$follow_up_types = Schedule::followUpTypeDropdown();
// Set default user from get parameter
$default_user = request()->input('assigned_to', null);
// Set default status from get parameter
$default_status = request()->input('status', null);
// Set default date from get parameter (Gregorian Y-m-d for filters)
$default_start_date = request()->input('start_date', null);
$default_end_date = request()->input('end_date', null);
$default_date_range_label = null;
if (! empty($default_start_date) && ! empty($default_end_date)) {
$default_date_range_label = $this->commonUtil->format_date($default_start_date)
.' ~ '.$this->commonUtil->format_date($default_end_date);
}
$default_followup_category_id = request()->input('followup_category_id', null);
$followup_category = Category::forDropdown($business_id, 'followup_category');
return view('crm::schedule.index')
->with(compact(
'contacts',
'assigned_to',
'statuses',
'follow_up_types',
'default_start_date',
'default_end_date',
'default_date_range_label',
'default_status',
'default_user',
'followup_category',
'default_followup_category_id'
));
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
$business_id = request()->session()->get('user.business_id');
if (!(auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'crm_module'))) {
abort(403, 'Unauthorized action.');
}
$schedule_for = request()->get('schedule_for', 'customer');
$statuses = Schedule::statusDropdown();
$follow_up_types = Schedule::followUpTypeDropdown();
$notify_type = Schedule::followUpNotifyTypeDropdown();
$followup_tags = $this->crmUtil->getAdvFollowupsTags();
$users = User::forDropdown($business_id, false);
$followup_category = Category::forDropdown($business_id, 'followup_category');
if (request()->has('is_recursive')) {
return view('crm::schedule.create_recursive_follow_up')
->with(compact('statuses', 'follow_up_types', 'notify_type', 'followup_tags', 'users', 'followup_category'));
}
$customers = CrmContact::getCustomerAndLeadsDropdown($business_id);
if (request()->ajax()) {
$contact_id = request()->get('contact_id', '');
return view('crm::schedule.create')
->with(compact('customers', 'users', 'statuses', 'contact_id', 'schedule_for', 'follow_up_types', 'notify_type', 'followup_category'));
}
return view('crm::schedule.create_advance_follow_up')
->with(compact('statuses', 'schedule_for', 'follow_up_types', 'notify_type', 'followup_tags', 'customers', 'followup_category'));
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$business_id = request()->session()->get('user.business_id');
if (!(auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'crm_module'))) {
abort(403, 'Unauthorized action.');
}
try {
$input = $request->except(['_token', 'schedule_for', 'contact_ids']);
if (empty($input['is_recursive'])) {
$input['start_datetime'] = $this->commonUtil->uf_date($input['start_datetime'], true);
$input['end_datetime'] = $this->commonUtil->uf_date($input['end_datetime'], true);
}
DB::beginTransaction();
if (empty($input['follow_ups']) && empty($input['is_recursive'])) {
$this->crmUtil->addFollowUp($input, \Auth::user());
} elseif (!empty($input['is_recursive'])) {
$this->crmUtil->addRecursiveFollowUp($input, \Auth::user());
} else {
$this->crmUtil->addAdvanceFollowUp($input, \Auth::user());
}
DB::commit();
$schedule_for = request()->get('schedule_for', 'customer');
$output = [
'success' => true,
'msg' => __('lang_v1.success'),
'schedule_for' => $schedule_for,
];
} catch (Exception $e) {
DB::rollBack();
\Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
$output = [
'success' => false,
'msg' => __('messages.something_went_wrong'),
];
}
if (request()->ajax()) {
return $output;
} else {
return redirect()->action([\Modules\Crm\Http\Controllers\ScheduleController::class, 'index'])->with(['status' => $output]);
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$business_id = request()->session()->get('user.business_id');
$can_access_all_schedule = auth()->user()->can('crm.access_all_schedule');
$can_access_own_schedule = auth()->user()->can('crm.access_own_schedule');
if (!(auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'crm_module')) || !($can_access_all_schedule || $can_access_own_schedule)) {
abort(403, 'Unauthorized action.');
}
$query = Schedule::with(['customer', 'users', 'invoices', 'invoices.payment_lines'])
->where('business_id', $business_id);
if (! $can_access_all_schedule && $can_access_own_schedule) {
$query->where(function ($qry) {
$qry->whereHas('users', function ($q) {
$q->where('user_id', auth()->user()->id);
})->orWhere('created_by', auth()->user()->id);
});
}
$schedule = $query->findOrFail($id);
return view('crm::schedule.show')
->with(compact('schedule'));
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
$business_id = request()->session()->get('user.business_id');
$can_access_all_schedule = auth()->user()->can('crm.access_all_schedule');
$can_access_own_schedule = auth()->user()->can('crm.access_own_schedule');
if (!(auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'crm_module')) || !($can_access_all_schedule || $can_access_own_schedule)) {
abort(403, 'Unauthorized action.');
}
$query = Schedule::with(['customer', 'users'])
->where('business_id', $business_id);
if (!$can_access_all_schedule && $can_access_own_schedule) {
$query->where(function ($qry) {
$qry->whereHas('users', function ($q) {
$q->where('user_id', auth()->user()->id);
})->orWhere('created_by', auth()->user()->id);
});
}
$schedule = $query->findOrFail($id);
$schedule_for = request()->get('schedule_for', 'customer');
$leads = CrmContact::leadsDropdown($business_id, false, false);
$customers = Contact::customersDropdown($business_id, false, false)->toArray();
$followup_category = Category::forDropdown($business_id, 'followup_category');
foreach ($customers as $key => $value) {
$customers[$key] = $value . ' (' . __('contact.customer') . ')';
}
foreach ($leads as $key => $value) {
$customers[$key] = $value . ' (' . __('crm::lang.lead') . ')';
}
$users = User::forDropdown($business_id, false);
$statuses = Schedule::statusDropdown();
$follow_up_types = Schedule::followUpTypeDropdown();
$notify_type = Schedule::followUpNotifyTypeDropdown();
return view('crm::schedule.edit')
->with(compact('schedule', 'customers', 'users', 'statuses', 'schedule_for', 'follow_up_types', 'notify_type', 'followup_category'));
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
$business_id = request()->session()->get('user.business_id');
$can_access_all_schedule = auth()->user()->can('crm.access_all_schedule');
$can_access_own_schedule = auth()->user()->can('crm.access_own_schedule');
if (!(auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'crm_module')) || !($can_access_all_schedule || $can_access_own_schedule)) {
abort(403, 'Unauthorized action.');
}
try {
$request = $request->except(['_method', '_token', 'schedule_for']);
$request['start_datetime'] = $this->commonUtil->uf_date($request['start_datetime'], true);
$request['end_datetime'] = $this->commonUtil->uf_date($request['end_datetime'], true);
$this->crmUtil->updateFollowUp($id, $request, \Auth::user());
$schedule_for = request()->get('schedule_for', 'customer');
$output = [
'success' => true,
'msg' => __('lang_v1.success'),
'schedule_for' => $schedule_for,
];
} catch (Exception $e) {
\Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
$output = [
'success' => false,
'msg' => __('messages.something_went_wrong'),
];
}
return $output;
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
$business_id = request()->session()->get('user.business_id');
$can_access_all_schedule = auth()->user()->can('crm.access_all_schedule');
$can_access_own_schedule = auth()->user()->can('crm.access_own_schedule');
if (!(auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'crm_module')) || !($can_access_all_schedule || $can_access_own_schedule)) {
abort(403, 'Unauthorized action.');
}
if (request()->ajax()) {
try {
$query = Schedule::where('business_id', $business_id);
if (!$can_access_all_schedule && $can_access_own_schedule) {
$query->where(function ($qry) {
$qry->whereHas('users', function ($q) {
$q->where('user_id', auth()->user()->id);
})->orWhere('created_by', auth()->user()->id);
});
}
$schedule = $query->findOrFail($id);
$schedule->delete();
$view_type = request()->get('view_type', 'schedule');
$output = [
'success' => true,
'msg' => __('lang_v1.success'),
'action' => action([\Modules\Crm\Http\Controllers\ScheduleController::class, 'index']),
'view_type' => $view_type,
];
} catch (Exception $e) {
\Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
$output = [
'success' => false,
'msg' => __('messages.something_went_wrong'),
];
}
return $output;
}
}
/**
* Get today's schedule
*
* @return \Illuminate\Http\Response
*/
public function getTodaysSchedule()
{
$business_id = request()->session()->get('user.business_id');
if (!(auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'crm_module'))) {
abort(403, 'Unauthorized action.');
}
try {
$start_date = Carbon::today();
$query = $this->crmUtil->getFollowUpForGivenDate(\Auth::user(), $start_date);
$schedules = $query->get();
$schedule_html = view('crm::schedule.partial.today_schedule')
->with(compact('schedules'))
->render();
$output = [
'success' => true,
'msg' => __('lang_v1.success'),
'todays_schedule' => $schedule_html,
];
} catch (Exception $e) {
\Log::emergency('File:' . $e->getFile() . 'Line:' . $e->getLine() . 'Message:' . $e->getMessage());
$output = [
'success' => false,
'msg' => __('messages.something_went_wrong'),
];
}
return $output;
}
public function getLeadSchedule(Request $request)
{
$business_id = request()->session()->get('user.business_id');
if (!(auth()->user()->can('superadmin') || $this->moduleUtil->hasThePermissionInSubscription($business_id, 'crm_module'))) {
abort(403, 'Unauthorized action.');
}
$lead_id = $request->get('lead_id');
$schedules = Schedule::with('users')
->where('business_id', $business_id)
->where('contact_id', $lead_id)
->select('*');
return Datatables::of($schedules)
->addColumn('action', function ($row) {
$html = '
';
return $html;
})
->editColumn('start_datetime', '
@format_datetime($start_datetime)
')
->editColumn('end_datetime', '
@format_datetime($end_datetime)
')
->editColumn('users', function ($row) {
$html = ' ';
foreach ($row->users as $user) {
if (isset($user->media->display_url)) {
$html .= '
';
} else {
$html .= '
';
}
}
return $html;
})
->removeColumn('id')
->rawColumns(['action', 'start_datetime', 'end_datetime', 'users'])
->make(true);
}
/**
* Get invoices dropdaown by payment status or transaction activity
*
* @return array
*/
public function getInvoicesForFollowUp()
{
$business_id = request()->session()->get('user.business_id');
$follow_up_by = request()->input('follow_up_by');
$payment_status = request()->input('payment_status');
$query = Transaction::with(['contact'])
->where('business_id', $business_id)
->where('type', 'sell')
->where('status', 'final');
$permitted_locations = auth()->user()->permitted_locations();
if ($permitted_locations != 'all') {
$query->whereIn('transactions.location_id', $permitted_locations);
}
if ($follow_up_by == 'payment_status') {
if ($payment_status == 'all') {
$query->whereIn('payment_status', ['due', 'partial']);
} elseif ($payment_status == 'due') {
$query->where('payment_status', 'due');
} elseif ($payment_status == 'partial') {
$query->where('payment_status', 'partial');
} elseif ($payment_status == 'overdue') {
$query->overDue();
}
}
$sells = $query->select('id', 'invoice_no', 'payment_status', 'contact_id', 'pay_term_number', 'pay_term_type', 'transaction_date')
->get();
$sells_array = [];
foreach ($sells as $sell) {
$payment_status = Transaction::getPaymentStatus($sell);
$contact = ' - ' . $sell->contact->name;
if (!empty($sell->contact->supplier_business_name)) {
$contact = ' - ' . $sell->contact->supplier_business_name . $contact;
}
$sells_array[] = [
'id' => $sell->id,
'text' => $sell->invoice_no . ' (' . __('lang_v1.' . $payment_status) . $contact . ')',
];
}
return $sells_array;
}
/**
* Groups customers for follow-up based on payment status
* or transaction activity
*
* @return html
*/
public function getFollowUpGroups()
{
$business_id = request()->session()->get('user.business_id');
$users = User::forDropdown($business_id, false);
$follow_up_by = request()->input('follow_up_by');
if ($follow_up_by == 'payment_status') {
$invoices = request()->input('invoices');
$sells = Transaction::where('business_id', $business_id)
->where('type', 'sell')
->where('status', 'final')
->whereIn('id', $invoices)
->with(['contact'])
->select('id', 'invoice_no', 'contact_id')
->get();
$sells_by_customer = [];
foreach ($sells as $sell) {
$sells_by_customer[$sell->contact_id][] = $sell;
}
return view('crm::schedule.partial.group_invoices_by_customer')
->with(compact('sells_by_customer', 'users'));
} elseif ($follow_up_by == 'contact_name') {
$contact_ids = request()->input('contact_ids');
$customers = Contact::where('contacts.business_id', $business_id)
->whereIn('id', $contact_ids)
->get();
return view('crm::schedule.partial.group_customers')
->with(compact('customers', 'users'));
} else {
$days = request()->input('days');
$from_transaction_date = \Carbon::now()->subDays($days)->format('Y-m-d');
$query = Contact::where('contacts.business_id', $business_id)
->OnlyCustomers()
->leftJoin('transactions as t', 't.contact_id', '=', 'contacts.id');
if ($follow_up_by == 'has_transactions') {
$query->whereNotNull('t.id')
->havingRaw("MAX(DATE(transaction_date)) >= '{$from_transaction_date}'");
}
if ($follow_up_by == 'has_no_transactions') {
$query->havingRaw("MAX(DATE(transaction_date)) < '{$from_transaction_date}'")
->orHavingRaw('transaction_date IS NULL');
}
$customers = $query->select('contacts.*', 'transaction_date')
->groupBy('contacts.id')
->get();
return view('crm::schedule.partial.group_customers')
->with(compact('customers', 'users'));
}
}
public function getCustomerDropdown($business_id)
{
$leads = CrmContact::leadsDropdown($business_id, false);
$customers = Contact::customersDropdown($business_id, false)->toArray();
foreach ($customers as $key => $value) {
$customers[$key] = $value . ' (' . __('contact.customer') . ')';
}
foreach ($leads as $key => $value) {
$customers[$key] = $value . ' (' . __('crm::lang.lead') . ')';
}
return $customers;
}
}