Fin Stat + Export PDF

This commit is contained in:
Thibault Richy 2019-03-18 08:58:41 +01:00
parent b49772791f
commit b45c3ff5e8
21 changed files with 1003 additions and 231 deletions

2
.gitignore vendored
View file

@ -5,6 +5,8 @@
!/public/landings/.gitkeep
/public/generation/*
!/public/generation/.gitkeep
/public/export/*
!/public/export/.gitkeep
/public/coupons/*
!/public/coupons/.gitkeep
/public/images/logos/*

View file

@ -0,0 +1,116 @@
<?php
namespace App\Http\Controllers;
use App;
use Illuminate\Support\Facades\Storage;
use CpChart\Data;
use CpChart\Image;
use App\Traits\CouponTrait;
use App\Traits\GraphTrait;
use App\Campagne;
use App\Site;
use App\Coupon;
use Datetime;
use Illuminate\Http\Request;
class ExportController extends Controller
{
use CouponTrait;
use GraphTrait;
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function show(Request $request)
{
$coupon = Coupon::where(['coupon_code' => 2958008200723])->first();
$campid = 101;
$startdate = '27-02-2019';
$enddate = '11-03-2019';
$labels = $this->getLabelsForStats($startdate, $enddate);
$dataCoupon = $this->getDataForCoupon($labels, $campid, $coupon);
$sites = Site::all();
$startdate = new DateTime("first day of last month");
$startdate = $startdate->format('Y-m-d');
$enddate = date('Y-m-d');
// $pdf = App::make('dompdf.wrapper');
// $myData = new Data();
// $myData->addPoints($dataCoupon,"My Serie 1");
// $myData->addPoints($labels,"My Serie 2");
// $myData->setAxisName(0,"Coupons");
// $myData->setAbscissa("My Serie 2");
// $myPicture = new Image(700,230,$myData);
// $myPicture->setGraphArea(60,40,670,190);
// $myPicture->setFontProperties(array("FontSize"=>6));
// $myPicture->drawScale(array("DrawSubTicks"=>TRUE, 'LabelRotation'=>25));
// $myPicture->setShadow(TRUE,array("X"=>1,"Y"=>1,"R"=>0,"G"=>0,"B"=>0,"Alpha"=>10));
// $myPicture->drawSplineChart();
// $LabelSettings = array("NoTitle"=>TRUE);
// $myPicture->writeLabel("My Serie 1",0, $LabelSettings);
// $myPicture->Render('charts/test.png');
// $pdf->loadHTML('<h1 id="test" style="color:red;">Test</h1><img src="charts/test.png" />');
// return $pdf->download();
return view('export.index')->with(['sites'=> $sites, 'startdate' => $startdate, 'enddate' => $enddate]);
}
//------ AJAX Export
public function export_coupons(Request $request){
$ids = $request->input('ids');
$startdate = date('Y-m-d', strtotime($request->input('startdate')));
$enddate = date('Y-m-d', strtotime($request->input('enddate')));
$coupons = Coupon::find($ids);
$labels = $this->getLabelsForStats($startdate, $enddate);
foreach ($coupons as $coupon) {
$cpName = str_replace(' ', '', $coupon->coupon_name);
$now = strtotime(now());
$full_path = 'export/'.$cpName.'_'.$now.'.pdf';
$dataCoupon = $this->getDataForCouponAllCamp($labels, $coupon);
$coupon->couponQuantity = $this->getFullQuantity($coupon);
$coupon->couponFullPrinted = $this->getUsedQuantity($coupon);
$coupon->couponPrinted = $this->getUsedQuantityOnPeriod($coupon, $startdate, $enddate);
$pdf = App::make('dompdf.wrapper');
$myData = new Data();
$myData->addPoints($dataCoupon,"My Serie 1");
$myData->addPoints($labels,"My Serie 2");
$myData->setAxisName(0,"Coupons Diffusés");
$myData->setAbscissa("My Serie 2");
$myData->setSerieTicks("My Serie 2",2);
$serieSettings = array("R"=>229,"G"=>11,"B"=>11);
$myData->setPalette("My Serie 1",$serieSettings);
$myPicture = new Image(700,230,$myData);
$myPicture->setGraphArea(60,40,670,190);
$myPicture->setFontProperties(array("FontSize"=>10));
$myPicture->drawScale(array("DrawSubTicks"=>TRUE, 'LabelSkip'=>1, 'LabelRotation'=>25, "Mode" => SCALE_MODE_START0, "CycleBackground"=>TRUE,"GridR"=>102,"GridG"=>102,"GridB"=>102));
$myPicture->setShadow(TRUE,array("X"=>1,"Y"=>1,"R"=>0,"G"=>0,"B"=>0,"Alpha"=>10));
$myPicture->drawLineChart(array("DisplayColor"=>DISPLAY_AUTO));
$LabelSettings = array("NoTitle"=>TRUE);
$myPicture->Render('export/temp.png');
$view = view('export.template')->with(['src' => 'export/temp.png', 'coupon' => $coupon, 'startdate' => $startdate, 'enddate' => $enddate])->render();
//var_dump($view);
$pdf->loadHTML($view);
$pdf->save($full_path);
}
return json_encode($full_path);
}
}

View file

@ -7,11 +7,12 @@ use App\Campagne;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use App\Traits\CouponTrait;
use DateTime;
use App\Traits\GraphTrait;
class StatistiqueController extends Controller
{
use CouponTrait;
use GraphTrait;
/**
* Display a listing of the resource.
*
@ -91,51 +92,21 @@ class StatistiqueController extends Controller
$startdate = $request->startdate;
$enddate = $request->enddate;
$datetime1 = new DateTime($request->startdate);
$datetime2 = new DateTime($request->enddate);
$interval = $datetime1->diff($datetime2);
$days = $interval->format('%a');
// ---- Labels des graphiques
$labels = [];
for ($i=0; $i <= $days ; $i++) {
$date = date('d/m/Y', strtotime("+".$i." days", strtotime($startdate)));
array_push($labels, $date);
}
//array_reverse($labels);
// ---- Labels pour la période
$labels = $this->getLabelsForStats($startdate, $enddate);
// ---- Data pour le graphique global
$dataGlobal = [];
$test = [];
foreach ($labels as $label) {
$date = date('Y-m-d', strtotime(str_replace('/', '-', $label)));
$stat = Statistique::where(['stat_campId' => $campid])->whereDate('created_at', '=', $date)->sum('stat_couponPrinted');
$test[] = $date;
if(isset($stat)){
$dataGlobal[] = $stat;
} else {
$dataGlobal[] = 0;
}
}
$dataGlobal = $this->getDataForCamp($labels, $campid);
// ---- Data pour le graphique par coupons
$campagne = Campagne::where(['camp_id' => $campid])->first();
$coupons = $campagne->coupons;
$dataSpec = [];
foreach ($coupons as $coupon) {
$dataCoupon = [];
foreach ($labels as $label) {
$date = date('Y-m-d', strtotime(str_replace('/', '-', $label)));
$stat = Statistique::where(['stat_campId' => $campid, 'stat_couponId' => $coupon->coupon_id])->whereDate('created_at', '=', $date)->first();
if(isset($stat->stat_couponPrinted)){
$dataCoupon[] = $stat->stat_couponPrinted;
} else {
$dataCoupon[] = 0;
}
}
$dataCoupon = $this->getDataForCoupon($labels, $campid, $coupon);
$dataSpec[$coupon->coupon_code] = $dataCoupon;
}
$data = array('labels' => $labels, 'dataGlobal' => $dataGlobal, 'dataSpec' => $dataSpec);
return json_encode($data);

View file

@ -7,8 +7,9 @@ use App\Coupon;
use App\Contact;
use App\Calendrier;
use App\Mur;
use App\Statistique;
use App\Panier;
use DateTime;
trait CouponTrait {
@ -247,4 +248,27 @@ trait CouponTrait {
}
return $countPrinted;
}
public function getUsedQuantityOnPeriod(Coupon $coupon, $startdate, $enddate) {
$countPrinted = 0;
$startdate = date('Y-m-d H:i:s', strtotime($startdate));
$enddate = date('Y-m-d H:i:s', strtotime($enddate));
$campagnes = $coupon->campagnes()->get();
foreach ($campagnes as $campagne) {
if($campagne->camp_type == 0 || $campagne->camp_type == 2) { // Murs
$murs = Mur::where(['mur_campid' => $campagne->camp_id, 'mur_couponId' => $coupon->coupon_id])->whereBetween('mur_createdate', [$startdate, $enddate])->get();
$countPrinted = $countPrinted + count($murs);
} else { // Paniers
$paniers = Panier::where(['panier_campId' => $campagne->camp_id])->where(function($query) use ($startdate, $enddate){
$query->whereBetween('panier_createdate', [$startdate, $enddate])
->orWhereBetween('panier_updatedate', [$startdate, $enddate]);
})->get();
foreach ($paniers as $key => $panier) {
$panierContentCount = $panier->panierContents->sum('panier_content_printed');
$countPrinted = $countPrinted + $panierContentCount;
}
}
}
return $countPrinted;
}
}

78
app/Traits/GraphTrait.php Normal file
View file

@ -0,0 +1,78 @@
<?php
namespace App\Traits;
use App\Campagne;
use App\Coupon;
use App\Contact;
use App\Calendrier;
use App\Mur;
use App\Statistique;
use App\Panier;
use DateTime;
trait GraphTrait {
// ------ Make Labels
public function getLabelsForStats($startdate, $enddate){
// ---- Calcul de l'intervalle en jour
$datetime1 = new DateTime($startdate);
$datetime2 = new DateTime($enddate);
$interval = $datetime1->diff($datetime2);
$days = $interval->format('%a');
// ---- Labels des graphiques
$labels = [];
for ($i=0; $i <= $days ; $i++) {
$date = date('d/m/Y', strtotime("+".$i." days", strtotime($startdate)));
array_push($labels, $date);
}
return $labels;
}
// ---- Data for global graph
public function getDataForCamp($labels, $campid){
$dataGlobal = [];
foreach ($labels as $label) {
$date = date('Y-m-d', strtotime(str_replace('/', '-', $label)));
$stat = Statistique::where(['stat_campId' => $campid])->whereDate('created_at', '=', $date)->sum('stat_couponPrinted');
if(isset($stat)){
$dataGlobal[] = $stat;
} else {
$dataGlobal[] = 0;
}
}
return $dataGlobal;
}
// ---- Data for one coupon on one camp
public function getDataForCoupon($labels, $campid, $coupon){
$dataCoupon = [];
foreach ($labels as $label) {
$date = date('Y-m-d', strtotime(str_replace('/', '-', $label)));
$stat = Statistique::where(['stat_campId' => $campid, 'stat_couponId' => $coupon->coupon_id])->whereDate('created_at', '=', $date)->first();
if(isset($stat->stat_couponPrinted)){
$dataCoupon[] = $stat->stat_couponPrinted;
} else {
$dataCoupon[] = 0;
}
}
return $dataCoupon;
}
// ---- Data for one coupon all camp
public function getDataForCouponAllCamp($labels, $coupon) {
$dataCoupon = [];
foreach ($labels as $label) {
$date = date('Y-m-d', strtotime(str_replace('/', '-', $label)));
$stat = Statistique::where(['stat_couponId' => $coupon->coupon_id])->whereDate('created_at', '=', $date)->sum('stat_couponPrinted');
if(isset($stat)){
$dataCoupon[] = $stat;
} else {
$dataCoupon[] = 0;
}
}
return $dataCoupon;
}
}

View file

@ -6,12 +6,14 @@
"type": "project",
"require": {
"php": "^7.1.3",
"barryvdh/laravel-dompdf": "^0.8.4",
"doctrine/dbal": "^2.8",
"fideloper/proxy": "^4.0",
"laravel/framework": "5.7.*",
"laravel/tinker": "^1.0",
"laravelcollective/html": "^5.4.0",
"picqer/php-barcode-generator": "^0.3.0",
"szymach/c-pchart": "^3.0",
"uxweb/sweet-alert": "^2.0"
},
"require-dev": {

310
composer.lock generated
View file

@ -4,8 +4,64 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "5472aedecf7d5401ffe3f89f46979fa2",
"content-hash": "24e88d3c29349a8c1dded281fc337313",
"packages": [
{
"name": "barryvdh/laravel-dompdf",
"version": "v0.8.4",
"source": {
"type": "git",
"url": "https://github.com/barryvdh/laravel-dompdf.git",
"reference": "3fd817065e1c820b1ddace8b2bf65ca45088df4f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-dompdf/zipball/3fd817065e1c820b1ddace8b2bf65ca45088df4f",
"reference": "3fd817065e1c820b1ddace8b2bf65ca45088df4f",
"shasum": ""
},
"require": {
"dompdf/dompdf": "^0.8",
"illuminate/support": "5.5.x|5.6.x|5.7.x|5.8.x",
"php": ">=7"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "0.8-dev"
},
"laravel": {
"providers": [
"Barryvdh\\DomPDF\\ServiceProvider"
],
"aliases": {
"PDF": "Barryvdh\\DomPDF\\Facade"
}
}
},
"autoload": {
"psr-4": {
"Barryvdh\\DomPDF\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Barry vd. Heuvel",
"email": "barryvdh@gmail.com"
}
],
"description": "A DOMPDF Wrapper for Laravel",
"keywords": [
"dompdf",
"laravel",
"pdf"
],
"time": "2019-02-26T18:07:43+00:00"
},
{
"name": "dnoegel/php-xdg-base-dir",
"version": "0.1",
@ -388,6 +444,72 @@
],
"time": "2014-09-09T13:34:57+00:00"
},
{
"name": "dompdf/dompdf",
"version": "v0.8.3",
"source": {
"type": "git",
"url": "https://github.com/dompdf/dompdf.git",
"reference": "75f13c700009be21a1965dc2c5b68a8708c22ba2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/75f13c700009be21a1965dc2c5b68a8708c22ba2",
"reference": "75f13c700009be21a1965dc2c5b68a8708c22ba2",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-mbstring": "*",
"phenx/php-font-lib": "0.5.*",
"phenx/php-svg-lib": "0.3.*",
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8|^5.5|^6.5",
"squizlabs/php_codesniffer": "2.*"
},
"suggest": {
"ext-gd": "Needed to process images",
"ext-gmagick": "Improves image processing performance",
"ext-imagick": "Improves image processing performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-develop": "0.7-dev"
}
},
"autoload": {
"psr-4": {
"Dompdf\\": "src/"
},
"classmap": [
"lib/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-2.1"
],
"authors": [
{
"name": "Fabien Ménager",
"email": "fabien.menager@gmail.com"
},
{
"name": "Brian Sweeney",
"email": "eclecticgeek@gmail.com"
},
{
"name": "Gabriel Bull",
"email": "me@gabrielbull.com"
}
],
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
"homepage": "https://github.com/dompdf/dompdf",
"time": "2018-12-14T02:40:31+00:00"
},
{
"name": "dragonmantank/cron-expression",
"version": "v2.2.0",
@ -1266,6 +1388,83 @@
],
"time": "2018-07-02T15:55:56+00:00"
},
{
"name": "phenx/php-font-lib",
"version": "0.5.1",
"source": {
"type": "git",
"url": "https://github.com/PhenX/php-font-lib.git",
"reference": "760148820110a1ae0936e5cc35851e25a938bc97"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PhenX/php-font-lib/zipball/760148820110a1ae0936e5cc35851e25a938bc97",
"reference": "760148820110a1ae0936e5cc35851e25a938bc97",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "^4.8"
},
"type": "library",
"autoload": {
"psr-4": {
"FontLib\\": "src/FontLib"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Fabien Ménager",
"email": "fabien.menager@gmail.com"
}
],
"description": "A library to read, parse, export and make subsets of different types of font files.",
"homepage": "https://github.com/PhenX/php-font-lib",
"time": "2017-09-13T16:14:37+00:00"
},
{
"name": "phenx/php-svg-lib",
"version": "v0.3.2",
"source": {
"type": "git",
"url": "https://github.com/PhenX/php-svg-lib.git",
"reference": "ccc46ef6340d4b8a4a68047e68d8501ea961442c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PhenX/php-svg-lib/zipball/ccc46ef6340d4b8a4a68047e68d8501ea961442c",
"reference": "ccc46ef6340d4b8a4a68047e68d8501ea961442c",
"shasum": ""
},
"require": {
"sabberworm/php-css-parser": "8.1.*"
},
"require-dev": {
"phpunit/phpunit": "~5.0"
},
"type": "library",
"autoload": {
"psr-0": {
"Svg\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL-3.0"
],
"authors": [
{
"name": "Fabien Ménager",
"email": "fabien.menager@gmail.com"
}
],
"description": "A library to read, parse and export to PDF SVG files.",
"homepage": "https://github.com/PhenX/php-svg-lib",
"time": "2018-06-03T10:10:03+00:00"
},
{
"name": "picqer/php-barcode-generator",
"version": "v0.3",
@ -1635,6 +1834,50 @@
],
"time": "2018-07-19T23:38:55+00:00"
},
{
"name": "sabberworm/php-css-parser",
"version": "8.1.0",
"source": {
"type": "git",
"url": "https://github.com/sabberworm/PHP-CSS-Parser.git",
"reference": "850cbbcbe7fbb155387a151ea562897a67e242ef"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/850cbbcbe7fbb155387a151ea562897a67e242ef",
"reference": "850cbbcbe7fbb155387a151ea562897a67e242ef",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"require-dev": {
"phpunit/phpunit": "*"
},
"type": "library",
"autoload": {
"psr-0": {
"Sabberworm\\CSS": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Raphael Schweikert"
}
],
"description": "Parser for CSS Files written in PHP",
"homepage": "http://www.sabberworm.com/blog/2010/6/10/php-css-parser",
"keywords": [
"css",
"parser",
"stylesheet"
],
"time": "2016-07-19T19:14:21+00:00"
},
{
"name": "swiftmailer/swiftmailer",
"version": "v6.1.3",
@ -2566,6 +2809,71 @@
],
"time": "2018-08-02T09:24:26+00:00"
},
{
"name": "szymach/c-pchart",
"version": "v3.0.7",
"source": {
"type": "git",
"url": "https://github.com/szymach/c-pchart.git",
"reference": "cff756ac9cb87671b4833c5935c1c7bd12947db0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/szymach/c-pchart/zipball/cff756ac9cb87671b4833c5935c1c7bd12947db0",
"reference": "cff756ac9cb87671b4833c5935c1c7bd12947db0",
"shasum": ""
},
"require": {
"ext-gd": "*",
"php": ">=5.4"
},
"require-dev": {
"codeception/codeception": "^2.4",
"phpunit/phpunit": "^4.8|^7.1",
"squizlabs/php_codesniffer": "^2.8|^3.3"
},
"type": "project",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev",
"2.0": "2.0.x-dev"
}
},
"autoload": {
"psr-4": {
"CpChart\\": "src/"
},
"files": [
"constants.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0-only"
],
"authors": [
{
"name": "Jean-Damien Pogolotti",
"homepage": "http://www.pchart.net",
"role": "Creator of the original pChart library"
},
{
"name": "Piotr Szymaszek",
"homepage": "https://github.com/szymach",
"role": "Developer of the CpChart wrapper package"
}
],
"description": "Port of \"pChart\" library into PHP 5+",
"homepage": "https://github.com/szymach/c-pchart",
"keywords": [
"CpChart",
"c-pChart",
"charts",
"pchart",
"statistics"
],
"time": "2018-11-22T11:28:00+00:00"
},
{
"name": "tijsverkoyen/css-to-inline-styles",
"version": "2.2.1",

View file

@ -161,7 +161,7 @@ return [
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
Barryvdh\DomPDF\ServiceProvider::class,
],
/*
@ -213,7 +213,7 @@ return [
'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,
'Debugbar' => Barryvdh\Debugbar\Facade::class,
'PDF' => Barryvdh\DomPDF\Facade::class,
],
];

254
public/css/app.css vendored
View file

@ -172,6 +172,13 @@ h5 i {
margin-right: 10px;
}
h5 {
font-family: 'Nunito-ExtraLight', sans-serif;
font-size: 1em;
color: #de9700;
margin: 20px 0 10px 0;
}
p {
font-family: 'Nunito-ExtraLight', sans-serif;
color: #adb5bd;
@ -6933,9 +6940,17 @@ main section .statistiquesContent .couponStats .couponStatsDetail h4 {
color: #adb5bd;
font-weight: bold;
background-color: #212121;
}
main section .statistiquesContent .couponStats .couponStatsDetail h4 span {
cursor: pointer;
}
main section .statistiquesContent .couponStats .couponStatsDetail h4 span:first-child {
width: 95%;
display: block;
}
main section .statistiquesContent .couponStats .couponStatsDetail h4 .couponLegend {
position: absolute;
display: inline-block;
@ -6944,6 +6959,17 @@ main section .statistiquesContent .couponStats .couponStatsDetail h4 .couponLege
width: 20px;
height: 20px;
border-radius: 50%;
overflow: hidden;
}
main section .statistiquesContent .couponStats .couponStatsDetail h4 .couponLegend .line {
width: 35px;
height: 20px;
border-bottom: 3px solid red;
-webkit-transform: translateY(-20px) translateX(5px) rotate(27deg);
position: absolute;
top: 9px;
left: -10px;
}
main section .statistiquesContent .couponStats .couponStatsDetail .content {
@ -6985,108 +7011,48 @@ main section .statistiquesContent .graphStats h3 {
margin: 30px 0 20px 0;
}
main section .statistiquesContent .graphStats h3 i {
float: right;
margin-left: 10px;
cursor: pointer;
}
main section .selector-export {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: end;
-ms-flex-pack: end;
justify-content: flex-end;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
main section .selector-export h4 {
margin: 0;
margin-right: 20px;
}
main section .selector-export input {
min-width: 150px;
}
main section .selector-export input#startdate {
margin-right: 20px;
}
main section .export-btn {
text-align: right;
margin-top: 20px;
}
#coupons-list {
background-color: #2d2d2d;
padding: 20px;
min-width: 550px;
}
#coupons-list .inputGroup {
background-color: #393939;
display: block;
margin: 2px 0;
position: relative;
}
#coupons-list .inputGroup.notPublished {
background-color: rgba(223, 0, 0, 0.3);
}
#coupons-list .inputGroup label {
padding: 8px 30px;
width: 100%;
display: block;
text-align: left;
color: #adb5bd;
cursor: pointer;
position: relative;
z-index: 2;
-webkit-transition: color 200ms ease-in;
transition: color 200ms ease-in;
overflow: hidden;
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-family: 'Nunito-Regular', sans-serif;
}
#coupons-list .inputGroup label:before {
width: 10px;
height: 10px;
border-radius: 50%;
content: '';
background-color: #212121;
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%) scale3d(1, 1, 1);
transform: translate(-50%, -50%) scale3d(1, 1, 1);
-webkit-transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
opacity: 0;
z-index: -1;
}
#coupons-list .inputGroup label:after {
width: 20px;
height: 20px;
content: '';
border: 1px solid #de9700;
background-color: #393939;
background-image: url("data:image/svg+xml,%3Csvg width='32' height='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.414 11L4 12.414l5.414 5.414L20.828 6.414 19.414 5l-10 10z' fill='%23393939' fill-rule='nonzero'/%3E%3C/svg%3E ");
background-repeat: no-repeat;
background-position: -3px -1px;
z-index: 2;
position: absolute;
right: 30px;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
cursor: pointer;
-webkit-transition: all 200ms ease-in;
transition: all 200ms ease-in;
}
#coupons-list .inputGroup input:checked ~ label {
color: #fff;
}
#coupons-list .inputGroup input:checked ~ label:before {
-webkit-transform: translate(-50%, -50%) scale3d(130, 130, 1);
transform: translate(-50%, -50%) scale3d(130, 130, 1);
opacity: 1;
}
#coupons-list .inputGroup input:checked ~ label:after {
background-color: #de9700;
border-color: #de9700;
}
#coupons-list .inputGroup input {
width: 32px;
height: 32px;
-webkit-box-ordinal-group: 2;
-ms-flex-order: 1;
order: 1;
z-index: 2;
position: absolute;
right: 30px;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
cursor: pointer;
visibility: hidden;
}
#coupons-list input[type=submit] {
padding: 5px 10px;
background-color: #de9700;
@ -7197,3 +7163,99 @@ main section .statistiquesContent .graphStats h3 {
cursor: pointer;
margin-right: 15px;
}
.inputGroup {
background-color: #393939;
display: block;
margin: 2px 0;
position: relative;
}
.inputGroup.notPublished {
background-color: rgba(223, 0, 0, 0.3);
}
.inputGroup label {
padding: 8px 30px;
width: 100%;
display: block;
text-align: left;
color: #adb5bd;
cursor: pointer;
position: relative;
z-index: 2;
-webkit-transition: color 200ms ease-in;
transition: color 200ms ease-in;
overflow: hidden;
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-family: 'Nunito-Regular', sans-serif;
}
.inputGroup label:before {
width: 10px;
height: 10px;
border-radius: 50%;
content: '';
background-color: #212121;
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%) scale3d(1, 1, 1);
transform: translate(-50%, -50%) scale3d(1, 1, 1);
-webkit-transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
transition: all 300ms cubic-bezier(0.4, 0, 0.2, 1);
opacity: 0;
z-index: -1;
}
.inputGroup label:after {
width: 20px;
height: 20px;
content: '';
border: 1px solid #de9700;
background-color: #393939;
background-image: url("data:image/svg+xml,%3Csvg width='32' height='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.414 11L4 12.414l5.414 5.414L20.828 6.414 19.414 5l-10 10z' fill='%23393939' fill-rule='nonzero'/%3E%3C/svg%3E ");
background-repeat: no-repeat;
background-position: -3px -1px;
z-index: 2;
position: absolute;
right: 30px;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
cursor: pointer;
-webkit-transition: all 200ms ease-in;
transition: all 200ms ease-in;
}
.inputGroup input:checked ~ label {
color: #fff;
}
.inputGroup input:checked ~ label:before {
-webkit-transform: translate(-50%, -50%) scale3d(130, 130, 1);
transform: translate(-50%, -50%) scale3d(130, 130, 1);
opacity: 1;
}
.inputGroup input:checked ~ label:after {
background-color: #de9700;
border-color: #de9700;
}
.inputGroup input {
width: 32px;
height: 32px;
-webkit-box-ordinal-group: 2;
-ms-flex-order: 1;
order: 1;
z-index: 2;
position: absolute;
right: 30px;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
cursor: pointer;
visibility: hidden;
}

0
public/export/.gitkeep Normal file
View file

2
public/js/app.js vendored

File diff suppressed because one or more lines are too long

View file

@ -1,3 +0,0 @@
<?php
phpinfo();
?>

4
resources/js/app.js vendored
View file

@ -296,9 +296,9 @@ $('.couponDetail').each(function(){
})
$('body').on('click', '.couponStats h4', function(event){
$('body').on('click', '.expand', function(event){
event.preventDefault();
var contentDiv = $(this).parent().find('.content')
var contentDiv = $(this).parent().parent().find('.content')
if(contentDiv.css('display') == 'none'){
contentDiv.slideDown();

View file

@ -658,7 +658,13 @@ table {
color:$lightgrey;
font-weight:bold;
background-color:$darkgrey;
cursor:pointer;
span {
cursor:pointer;
&:first-child {
width: 95%;
display: block;
}
}
.couponLegend {
position:absolute;
display:inline-block;
@ -667,6 +673,19 @@ table {
width:20px;
height:20px;
border-radius:50%;
overflow:hidden;
.line {
width: 35px;
height: 20px;
border-bottom: 3px solid red;
-webkit-transform:
translateY(-20px)
translateX(5px)
rotate(27deg);
position: absolute;
top: 9px;
left: -10px;
}
}
}
.content {
@ -696,6 +715,31 @@ table {
width:55%;
h3 {
margin:30px 0 20px 0;
i {
float:right;
margin-left:10px;
cursor: pointer;
}
}
}
}
.selector-export {
display:flex;
justify-content:flex-end;
align-items:center;
h4 {
margin:0;
margin-right:20px;
}
input {
min-width: 150px;
&#startdate {
margin-right:20px;
}
}
}
.export-btn {
text-align:right;
margin-top:20px;
}

View file

@ -3,89 +3,7 @@
padding:20px;
min-width:550px;
.inputGroup {
background-color: $grey3;
display: block;
margin: 2px 0;
position: relative;
&.notPublished {
background-color:rgba(223, 0, 0, 0.3);
}
label {
padding: 8px 30px;
width: 100%;
display: block;
text-align: left;
color: $lightgrey;
cursor: pointer;
position: relative;
z-index: 2;
transition: color 200ms ease-in;
overflow: hidden;
box-sizing: border-box;
font-family: 'Nunito-Regular', sans-serif;
&:before {
width: 10px;
height: 10px;
border-radius: 50%;
content: '';
background-color: $darkgrey;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) scale3d(1, 1, 1);
transition: all 300ms cubic-bezier(0.4, 0.0, 0.2, 1);
opacity: 0;
z-index: -1;
}
&:after {
width: 20px;
height: 20px;
content: '';
border: 1px solid $orange;
background-color: $grey3;
background-image: url("data:image/svg+xml,%3Csvg width='32' height='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.414 11L4 12.414l5.414 5.414L20.828 6.414 19.414 5l-10 10z' fill='%23393939' fill-rule='nonzero'/%3E%3C/svg%3E ");
background-repeat: no-repeat;
background-position: -3px -1px;
//border-radius: 50%;
z-index: 2;
position: absolute;
right: 30px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
transition: all 200ms ease-in;
}
}
input:checked ~ label {
color: #fff;
&:before {
transform: translate(-50%, -50%) scale3d(130, 130, 1);
opacity: 1;
}
&:after {
background-color: $orange;
border-color: $orange;
}
}
input {
width: 32px;
height: 32px;
order: 1;
z-index: 2;
position: absolute;
right: 30px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
visibility: hidden;
}
}
input[type=submit] {
padding:5px 10px;
background-color: $orange;
@ -186,4 +104,88 @@
cursor:pointer;
margin-right:15px;
}
}
.inputGroup {
background-color: $grey3;
display: block;
margin: 2px 0;
position: relative;
&.notPublished {
background-color:rgba(223, 0, 0, 0.3);
}
label {
padding: 8px 30px;
width: 100%;
display: block;
text-align: left;
color: $lightgrey;
cursor: pointer;
position: relative;
z-index: 2;
transition: color 200ms ease-in;
overflow: hidden;
box-sizing: border-box;
font-family: 'Nunito-Regular', sans-serif;
&:before {
width: 10px;
height: 10px;
border-radius: 50%;
content: '';
background-color: $darkgrey;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%) scale3d(1, 1, 1);
transition: all 300ms cubic-bezier(0.4, 0.0, 0.2, 1);
opacity: 0;
z-index: -1;
}
&:after {
width: 20px;
height: 20px;
content: '';
border: 1px solid $orange;
background-color: $grey3;
background-image: url("data:image/svg+xml,%3Csvg width='32' height='32' viewBox='0 0 32 32' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5.414 11L4 12.414l5.414 5.414L20.828 6.414 19.414 5l-10 10z' fill='%23393939' fill-rule='nonzero'/%3E%3C/svg%3E ");
background-repeat: no-repeat;
background-position: -3px -1px;
//border-radius: 50%;
z-index: 2;
position: absolute;
right: 30px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
transition: all 200ms ease-in;
}
}
input:checked ~ label {
color: #fff;
&:before {
transform: translate(-50%, -50%) scale3d(130, 130, 1);
opacity: 1;
}
&:after {
background-color: $orange;
border-color: $orange;
}
}
input {
width: 32px;
height: 32px;
order: 1;
z-index: 2;
position: absolute;
right: 30px;
top: 50%;
transform: translateY(-50%);
cursor: pointer;
visibility: hidden;
}
}

View file

@ -126,6 +126,14 @@ h5 {
}
}
h5 {
font-family: 'Nunito-ExtraLight', sans-serif;
font-size:1em;
//font-weight:bold;
color:$orange;
margin: 20px 0 10px 0;
}
p {
font-family: 'Nunito-ExtraLight', sans-serif;
color:$lightgrey;

View file

@ -0,0 +1,69 @@
@extends('layouts.main')
@section('content')
<h2><i class="fas fa-file-export"></i> Export des données coupons</h2>
<div class="selector-export">
<h4>Période :</h4>
<input type="date" name="startdate" id="startdate" value="{{ $startdate }}">
<input type="date" name="enddate" id="enddate" value="{{ $enddate }}">
<input type="hidden" name="csrf" id="csrf" value="<?php echo csrf_token(); ?>">
<a href="#" class="add-button export-data"><i class="fas fa-file-export"></i> Exporter les données</a>
</div>
@foreach ($sites as $site)
<h4>{{ $site->site_nom }} ({{ $site->site_id }})</h4>
@if (isset($site->coupons) && $site->coupons->count()>0)
@foreach ($site->coupons as $coupon)
<div class="inputGroup">
<input id="coupon[{{$coupon->coupon_id}}]" name="coupon[{{$coupon->coupon_id}}]" type="checkbox" value="{{$coupon->coupon_id}}"/>
<label for="coupon[{{$coupon->coupon_id}}]">{{$coupon->coupon_name}}</label>
</div>
@endforeach
@endif
@endforeach
<div class="export-btn">
<a href="#" class="add-button export-data"><i class="fas fa-file-export"></i> Exporter les données</a>
<a href="" download class="dl-pdf"></a>
</div>
@endsection
@section('scripts')
<script>
$('.export-data').on('click', function(event){
event.preventDefault();
let ids = [];
$('.inputGroup input').each(function(event){
if($(this).is(':checked')){
ids.push($(this).val());
}
})
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('#csrf').val()
}
});
$.ajax({
url: '/exportCoupon',
type: 'POST',
data: {
ids: ids,
startdate: $('#startdate').val(),
enddate: $('#enddate').val(),
},
dataType: 'JSON',
success: function (response) {
$('.dl-pdf').attr("href", '/'+response);
$('.dl-pdf').get(0).click();
},
error: function (e) {
console.log(e.responseText);
}
});
})
</script>
@endsection

View file

@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="font-family:Helvetica;">
<div class="wrapper">
<h1 style="text-align:center; margin-bottom:5px;">MesBR.eu</h1>
<h2 style="text-align:center; margin:5px;">{{ $coupon->coupon_name }}</h2>
<h3 style="margin-bottom:80px; margin-top:5px; text-align:center;">Diffusions du {{ date('d/m/Y', strtotime($startdate)) }} au {{ date('d/m/Y', strtotime($enddate)) }}</h3>
<img style="width:80%; margin-left:10%; margin-bottom:20px;" src="{{ $coupon->coupon_image }}" alt="">
<h3 style="margin:0; margin-bottom:10px;">Détail du coupon</h3>
<table style="font-size:12px;">
<tr style="background-color:#2d2d2d; color:#FFF; text-align:center;">
<th style="width:25%">Nom</th>
<th style="width:15%">Code</th>
<th style="width:10%">Quantité totale</th>
<th style="width:10%">Qté totale diffusée</th>
<th style="width:15%">Date de début de diffusion</th>
<th style="width:15%">Date de fin de diffusion</th>
</tr>
<tr style="background-color:#adb5bd; color:#000; text-align:center;">
<td style="padding:5px 0;">{{ $coupon->coupon_name }}</td>
<td>{{ $coupon->coupon_code }}</td>
<td>{{ $coupon->couponQuantity }}</td>
<td>{{ $coupon->couponFullPrinted }}</td>
@if($coupon->coupon_maxdatediffusion != null)
<td>{{ date('d/m/Y', strtotime($coupon->coupon_mindatediffusion)) }}</td>
@else
<td>n/c</td>
@endif
@if($coupon->coupon_maxdatediffusion != null)
<td>{{ date('d/m/Y', strtotime($coupon->coupon_maxdatediffusion)) }}</td>
@else
<td>n/c</td>
@endif
</tr>
</table>
<h3>Graphique de diffusion sur la période du {{ date('d/m/Y', strtotime($startdate)) }} au {{ date('d/m/Y', strtotime($enddate)) }}</h3>
<p style="margin-bottom:20px;">Nombre de coupons diffusés : {{ $coupon->couponPrinted }}</p>
<img src="{{ $src }}" alt="">
</div>
</body>
</html>

View file

@ -10,6 +10,7 @@
@endif
@if(Auth::user()->roles == "superadmin")
<a href="{{ route('maintenance.show') }}" class="menu-item @if(session()->get('active_route') == 'maintenance') active @endif"><i class="fas fa-cogs"></i> <span>Maintenance</span></a>
<a href="{{ route('export.coupons') }}" class="menu-item @if(session()->get('active_route') == 'export') active @endif"><i class="fas fa-file-export"></i> <span>Exportation</span></a>
@endif
<a href="{{ url('bo/logout') }}" class="menu-item logout"><i class="fas fa-sign-out-alt"></i> <span>Déconnexion</span></a>
</div>

View file

@ -74,7 +74,7 @@
</div>
@foreach ($campagne->coupons as $coupon)
<div class="couponStatsDetail">
<h4>{{ $coupon->coupon_name }} <span style="background-color:{{$coupon->color}}" class="couponLegend"></span></h4>
<h4><span class="expand">{{ $coupon->coupon_name }}</span> <span style="background-color:{{$coupon->color}}" class="couponLegend" data-label="{{ $coupon->coupon_name }}"></span></h4>
<div class="content">
<figure>
<a href="{{ asset($coupon->coupon_image) }}" data-fancybox="images" data-caption="{{ $coupon->coupon_name }}"><img src="{{ asset($coupon->coupon_image) }}" alt=""></a>
@ -111,7 +111,7 @@
@endforeach
</div>
<div class="graphStats">
<h3>Consommation par coupons</h3>
<h3>Consommation par coupons <i class="fas fa-eye"></i><i class="fas fa-eye-slash"></i></h3>
<canvas id="myChart" height="150" width="300"></canvas>
</div>
</div>
@ -120,6 +120,7 @@
@section('scripts')
<script src="{{ asset('js/Chart.js') }}" charset="utf-8"></script>
<script>
var myLine;
function load_graphs(campid, startdate, enddate){
$.ajaxSetup({
headers: {
@ -163,7 +164,7 @@
}
}
var ctxGlobal = document.getElementById("myChartGlobal").getContext('2d');
window.myLineGlobal = new Chart(ctxGlobal, configGlobal);
var myLineGlobal = new Chart(ctxGlobal, configGlobal);
//Mise en place du graphique spec
var dataSpecCp = [];
@ -188,7 +189,7 @@
maintainAspectRatio: true,
responsive: true,
legend: {
display:true,
display:false,
position:'bottom',
},
title: {
@ -198,7 +199,7 @@
}
}
var ctx = document.getElementById("myChart").getContext('2d');
window.myLine = new Chart(ctx, config);
myLine = new Chart(ctx, config);
},
error: function (e) {
console.log(e.responseText);
@ -208,8 +209,44 @@
window.onload = function() {
load_graphs($('#reloader').attr('data-campid'), $('#startdate').val(), $('#enddate').val());
}
// ---- SHOW ALL
$('.fa-eye').on('click', function(){
$('.couponLegend').each(function(){
$(this).find('.line').remove();
})
myLine.data.datasets.forEach(function(ds) {
ds.hidden = false;
});
myLine.update();
})
// ---- HIDE ALL
$('.fa-eye-slash').on('click', function(){
$('.couponLegend').each(function(){
$(this).append('<div class="line"></div>');
})
myLine.data.datasets.forEach(function(ds) {
ds.hidden = true;
});
myLine.update();
})
$('.couponStats').on('click', '.couponLegend', function(e){
if($(this).find('.line').length){
$(this).find('.line').remove();
} else {
$(this).append('<div class="line"></div>');
}
var label = $(this).attr('data-label');
myLine.data.datasets.forEach(function(ds) {
if(ds.label == label){
ds.hidden = !ds.hidden;
}
});
myLine.update();
})
}
$('.reload-stats').on('click', function(event){
var campid = $(this).attr('data-campid');

View file

@ -44,6 +44,8 @@ Route::group(['prefix' => 'bo', 'middleware' => ['auth', 'saveroute']], function
// ---- Routes pour la gestion des mails d'alerte
Route::post('new-notification', array('uses' => 'CampagneController@saveNotification'));
Route::delete('delete-notification/{id}', array('uses' => 'CampagneController@deleteNotification'))->name('campagne.deleteNotif');
// ---- Route Export PDF
Route::get('export', 'ExportController@show')->name('export.coupons');
});
// ---- Routes Ajax:
@ -73,6 +75,8 @@ Route::group(['prefix' => 'bo', 'middleware' => ['auth', 'saveroute']], function
Route::post('/cleanBaskets', 'AjaxController@clean_baskets');
// ---- Statistiques
Route::post('/loadStat', 'StatistiqueController@load_stats');
// ---- Export Coupons
Route::post('/exportCoupon', 'ExportController@export_coupons');
// ---- Routes spécifiques : API
Route::any('/{param?}', function ($param = null) {