diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 5549c8df1978..52f23424209c 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -3,6 +3,7 @@ namespace App\Http\Controllers; use App\Jobs\ExportReportResults; +use App\Jobs\LoadPostmarkStats; use App\Jobs\RunReport; use App\Models\Account; use App\Models\ScheduledReport; @@ -12,9 +13,6 @@ use Utils; use View; use Carbon; use Validator; -use stdClass; -use DateInterval; -use DatePeriod; /** @@ -189,67 +187,8 @@ class ReportController extends BaseController public function loadEmailReport($startDate, $endDate) { - $account = auth()->user()->account; - $startDate = date_create($startDate); - $endDate = date_create($endDate); - $postmark = new \Postmark\PostmarkClient(config('services.postmark')); - $obj = new stdClass; + $data = dispatch(new LoadPostmarkStats($startDate, $endDate)); - $eventTypes = ['sent', 'opened']; - - foreach ($eventTypes as $eventType) { - $data = []; - $endDate->modify('+1 day'); - $interval = new DateInterval('P1D'); - $period = new DatePeriod($startDate, $interval, $endDate); - $endDate->modify('-1 day'); - $records = []; - - if ($eventType == 'sent') { - $response = $postmark->getOutboundSendStatistics(null, request()->start_date, request()->end_date); - } else { - $response = $postmark->getOutboundOpenStatistics(null, request()->start_date, request()->end_date); - } - - foreach ($response->days as $key => $val) { - $field = $eventType == 'opened' ? 'unique' : $eventType; - $data[$val['date']] = $val[$field]; - } - - foreach ($period as $day) { - $date = $day->format('Y-m-d'); - $records[] = isset($data[$date]) ? $data[$date] : 0; - - if ($eventType == 'sent') { - $labels[] = $day->format('m/d/Y'); - } - } - - if ($eventType == 'sent') { - $color = '51,122,183'; - } elseif ($eventType == 'opened') { - $color = '54,193,87'; - } elseif ($eventType == 'bounced') { - $color = '128,128,128'; - } - - $group = new stdClass(); - $group->data = $records; - $group->label = trans("texts.{$eventType}"); - $group->lineTension = 0; - $group->borderWidth = 4; - $group->borderColor = "rgba({$color}, 1)"; - $group->backgroundColor = "rgba({$color}, 0.1)"; - $datasets[] = $group; - } - - $data = new stdClass(); - $data->labels = $labels; - $data->datasets = $datasets; - - $response = new stdClass(); - $response->data = $data; - - return response()->json($response); + return response()->json($data); } } diff --git a/app/Jobs/LoadPostmarkStats.php b/app/Jobs/LoadPostmarkStats.php new file mode 100644 index 000000000000..df101c4514e8 --- /dev/null +++ b/app/Jobs/LoadPostmarkStats.php @@ -0,0 +1,151 @@ +startDate = $startDate; + $this->endDate = $endDate; + + $this->response = new stdClass(); + $this->postmark = new \Postmark\PostmarkClient(config('services.postmark')); + $this->account = auth()->user()->account; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $this->loadOverallStats(); + $this->loadSentStats(); + $this->loadPlatformStats(); + $this->loadEmailClientStats(); + + return $this->response; + } + + private function loadOverallStats() { + $startDate = date_create($this->startDate); + $endDate = date_create($this->endDate); + + $eventTypes = ['sent', 'opened']; + + foreach ($eventTypes as $eventType) { + $data = []; + $endDate->modify('+1 day'); + $interval = new DateInterval('P1D'); + $period = new DatePeriod($startDate, $interval, $endDate); + $endDate->modify('-1 day'); + $records = []; + + if ($eventType == 'sent') { + $response = $this->postmark->getOutboundSendStatistics(null, request()->start_date, request()->end_date); + } else { + $response = $this->postmark->getOutboundOpenStatistics(null, request()->start_date, request()->end_date); + } + + foreach ($response->days as $key => $val) { + $field = $eventType == 'opened' ? 'unique' : $eventType; + $data[$val['date']] = $val[$field]; + } + + foreach ($period as $day) { + $date = $day->format('Y-m-d'); + $records[] = isset($data[$date]) ? $data[$date] : 0; + + if ($eventType == 'sent') { + $labels[] = $day->format('m/d/Y'); + } + } + + if ($eventType == 'sent') { + $color = '51,122,183'; + } elseif ($eventType == 'opened') { + $color = '54,193,87'; + } elseif ($eventType == 'bounced') { + $color = '128,128,128'; + } + + $group = new stdClass(); + $group->data = $records; + $group->label = trans("texts.{$eventType}"); + $group->lineTension = 0; + $group->borderWidth = 4; + $group->borderColor = "rgba({$color}, 1)"; + $group->backgroundColor = "rgba({$color}, 0.1)"; + $datasets[] = $group; + } + + $data = new stdClass(); + $data->labels = $labels; + $data->datasets = $datasets; + $this->response->data = $data; + } + + private function loadSentStats() { + $account = $this->account; + $data = $this->postmark->getOutboundOverviewStatistics(null, request()->start_date, request()->end_date); + $this->response->totals = [ + 'sent' => $account->formatNumber($data->sent), + 'opened' => sprintf('%s | %s%%', $account->formatNumber($data->uniqueopens), $account->formatNumber($data->uniqueopens / $data->sent * 100)), + 'bounced' => sprintf('%s | %s%%', $account->formatNumber($data->bounced), $account->formatNumber($data->bouncerate, 3)), + //'spam' => sprintf('%s | %s%%', $account->formatNumber($data->spamcomplaints), $account->formatNumber($data->spamcomplaintsrate, 3)) + ]; + } + + private function loadPlatformStats() { + $data = $this->postmark->getOutboundPlatformStatistics(null, request()->start_date, request()->end_date); + $account = $this->account; + $str = ''; + $total = 0; + + $total = $data['desktop'] + $data['mobile'] + $data['webmail']; + + foreach (['mobile', 'desktop', 'webmail'] as $platform) { + $str .= sprintf('%s%s%%', trans('texts.' . $platform), $account->formatNumber($data[$platform] / $total * 100)); + } + + $this->response->platforms = $str; + } + + private function loadEmailClientStats() { + $data = $this->postmark->getOutboundEmailClientStatistics(null, request()->start_date, request()->end_date); + $account = $this->account; + $str = ''; + $total = 0; + $clients = []; + + foreach ($data as $key => $val) { + if ($key == 'days') { + continue; + } + + $total += $val; + $clients[$key] = $val; + } + + arsort($clients); + + foreach ($clients as $key => $val) { + $percent = $val / $total * 100; + if ($percent < 0.5) { + continue; + } + $str .= sprintf('%s%s%%', ucwords($key), $account->formatNumber($percent)); + } + + $this->response->emailClients = $str; + } + +} diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index 5dab8479b534..abbdc4904458 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -500,6 +500,21 @@ class Utils return $data->first(); } + public static function formatNumber($value, $currencyId = false, $precision = 0) + { + $value = floatval($value); + + if (! $currencyId) { + $currencyId = Session::get(SESSION_CURRENCY, DEFAULT_CURRENCY); + } + + $currency = self::getFromCache($currencyId, 'currencies'); + $thousand = $currency->thousand_separator; + $decimal = $currency->decimal_separator; + + return number_format($value, $precision, $decimal, $thousand); + } + public static function formatMoney($value, $currencyId = false, $countryId = false, $decorator = false) { $value = floatval($value); diff --git a/app/Models/Account.php b/app/Models/Account.php index 446dde613a2c..8b0c6fc84ecb 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -682,6 +682,17 @@ class Account extends Eloquent return Utils::formatMoney($amount, $currencyId, $countryId, $decorator); } + public function formatNumber($amount, $precision = 0) + { + if ($this->currency_id) { + $currencyId = $this->currency_id; + } else { + $currencyId = DEFAULT_CURRENCY; + } + + return Utils::formatNumber($amount, $currencyId, $precision); + } + /** * @return mixed */ diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 75a20573ac38..cc85b0b68468 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -2755,6 +2755,15 @@ $LANG = array( 'emails' => 'Emails', 'opened' => 'Opened', 'bounced' => 'Bounced', + 'total_sent' => 'Total Sent', + 'total_opened' => 'Total Opened', + 'total_bounced' => 'Total Bounced', + 'total_spam' => 'Total Spam', + 'platforms' => 'Platforms', + 'email_clients' => 'Email Clients', + 'mobile' => 'Mobile', + 'desktop' => 'Desktop', + 'webmail' => 'Webmail', ); diff --git a/resources/views/reports/emails.blade.php b/resources/views/reports/emails.blade.php index 055f2998cc1d..03250a74f5fe 100644 --- a/resources/views/reports/emails.blade.php +++ b/resources/views/reports/emails.blade.php @@ -66,11 +66,6 @@ } } }, - title: { - display: false, - fontSize: 18, - text: '{{ trans('texts.total_revenue') }}' - }, scales: { xAxes: [{ type: 'time', @@ -164,8 +159,14 @@ function loadData() { var url = "{!! url('/reports/emails_report') !!}/" + chartStartDate.format('YYYY-MM-DD') + '/' + chartEndDate.format('YYYY-MM-DD'); $.get(url, function(response) { - //response = JSON.parse(response); loadChart(response.data); + $('#totalSentDiv').html(response.totals['sent']); + $('#totalOpenedDiv').html(response.totals['opened']); + $('#totalBouncedDiv').html(response.totals['bounced']); + //$('#totalSpamDiv').html(response.totals['spam']); + + $('#platformsTable').html(response.platforms); + $('#emailClientsTable').html(response.emailClients); }) } @@ -174,6 +175,68 @@ + +
+
+
+
+
+
+ {{ trans('texts.total_sent') }} +
+
+   +
+
+
+
+
+
+
+
+
+
+ {{ trans('texts.total_opened') }} +
+
+   +
+
+
+
+
+
+
+
+
+
+ {{ trans('texts.total_bounced') }} +
+
+   +
+
+
+
+
+ +
+
@@ -184,4 +247,35 @@
+

 

+ +
+
+
+
+

+ {{ trans('texts.platforms') }} +

+
+
+ +
+
+
+
+
+
+
+

+ {{ trans('texts.email_clients') }} +

+
+
+ +
+
+
+
+
+ @stop