shell bypass 403
<?php
namespace App\Http\Controllers\Customer;
use App\Http\Controllers\Controller;
use App\Library\SMSCounter;
use App\Library\Tool;
use App\Models\Campaigns;
use App\Models\CampaignsList;
use App\Models\CampaignsRecipients;
use App\Models\CampaignsSenderid;
use App\Models\CampaignsSendingServer;
use App\Models\ContactGroups;
use App\Models\Country;
use App\Models\PhoneNumbers;
use App\Models\PlansCoverageCountries;
use App\Models\Reports;
use App\Models\Senderid;
use App\Models\Templates;
use App\Models\TemplateTags;
use App\Notifications\SendCampaignCopy;
use ArielMejiaDev\LarapexCharts\LarapexChart;
use Box\Spout\Common\Exception\InvalidArgumentException;
use Box\Spout\Common\Exception\IOException;
use Box\Spout\Common\Exception\UnsupportedTypeException;
use Box\Spout\Writer\Exception\WriterNotOpenedException;
use Carbon\Carbon;
use Exception;
use Generator;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Contracts\View\Factory;
use Illuminate\Contracts\View\View;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Rap2hpoutre\FastExcel\FastExcel;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
class ReportsController extends Controller
{
/**
* sms reports
*
* @param Request $request
*
* @return Application|Factory|View
* @throws AuthorizationException
*/
public function reports(Request $request)
{
$this->authorize('view_reports');
$recipient = $request->recipient;
if ($recipient) {
$title = __('locale.contacts.conversion_with', ['recipient' => $recipient]);
$name = __('locale.contacts.view_conversion');
} else {
$title = __('locale.menu.All Messages');
$name = __('locale.menu.All Messages');
}
$breadcrumbs = [
['link' => url("/dashboard"), 'name' => __('locale.menu.Dashboard')],
['link' => url("/dashboard"), 'name' => __('locale.menu.Reports')],
['name' => $name],
];
return view('customer.Reports.all_messages', compact('breadcrumbs', 'recipient', 'title'));
}
/**
* get all message reports
*
* @param Request $request
*
* @throws AuthorizationException
*/
public function searchAllMessages(Request $request)
{
$this->authorize('view_reports');
$columns = [
0 => 'responsive_id',
1 => 'uid',
2 => 'uid',
3 => 'created_at',
4 => 'send_by',
5 => 'sms_type',
6 => 'from',
7 => 'to',
8 => 'cost',
9 => 'status',
];
$totalData = Reports::where('user_id', auth()->user()->id)->count();
$totalFiltered = $totalData;
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$dir = $request->input('order.0.dir');
$recipient = $request->get('recipient');
if (empty($request->input('search.value')) && empty($recipient)) {
$sms_reports = Reports::where('user_id', auth()->user()->id)
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
} elseif ($recipient != null) {
$sms_reports = Reports::where('user_id', auth()->user()->id)
->where('to', $recipient)
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
} else {
$search = $request->input('search.value');
$sms_reports = Reports::where('user_id', auth()->user()->id)->whereLike(['uid', 'send_by', 'sms_type', 'from', 'to', 'cost', 'status', 'created_at'], $search)
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
$totalFiltered = Reports::where('user_id', auth()->user()->id)->whereLike(['uid', 'send_by', 'sms_type', 'from', 'to', 'cost', 'status', 'created_at'], $search)->count();
}
$data = [];
if ( ! empty($sms_reports)) {
foreach ($sms_reports as $report) {
if ($report->created_at == null) {
$created_at = null;
} else {
$created_at = Tool::customerDateTime($report->created_at);
}
$nestedData['responsive_id'] = '';
$nestedData['uid'] = $report->uid;
$nestedData['created_at'] = $created_at;
$nestedData['send_by'] = $report->getSendBy();
$nestedData['sms_type'] = $report->getSMSType();
$nestedData['from'] = $report->from;
$nestedData['to'] = $report->to;
$nestedData['cost'] = $report->cost;
$nestedData['status'] = str_limit($report->status, 20);
$data[] = $nestedData;
}
}
$json_data = [
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data,
];
echo json_encode($json_data);
exit();
}
/**
* view single reports
*
* @param Reports $uid
*
* @return JsonResponse
*/
public function viewReports(Reports $uid): JsonResponse
{
return response()->json([
'status' => 'success',
'data' => $uid,
]);
}
/**
* @param Reports $uid
*
* @return JsonResponse
* @throws Exception
*/
public function destroy(Reports $uid): JsonResponse
{
if (config('app.stage') == 'demo') {
return response()->json([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
if ( ! $uid->delete()) {
return response()->json([
'status' => 'error',
'message' => __('locale.exceptions.something_went_wrong'),
]);
}
return response()->json([
'status' => 'success',
'message' => __('locale.campaigns.sms_was_successfully_deleted'),
]);
}
/**
* bulk sms delete
*
* @param Request $request
*
* @return JsonResponse
*/
public function batchAction(Request $request): JsonResponse
{
if (config('app.stage') == 'demo') {
return response()->json([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$ids = $request->get('ids');
if (Reports::whereIn('uid', $ids)->where('user_id', auth()->user()->id)->delete()) {
return response()->json([
'status' => 'success',
'message' => __('locale.campaigns.sms_was_successfully_deleted'),
]);
}
return response()->json([
'status' => 'error',
'message' => __('locale.exceptions.something_went_wrong'),
]);
}
/**
* sms received
*
* @return Application|Factory|View
* @throws AuthorizationException
*/
public function received()
{
$this->authorize('view_reports');
$breadcrumbs = [
['link' => url("/dashboard"), 'name' => __('locale.menu.Dashboard')],
['link' => url("/dashboard"), 'name' => __('locale.menu.Reports')],
['name' => __('locale.menu.Received Messages')],
];
return view('customer.Reports.received_messages', compact('breadcrumbs'));
}
/**
* get all received reports
*
* @param Request $request
*
* @throws AuthorizationException
*/
public function searchReceivedMessage(Request $request)
{
$this->authorize('view_reports');
$columns = [
0 => 'responsive_id',
1 => 'uid',
2 => 'uid',
3 => 'created_at',
5 => 'sms_type',
6 => 'from',
7 => 'to',
8 => 'cost',
9 => 'status',
];
$totalData = Reports::where('user_id', auth()->user()->id)->where('send_by', 'to')->count();
$totalFiltered = $totalData;
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$dir = $request->input('order.0.dir');
if (empty($request->input('search.value'))) {
$sms_reports = Reports::where('user_id', auth()->user()->id)->where('send_by', 'to')->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
} else {
$search = $request->input('search.value');
$sms_reports = Reports::where('user_id', auth()->user()->id)->where('send_by', 'to')->whereLike(['uid', 'sms_type', 'from', 'to', 'cost', 'status', 'created_at'], $search)
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
$totalFiltered = Reports::where('user_id', auth()->user()->id)->where('send_by', 'to')->whereLike(['uid', 'sms_type', 'from', 'to', 'cost', 'status', 'created_at'], $search)->count();
}
$data = [];
if ( ! empty($sms_reports)) {
foreach ($sms_reports as $report) {
if ($report->created_at == null) {
$created_at = null;
} else {
$created_at = Tool::customerDateTime($report->created_at);
}
$nestedData['responsive_id'] = '';
$nestedData['uid'] = $report->uid;
$nestedData['created_at'] = $created_at;
$nestedData['sms_type'] = $report->getSMSType();
$nestedData['from'] = $report->from;
$nestedData['to'] = $report->to;
$nestedData['cost'] = $report->cost;
$nestedData['status'] = str_limit($report->status, 20);
$data[] = $nestedData;
}
}
$json_data = [
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data,
];
echo json_encode($json_data);
exit();
}
/**
* sms sent
*
* @return Application|Factory|View
* @throws AuthorizationException
*/
public function sent()
{
$this->authorize('view_reports');
$breadcrumbs = [
['link' => url("/dashboard"), 'name' => __('locale.menu.Dashboard')],
['link' => url("/dashboard"), 'name' => __('locale.menu.Reports')],
['name' => __('locale.menu.Sent Messages')],
];
return view('customer.Reports.sent_messages', compact('breadcrumbs'));
}
/**
* get all sent reports
*
* @param Request $request
*
* @throws AuthorizationException
*/
public function searchSentMessage(Request $request)
{
$this->authorize('view_reports');
$columns = [
0 => 'responsive_id',
1 => 'uid',
2 => 'uid',
3 => 'created_at',
5 => 'sms_type',
6 => 'from',
7 => 'to',
8 => 'cost',
9 => 'status',
];
$totalData = Reports::where('user_id', auth()->user()->id)->where('send_by', 'from')->count();
$totalFiltered = $totalData;
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$dir = $request->input('order.0.dir');
if (empty($request->input('search.value'))) {
$sms_reports = Reports::where('user_id', auth()->user()->id)->where('send_by', 'from')->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
} else {
$search = $request->input('search.value');
$sms_reports = Reports::where('user_id', auth()->user()->id)->where('send_by', 'from')->whereLike(['uid', 'sms_type', 'from', 'to', 'cost', 'status', 'created_at'], $search)
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
$totalFiltered = Reports::where('user_id', auth()->user()->id)->where('send_by', 'from')->whereLike(['uid', 'sms_type', 'from', 'to', 'cost', 'status', 'created_at'], $search)->count();
}
$data = [];
if ( ! empty($sms_reports)) {
foreach ($sms_reports as $report) {
if ($report->created_at == null) {
$created_at = null;
} else {
$created_at = Tool::customerDateTime($report->created_at);
}
$nestedData['responsive_id'] = '';
$nestedData['uid'] = $report->uid;
$nestedData['created_at'] = $created_at;
$nestedData['sms_type'] = $report->getSMSType();
$nestedData['from'] = $report->from;
$nestedData['to'] = $report->to;
$nestedData['cost'] = $report->cost;
$nestedData['status'] = str_limit($report->status, 20);
$data[] = $nestedData;
}
}
$json_data = [
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data,
];
echo json_encode($json_data);
exit();
}
/**
* get campaign details
*
* @return Application|Factory|View
* @throws AuthorizationException
*/
public function campaigns()
{
$this->authorize('view_reports');
$breadcrumbs = [
['link' => url("/dashboard"), 'name' => __('locale.menu.Dashboard')],
['link' => url("/dashboard"), 'name' => __('locale.menu.Reports')],
['name' => __('locale.menu.Campaigns')],
];
return view('customer.Reports.campaigns', compact('breadcrumbs'));
}
/**
* search campaign data
*
* @param Request $request
*
* @throws AuthorizationException
*/
public function searchCampaigns(Request $request)
{
$this->authorize('view_reports');
$columns = [
0 => 'responsive_id',
1 => 'uid',
2 => 'uid',
3 => 'campaign_name',
4 => 'contacts',
5 => 'sms_type',
6 => 'schedule_type',
7 => 'status',
8 => 'uid',
];
$totalData = Campaigns::where('user_id', auth()->user()->id)->count();
$totalFiltered = $totalData;
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$dir = $request->input('order.0.dir');
if (empty($request->input('search.value'))) {
$campaigns = Campaigns::where('user_id', auth()->user()->id)->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
} else {
$search = $request->input('search.value');
$campaigns = Campaigns::where('user_id', auth()->user()->id)->whereLike(['uid', 'campaign_name', 'sms_type', 'schedule_type', 'created_at', 'status'], $search)
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
$totalFiltered = Campaigns::where('user_id', auth()->user()->id)->whereLike(['uid', 'campaign_name', 'sms_type', 'schedule_type', 'created_at', 'status'], $search)->count();
}
$data = [];
if ( ! empty($campaigns)) {
foreach ($campaigns as $campaign) {
$nestedData['responsive_id'] = '';
$nestedData['uid'] = $campaign->uid;
$nestedData['campaign_name'] = "<div>
<p class='text-bold-600'> $campaign->campaign_name </p>
<p class='text-muted'>".__('locale.labels.created_at').': '.Tool::formatHumanTime($campaign->created_at)."</p>
</div>";
$nestedData['contacts'] = Tool::number_with_delimiter($campaign->contactCount($campaign->cache));
$nestedData['sms_type'] = $campaign->getSMSType();
$nestedData['schedule_type'] = $campaign->getCampaignType();
$nestedData['status'] = $campaign->getStatus();
$nestedData['camp_status'] = $campaign->status;
$nestedData['show'] = route('customer.reports.campaign.edit', $campaign->uid);
$nestedData['show_label'] = __('locale.buttons.edit');
$nestedData['overview'] = route('customer.reports.campaign.overview', $campaign->uid);
$nestedData['overview_label'] = __('locale.menu.Overview');
$nestedData['delete'] = __('locale.buttons.delete');
$data[] = $nestedData;
}
}
$json_data = [
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data,
];
echo json_encode($json_data);
exit();
}
public function editCampaign(Campaigns $campaign)
{
if ($campaign->upload_type == 'file') {
return redirect()->route('customer.reports.campaigns')->with([
'status' => 'info',
'message' => __('locale.campaigns.you_are_not_able_to_update_file_import_campaign'),
]);
}
$breadcrumbs = [
['link' => url("/dashboard"), 'name' => __('locale.menu.Dashboard')],
['link' => url("/reports/campaigns"), 'name' => __('locale.menu.Reports')],
['name' => __('locale.menu.Campaign Builder')],
];
if (Auth::user()->customer->getOption('sender_id_verification') == 'yes') {
$sender_ids = Senderid::where('user_id', auth()->user()->id)->where('status', 'active')->cursor();
} else {
$sender_ids = null;
}
$phone_numbers = PhoneNumbers::where('user_id', auth()->user()->id)->where('status', 'assigned')->cursor();
$template_tags = TemplateTags::cursor();
$contact_groups = ContactGroups::where('status', 1)->where('customer_id', auth()->user()->id)->cursor();
$templates = Templates::where('user_id', auth()->user()->id)->where('status', 1)->cursor();
$campaign_sender_ids = CampaignsSenderid::where('campaign_id', $campaign->id)->cursor();
$exist_sender_id = null;
$exist_phone_numbers = [];
$originator = 'sender_id';
foreach ($campaign_sender_ids as $sender_id) {
if ($sender_id->originator == 'sender_id') {
$exist_sender_id = $sender_id->sender_id;
} else {
$originator = 'phone_number';
$exist_phone_numbers[] = $sender_id->sender_id;
}
}
$exist_groups = CampaignsList::where('campaign_id', $campaign->id)->select('contact_list_id')->get()->pluck('contact_list_id')->toArray();
$exist_recipients = CampaignsRecipients::where('campaign_id', $campaign->id)->select('recipient')->get()->pluck('recipient')->toArray();
$exist_recipients = implode(',', $exist_recipients);
$plan_id = Auth::user()->customer->activeSubscription()->plan_id;
return view('customer.Campaigns.updateCampaignBuilder', compact('breadcrumbs', 'sender_ids', 'phone_numbers', 'template_tags', 'contact_groups', 'templates', 'campaign', 'exist_sender_id', 'originator', 'exist_phone_numbers', 'exist_groups', 'exist_recipients', 'plan_id'));
}
/**
* @param Campaigns $campaign
* @param Request $request
*
* @return RedirectResponse
*/
public function postEditCampaign(Campaigns $campaign, Request $request): RedirectResponse
{
if (config('app.stage') == 'demo') {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$input = $request->except('_token');
$sms_type = $input['sms_type'];
$sending_servers = $campaign->getSendingServers();
if (empty($sending_servers)) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.campaigns.sending_server_not_available'),
]);
}
$sender_id = null;
if (Auth::user()->customer->getOption('sender_id_verification') == 'yes') {
if (isset($input['originator'])) {
if ($input['originator'] == 'sender_id') {
if ( ! isset($input['sender_id'])) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_required'),
]);
}
$sender_id = $input['sender_id'];
if (is_array($sender_id) && count($sender_id) > 0) {
$invalid = [];
$senderids = Senderid::where('user_id', Auth::user()->id)
->where('status', 'active')
->select('sender_id')
->cursor()
->pluck('sender_id')
->all();
foreach ($sender_id as $sender) {
if ( ! in_array($sender, $senderids)) {
$invalid[] = $sender;
}
}
if (count($invalid)) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_invalid', ['sender_id' => $invalid[0]]),
]);
}
} else {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_required'),
]);
}
} else {
if ( ! isset($input['phone_number'])) {
$sender_id = CampaignsSenderid::where('campaign_id', $campaign->id)->pluck('sender_id')->toArray();
} else {
$sender_id = $input['phone_number'];
}
if (isset($sender_id) && is_array($sender_id) && count($sender_id) > 0) {
$type_supported = [];
PhoneNumbers::where('user_id', Auth::user()->id)
->where('status', 'assigned')
->cursor()
->reject(function ($number) use ($sender_id, &$type_supported, &$invalid) {
if (in_array($number->number, $sender_id) && ! str_contains($number->capabilities, 'sms')) {
return $type_supported[] = $number->number;
}
return $sender_id;
})->all();
if (count($type_supported)) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_sms_capabilities', ['sender_id' => $type_supported[0]]),
]);
}
} else {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_required'),
]);
}
}
} else {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_required'),
]);
}
} elseif (Auth::user()->can('view_numbers') && isset($input['originator']) && $input['originator'] == 'phone_number') {
$sender_id = $input['phone_number'];
if (isset($sender_id) && is_array($sender_id) && count($sender_id) > 0) {
$type_supported = [];
PhoneNumbers::where('user_id', Auth::user()->id)
->where('status', 'assigned')
->cursor()
->reject(function ($number) use ($sender_id, &$type_supported, &$invalid) {
if (in_array($number->number, $sender_id) && ! str_contains($number->capabilities, 'sms')) {
return $type_supported[] = $number->number;
}
return $sender_id;
})->all();
if (count($type_supported)) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_sms_capabilities', ['sender_id' => $type_supported[0]]),
]);
}
} else {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_required'),
]);
}
} else {
if (isset($input['originator'])) {
if ($input['originator'] == 'sender_id') {
if ( ! isset($input['sender_id'])) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_required'),
]);
}
$sender_id = $input['sender_id'];
} else {
if ( ! isset($input['phone_number'])) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.phone_numbers_required'),
]);
}
$sender_id = $input['phone_number'];
}
if ( ! is_array($sender_id) || count($sender_id) <= 0) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.sender_id.sender_id_required'),
]);
}
}
if (isset($input['sender_id'])) {
$sender_id = $input['sender_id'];
$input['originator'] = 'sender_id';
}
}
$total = 0;
$campaign_groups = [];
// update contact groups details
if (isset($input['contact_groups']) && is_array($input['contact_groups']) && count($input['contact_groups']) > 0) {
$contact_groups = ContactGroups::whereIn('id', $input['contact_groups'])->where('status', true)->where('customer_id', Auth::user()->id)->cursor();
foreach ($contact_groups as $group) {
$total += $group->subscribersCount($group->cache);
$campaign_groups[] = [
'campaign_id' => $campaign->id,
'contact_list_id' => $group->id,
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
];
}
}
// update manual input numbers
if (isset($input['recipients'])) {
switch ($input['delimiter']) {
case ',':
$recipients = explode(',', $input['recipients']);
break;
case ';':
$recipients = explode(';', $input['recipients']);
break;
case '|':
$recipients = explode('|', $input['recipients']);
break;
case 'tab':
$recipients = explode(' ', $input['recipients']);
break;
case 'new_line':
$recipients = explode("\n", $input['recipients']);
break;
default:
$recipients = [];
break;
}
$recipients = collect($recipients)->unique();
$total += $recipients->count();
$numbers = [];
foreach ($recipients->chunk(500) as $chunk) {
foreach ($chunk as $number) {
$numbers[] = [
'campaign_id' => $campaign->id,
'recipient' => preg_replace("/\r/", "", $number),
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
];
}
}
CampaignsRecipients::where('campaign_id', $campaign->id)->delete();
CampaignsRecipients::insert($numbers);
} else {
CampaignsRecipients::where('campaign_id', $campaign->id)->delete();
}
if ($total == 0) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.campaigns.contact_not_found'),
]);
}
if (Auth::user()->sms_unit != '-1') {
$coverage = PlansCoverageCountries::where('plan_id', $input['plan_id'])->first();
$priceOption = json_decode($coverage->options, true);
$sms_count = 1;
$price = 0;
if (isset($input['message'])) {
$sms_counter = new SMSCounter();
$message_data = $sms_counter->count($input['message']);
$sms_count = $message_data->messages;
}
if ($sms_type == 'plain' || $sms_type == 'unicode') {
$unit_price = $priceOption['plain_sms'];
$price = $total * $unit_price;
}
if ($sms_type == 'voice') {
$unit_price = $priceOption['voice_sms'];
$price = $total * $unit_price;
}
if ($sms_type == 'mms') {
$unit_price = $priceOption['mms_sms'];
$price = $total * $unit_price;
}
if ($sms_type == 'whatsapp') {
$unit_price = $priceOption['whatsapp_sms'];
$price = $total * $unit_price;
}
$price *= $sms_count;
$balance = Auth::user()->sms_unit;
if ($price > $balance) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.campaigns.not_enough_balance', [
'current_balance' => $balance,
'campaign_price' => $price,
]),
]);
}
}
CampaignsSenderid::where('campaign_id', $campaign->id)->delete();
foreach ($sender_id as $id) {
$data = [
'campaign_id' => $campaign->id,
'sender_id' => $id,
];
if (isset($input['originator'])) {
$data['originator'] = $input['originator'];
}
CampaignsSenderid::create($data);
}
CampaignsList::where('campaign_id', $campaign->id)->delete();
CampaignsList::insert($campaign_groups);
// if schedule is available then check date, time and timezone
if (isset($input['schedule']) && $input['schedule'] == "true") {
$schedule_date = $input['schedule_date'].' '.$input['schedule_time'];
$schedule_time = Tool::systemTimeFromString($schedule_date, $input['timezone']);
$campaign->timezone = $input['timezone'];
$campaign->status = Campaigns::STATUS_SCHEDULED;
$campaign->schedule_time = $schedule_time;
if ($input['frequency_cycle'] == 'onetime') {
// working with onetime schedule
$campaign->schedule_type = Campaigns::TYPE_ONETIME;
} else {
// working with recurring schedule
//if schedule time frequency is not one time then check frequency details
$recurring_date = $input['recurring_date'].' '.$input['recurring_time'];
$recurring_end = Tool::systemTimeFromString($recurring_date, $input['timezone']);
$campaign->schedule_type = Campaigns::TYPE_RECURRING;
$campaign->recurring_end = $recurring_end;
if (isset($input['frequency_cycle'])) {
if ($input['frequency_cycle'] != 'custom') {
$schedule_cycle = $campaign::scheduleCycleValues();
$limits = $schedule_cycle[$input['frequency_cycle']];
$campaign->frequency_cycle = $input['frequency_cycle'];
$campaign->frequency_amount = $limits['frequency_amount'];
$campaign->frequency_unit = $limits['frequency_unit'];
} else {
$campaign->frequency_cycle = $input['frequency_cycle'];
$campaign->frequency_amount = $input['frequency_amount'];
$campaign->frequency_unit = $input['frequency_unit'];
}
}
}
} else {
$campaign->status = Campaigns::STATUS_QUEUED;
}
//update cache
$campaign->cache = json_encode([
'ContactCount' => $total,
'DeliveredCount' => 0,
'FailedDeliveredCount' => 0,
'NotDeliveredCount' => 0,
]);
$campaign->message = $input['message'];
if ($sms_type == 'voice') {
$campaign->language = $input['language'];
$campaign->gender = $input['gender'];
}
if ($sms_type == 'mms') {
$campaign->media_url = Tool::uploadImage($input['mms_file']);
}
$camp = $campaign->save();
if ($camp) {
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'success',
'message' => __('locale.campaigns.campaign_successfully_updated'),
]);
}
return redirect()->route('customer.reports.campaign.edit', $campaign->uid)->with([
'status' => 'error',
'message' => __('locale.exceptions.something_went_wrong'),
]);
}
public function campaignOverview(Campaigns $campaign)
{
$breadcrumbs = [
['link' => url("/dashboard"), 'name' => __('locale.menu.Dashboard')],
['link' => url("/reports/campaigns"), 'name' => __('locale.menu.Reports')],
['name' => __('locale.menu.Overview')],
];
$campaign = Campaigns::where('user_id', Auth::user()->id)->where('uid', $campaign->uid)->first();
if (! $campaign){
return redirect()->route('customer.reports.campaigns')->with([
'status' => 'error',
'message' => __('locale.exceptions.invalid_action'),
]);
}
return view('customer.Campaigns.overview', compact('campaign', 'breadcrumbs'));
}
/**
* view campaign reports
*
* @param Campaigns $campaign
* @param Request $request
*
* @throws AuthorizationException
*/
public function campaignReports(Campaigns $campaign, Request $request)
{
$this->authorize('view_reports');
$columns = [
0 => 'responsive_id',
1 => 'uid',
2 => 'uid',
3 => 'created_at',
6 => 'from',
7 => 'to',
8 => 'cost',
9 => 'status',
];
$totalData = Reports::where('user_id', auth()->user()->id)->where('campaign_id', $campaign->id)->count();
$totalFiltered = $totalData;
$limit = $request->input('length');
$start = $request->input('start');
$order = $columns[$request->input('order.0.column')];
$dir = $request->input('order.0.dir');
if (empty($request->input('search.value'))) {
$sms_reports = Reports::where('user_id', auth()->user()->id)->where('campaign_id', $campaign->id)->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
} else {
$search = $request->input('search.value');
$sms_reports = Reports::where('user_id', auth()->user()->id)->where('campaign_id', $campaign->id)->whereLike(['uid', 'from', 'to', 'cost', 'status', 'created_at'], $search)
->offset($start)
->limit($limit)
->orderBy($order, $dir)
->get();
$totalFiltered = Reports::where('user_id', auth()->user()->id)->where('campaign_id', $campaign->id)->whereLike(['uid', 'from', 'to', 'cost', 'status', 'created_at'], $search)->count();
}
$data = [];
if ( ! empty($sms_reports)) {
foreach ($sms_reports as $report) {
if ($report->created_at == null) {
$created_at = null;
} else {
$created_at = Tool::customerDateTime($report->created_at);
}
$nestedData['responsive_id'] = '';
$nestedData['uid'] = $report->uid;
$nestedData['created_at'] = $created_at;
$nestedData['from'] = $report->from;
$nestedData['to'] = $report->to;
$nestedData['cost'] = $report->cost;
$nestedData['status'] = str_limit($report->status, 20);
$data[] = $nestedData;
}
}
$json_data = [
"draw" => intval($request->input('draw')),
"recordsTotal" => intval($totalData),
"recordsFiltered" => intval($totalFiltered),
"data" => $data,
];
echo json_encode($json_data);
exit();
}
/**
* @param $type
*
* @return Generator
*/
public function reportsGenerator($type): Generator
{
if ($type == 'all') {
foreach (Reports::where('user_id', Auth::user()->id)->cursor() as $report) {
yield $report;
}
} else {
foreach (Reports::where('user_id', Auth::user()->id)->where('send_by', $type)->cursor() as $report) {
yield $report;
}
}
}
/**
* @param $campaign_id
*
* @return Generator
*/
public function campaignReportsGenerator($campaign_id): Generator
{
foreach (Reports::where('user_id', Auth::user()->id)->where('campaign_id', $campaign_id)->cursor() as $report) {
yield $report;
}
}
/**
* @param Request $request
*
* @return RedirectResponse|BinaryFileResponse
* @throws AuthorizationException
* @throws IOException
* @throws InvalidArgumentException
* @throws UnsupportedTypeException
* @throws WriterNotOpenedException
*/
public function export(Request $request)
{
if (config('app.stage') == 'demo') {
return redirect()->route('customer.reports.all')->with([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$this->authorize('view_reports');
Tool::resetMaxExecutionTime();
$file_name = (new FastExcel($this->exportData($request)))->export(storage_path('Reports_'.time().'.xlsx'));
return response()->download($file_name);
}
/**
* @param $request
*
* @return Generator
*/
public function exportData($request): Generator
{
$start_date = null;
$end_date = null;
if ($request->start_date && $request->end_date) {
$start_time = $request->start_date.' '.$request->start_time;
$start_date = Tool::systemTimeFromString($start_time, Auth::user()->timezone);
$end_time = $request->end_date.' '.$request->end_time;
$end_date = Tool::systemTimeFromString($end_time, Auth::user()->timezone);
}
$status = $request->status;
$direction = $request->direction;
$type = $request->type;
$to = $request->to;
$from = $request->from;
if ($status == 'delivered') {
$status = 'Delivered';
}
$get_data = Reports::query()->when($status, function ($query) use ($status) {
$query->whereLike(['status'], $status);
})->when($from, function ($query) use ($from) {
$query->whereLike(['from'], $from);
})->when($to, function ($query) use ($to) {
$query->whereLike(['to'], $to);
})->when($direction, function ($query) use ($direction) {
$query->where('send_by', $direction);
})->when($start_date, function ($query) use ($start_date, $end_date) {
$query->whereBetween('created_at', [$start_date, $end_date]);
})->where('sms_type', $type)->where('user_id', Auth::user()->id)->cursor();
foreach ($get_data as $report) {
yield $report;
}
}
/**
* @return RedirectResponse|BinaryFileResponse
* @throws AuthorizationException
* @throws IOException
* @throws InvalidArgumentException
* @throws UnsupportedTypeException
* @throws WriterNotOpenedException
*/
public function exportSent()
{
if (config('app.stage') == 'demo') {
return redirect()->route('customer.reports.all')->with([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$this->authorize('view_reports');
$file_name = (new FastExcel($this->reportsGenerator('from')))->export(storage_path('Reports_'.time().'.xlsx'));
return response()->download($file_name);
}
/**
* @return RedirectResponse|BinaryFileResponse
* @throws AuthorizationException
* @throws IOException
* @throws InvalidArgumentException
* @throws UnsupportedTypeException
* @throws WriterNotOpenedException
*/
public function exportReceive()
{
if (config('app.stage') == 'demo') {
return redirect()->route('customer.reports.all')->with([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$this->authorize('view_reports');
$file_name = (new FastExcel($this->reportsGenerator('to')))->export(storage_path('Reports_'.time().'.xlsx'));
return response()->download($file_name);
}
/**
* @return RedirectResponse|BinaryFileResponse
* @throws AuthorizationException
* @throws IOException
* @throws InvalidArgumentException
* @throws UnsupportedTypeException
* @throws WriterNotOpenedException
*/
public function exportCampaign(Campaigns $campaign)
{
if (config('app.stage') == 'demo') {
return redirect()->route('customer.reports.all')->with([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$this->authorize('view_reports');
$file_name = (new FastExcel($this->campaignReportsGenerator($campaign->id)))->export(storage_path('Reports_'.time().'.xlsx'));
return response()->download($file_name);
}
/**
* @return Generator
*/
public function campaignGenerator(): Generator
{
foreach (Campaigns::where('user_id', Auth::user()->id)->cursor() as $report) {
yield $report;
}
}
/**
* @return RedirectResponse|BinaryFileResponse
* @throws AuthorizationException
* @throws IOException
* @throws InvalidArgumentException
* @throws UnsupportedTypeException
* @throws WriterNotOpenedException
*/
public function campaignExport()
{
if (config('app.stage') == 'demo') {
return redirect()->route('customer.reports.all')->with([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$this->authorize('view_reports');
$file_name = (new FastExcel($this->campaignGenerator()))->export(storage_path('Campaign_'.time().'.xlsx'));
return response()->download($file_name);
}
/**
* delete campaign
*
* @param Campaigns $campaign
*
* @return JsonResponse
* @throws Exception
*/
public function campaignDelete(Campaigns $campaign): JsonResponse
{
if (config('app.stage') == 'demo') {
return response()->json([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
if ( ! $campaign->delete()) {
return response()->json([
'status' => 'error',
'message' => __('locale.exceptions.something_went_wrong'),
]);
}
return response()->json([
'status' => 'success',
'message' => __('locale.campaigns.campaign_was_successfully_deleted'),
]);
}
/**
* bulk campaign delete
*
* @param Request $request
*
* @return JsonResponse
*/
public function campaignBatchAction(Request $request): JsonResponse
{
if (config('app.stage') == 'demo') {
return response()->json([
'status' => 'error',
'message' => 'Sorry! This option is not available in demo mode',
]);
}
$ids = $request->get('ids');
if (Campaigns::whereIn('uid', $ids)->where('user_id', auth()->user()->id)->delete()) {
return response()->json([
'status' => 'success',
'message' => __('locale.campaigns.campaign_was_successfully_deleted'),
]);
}
return response()->json([
'status' => 'error',
'message' => __('locale.exceptions.something_went_wrong'),
]);
}
public function viewCharts()
{
$breadcrumbs = [
['link' => url("/dashboard"), 'name' => __('locale.menu.Dashboard')],
['name' => __('locale.menu.View Charts')],
];
$sms_outgoing = Reports::currentMonth()
->where('user_id', Auth::user()->id)
->selectRaw('Day(created_at) as day, count(send_by) as outgoing,send_by')
->where('send_by', "from")
->groupBy('day')->pluck('day', 'outgoing')->flip()->sortKeys();
$sms_incoming = Reports::currentMonth()
->where('user_id', Auth::user()->id)
->selectRaw('Day(created_at) as day, count(send_by) as incoming,send_by')
->where('send_by', "to")
->groupBy('day')->pluck('day', 'incoming')->flip()->sortKeys();
$outgoing = (new LarapexChart)->lineChart()
->addData(__('locale.labels.outgoing'), $sms_outgoing->values()->toArray())
->setXAxis($sms_outgoing->keys()->toArray());
$incoming = (new LarapexChart)->lineChart()
->addData(__('locale.labels.incoming'), $sms_incoming->values()->toArray())
->setXAxis($sms_incoming->keys()->toArray());
return view('customer.Reports.charts', compact('breadcrumbs', 'sms_incoming', 'sms_outgoing', 'outgoing', 'incoming'));
}
}