Fix on invoices, add delivery reference, wip on dashboard concurrency requests designed on template

This commit is contained in:
Ludovic CANDELLIER
2023-02-17 00:05:03 +01:00
parent 878ec7a8f2
commit 8e571de523
26 changed files with 555 additions and 130 deletions

View File

@@ -347,8 +347,14 @@ module.exports = function(grunt) {
}, },
{ {
expand: true, expand: true,
cwd: 'build/Suite/js/widgets/daterangepicker/Lang', cwd: 'node_modules/daterangepicker/',
src: ['**'], src: ['daterangepicker.css'],
dest: 'public/assets/plugins/daterangepicker',
},
{
expand: true,
cwd: 'node_modules/daterangepicker/',
src: ['daterangepicker.js'],
dest: 'public/assets/plugins/daterangepicker', dest: 'public/assets/plugins/daterangepicker',
}, },
{ {
@@ -568,6 +574,7 @@ module.exports = function(grunt) {
dist: { dist: {
files: ['build/js/*', 'build/css/*'], files: ['build/js/*', 'build/css/*'],
tasks: ['concat', 'copy'] tasks: ['concat', 'copy']
// tasks: ['concat']
} }
}, },
}); });

View File

@@ -13,9 +13,13 @@ class HomeController extends Controller
$this->middleware('auth'); $this->middleware('auth');
} }
public function index() public function index(Request $request, $period = false)
{ {
$data = Dashboards::getStats(); $data = $request->all();
$start = $request->input('start');
$end = $request->input('end');
$data = Dashboards::getStats($start, $end);
// dump($data);
return view('Admin.Shop.Dashboard.index', $data); return view('Admin.Shop.Dashboard.index', $data);
} }
} }

View File

@@ -5,33 +5,20 @@ namespace App\Http\Controllers\Admin\Shop;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Repositories\Core\Auth\Users; use App\Repositories\Shop\Dashboards;
class DashboardController extends Controller class DashboardController extends Controller
{ {
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct() public function __construct()
{ {
$this->middleware('auth'); $this->middleware('auth');
} }
/** public function index(Request $request)
* Show the application dashboard.
*
* @return
*/
public function index()
{ {
$data = []; $data = $request->all();
$data = Dashboards::getStats($data);
if (Users::hasRole('admin')) { dump($data);
$dashboard = 'dashboard';
$data = [];
}
return view('Admin.Shop.Dashboard.index', $data); return view('Admin.Shop.Dashboard.index', $data);
} }

View File

@@ -28,18 +28,19 @@ class InvoiceController extends Controller
public function show($id) public function show($id)
{ {
$data = Invoices::get($id); $data['invoice'] = Invoices::get($id)->toArray();
return view('Admin.Shop.Invoices.view', $data); return view('Admin.Shop.Invoices.view', $data);
} }
public function edit($id) public function edit($id)
{ {
$data['customer'] = Invoices::get($id)->toArray(); $data['invoice'] = Invoices::get($id, ['order.customer', 'order.address', 'order.detail'])->toArray();
$data['statuses'] = Invoices::statuses();
return view('Admin.Shop.Invoices.edit', $data); return view('Admin.Shop.Invoices.edit', $data);
} }
public function destroy($id) public function destroy($id)
{ {
return Invoices::destroy($id); return Invoices::delete($id);
} }
} }

View File

@@ -31,4 +31,14 @@ class Invoice extends Model
{ {
return $this->belongsToThrough(Customer::class, Order::class, null, '', [Customer::class => 'customer_id', Order::class => 'order_id']); return $this->belongsToThrough(Customer::class, Order::class, null, '', [Customer::class => 'customer_id', Order::class => 'order_id']);
} }
public function scopeByUUID($query, $uuid)
{
return $query->where('uuid', $uuid);
}
public function scopeByPeriod($query, $start, $end)
{
return $query->whereBetween('created_at', [$start, $end]);
}
} }

View File

@@ -46,6 +46,11 @@ class Order extends Model
return $this->belongsTo(SaleChannel::class); return $this->belongsTo(SaleChannel::class);
} }
public function scopeByUUID($query, $uuid)
{
return $query->where('uuid', $uuid);
}
public function scopeByCustomer($query, $customer_id) public function scopeByCustomer($query, $customer_id)
{ {
return $query->where('customer_id', $customer_id); return $query->where('customer_id', $customer_id);
@@ -56,6 +61,21 @@ class Order extends Model
return $query->where('delivery_id', $delivery_id); return $query->where('delivery_id', $delivery_id);
} }
public function scopePreparation($query)
{
return $query->byStatus(1);
}
public function scopeSended($query)
{
return $query->byStatus(2);
}
public function scopeReceived($query)
{
return $query->byStatus(3);
}
public function scopeByStatus($query, $status) public function scopeByStatus($query, $status)
{ {
return $query->where('status', $status); return $query->where('status', $status);
@@ -65,4 +85,9 @@ class Order extends Model
{ {
return $query->where('payment_type', $payment_type); return $query->where('payment_type', $payment_type);
} }
public function scopeByPeriod($query, $start, $end, $field = 'created_at')
{
return $query->whereBetween($field, [$start, $end]);
}
} }

View File

@@ -12,6 +12,59 @@ use function League\Period\interval_after;
class DateRange class DateRange
{ {
public static function today()
{
return self::previousDay(0);
}
public static function currentWeek()
{
return self::previousWeek(0);
}
public static function currentMonth()
{
return self::previousMonth(0);
}
public static function currentYear()
{
return self::previousYear(0);
}
public static function previousDay($nb = 1)
{
return [
'start' => Carbon::now()->subDay($nb)->startOfDay(),
'end' => Carbon::now()->subDay($nb)->endOfDay(),
];
}
public static function previousWeek($nb = 1)
{
return [
'start' => Carbon::now()->subWeek($nb)->startOfWeek(),
'end' => Carbon::now()->subWeek($nb)->endOfWeek(),
];
}
public static function previousMonth($nb = 1)
{
return [
'start' => Carbon::now()->subMonth($nb)->startOfMonth(),
'end' => Carbon::now()->subMonth($nb)->endOfMonth(),
];
}
public static function previousYear($nb = 1)
{
return [
'start' => Carbon::now()->subYear($nb)->startOfYear(),
'end' => Carbon::now()->subYear($nb)->endOfYear(),
];
}
public static function getPeriodsLastMonthWithLabels($nb, $with_actual = true) public static function getPeriodsLastMonthWithLabels($nb, $with_actual = true)
{ {
$periods = DateRange::PeriodsToCarbon(DateRange::getPeriodsLastMonth($nb, $with_actual)); $periods = DateRange::PeriodsToCarbon(DateRange::getPeriodsLastMonth($nb, $with_actual));
@@ -30,7 +83,7 @@ class DateRange
public static function getPeriodsLastMonth($nb = 1, $with_actual = true) public static function getPeriodsLastMonth($nb = 1, $with_actual = true)
{ {
$end = $with_actual ? Carbon::now()->endOfMonth() : self::lastMonth(); $end = $with_actual ? Carbon::now()->endOfMonth() : self::lastMonth();
$begin = ($nb == 1) ? $end->copy()->startOfMonth() : $end->copy()->startOfMonth()->subMonth($nb-1); $begin = ($nb == 1) ? $end->copy()->startOfMonth() : $end->copy()->startOfMonth()->subMonth($nb - 1);
$t = self::getPeriodsbyMonth($begin, $end); $t = self::getPeriodsbyMonth($begin, $end);
return self::getPeriodsbyMonth($begin, $end); return self::getPeriodsbyMonth($begin, $end);
} }
@@ -58,14 +111,14 @@ class DateRange
{ {
$end = $with_actual ? Carbon::now()->endOfWeek() : self::lastWeek(); $end = $with_actual ? Carbon::now()->endOfWeek() : self::lastWeek();
$begin = $end->copy()->subWeek($nb); $begin = $end->copy()->subWeek($nb);
return static::getPeriodsbyWeek($begin, $end); return self::getPeriodsbyWeek($begin, $end);
} }
public static function getPeriodsLastDay($nb = 1, $with_actual = true) public static function getPeriodsLastDay($nb = 1, $with_actual = true)
{ {
$end = $with_actual ? Carbon::now()->endOfDay() : static::lastDay(); $end = $with_actual ? Carbon::now()->endOfDay() : static::lastDay();
$begin = $end->copy()->subDay($nb); $begin = $end->copy()->subDay($nb);
return static::getPeriodsbyDay($begin, $end); return self::getPeriodsbyDay($begin, $end);
} }
public static function byDay() public static function byDay()
@@ -92,16 +145,16 @@ class DateRange
{ {
$quarter = Carbon::now()->quarter; $quarter = Carbon::now()->quarter;
switch ($quarter) { switch ($quarter) {
case 1: case 1:
case 2: case 2:
$date = Carbon::now()->startOfYear(); $date = Carbon::now()->startOfYear();
break; break;
case 3: case 3:
$date = Carbon::now()->startOfQuarter(); $date = Carbon::now()->startOfQuarter();
break; break;
case 4: case 4:
$date = Carbon::now()->subMonth(3)->startOfQuarter(); $date = Carbon::now()->subMonth(3)->startOfQuarter();
break; break;
} }
return [$date, $date->addMonth(6)]; return [$date, $date->addMonth(6)];
} }
@@ -143,7 +196,7 @@ class DateRange
public static function getPeriods($begin, $end, $duration, $interval = 1) public static function getPeriods($begin, $end, $duration, $interval = 1)
{ {
$period = new Period($begin, $end); $period = new Period($begin, $end, $interval);
foreach ($period->getDatePeriod($duration) as $day) { foreach ($period->getDatePeriod($duration) as $day) {
$daterange[] = interval_after($day, $duration); $daterange[] = interval_after($day, $duration);
} }

View File

@@ -0,0 +1,51 @@
<?php
namespace App\Repositories\Core;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
Trait DateStats
{
public static function countByMonth($prev = 0)
{
$start = Carbon::now()->startOfMonth($prev);
$end = Carbon::now()->endOfMonth($prev);
return self::countByPeriod($start, $end);
}
public static function countByPeriod($start, $end, $field = 'created_at')
{
return self::getModel()->whereBetween($field, [$start, $end])->count();
}
public static function avgByMonth($prev = 0, $field = false)
{
$start = Carbon::now()->startOfMonth($prev);
$end = Carbon::now()->endOfMonth($prev);
return self::avgByPeriod($start, $end, $field);
}
public static function avgByPeriod($start, $end, $field)
{
$c = self::countByPeriod($start, $end);
return $c ? round(self::sumByPeriod($start, $end, $field) / $c, 2) : 0;
}
public static function sumByMonth($prev = 0, $field = false)
{
$start = Carbon::now()->startOfMonth($prev);
$end = Carbon::now()->endOfMonth($prev);
return self::sumByPeriod($start, $end, $field);
}
public static function sumByPeriod($start, $end, $field = 'created_at')
{
return self::getModel()->whereBetween($field, [$start, $end])->sum($field);
}
public static function getModel()
{
return new Model;
}
}

View File

@@ -12,6 +12,11 @@ use App\Models\Shop\Customer;
class Customers class Customers
{ {
public static function count()
{
return Customer::count();
}
public static function editProfile($id = false) public static function editProfile($id = false)
{ {
$id = $id ? $id : self::getId(); $id = $id ? $id : self::getId();

View File

@@ -7,12 +7,17 @@ use App\Models\Shop\Homepage;
class Dashboards class Dashboards
{ {
public static function getStats() public static function getStats($start, $end)
{ {
return [ return [
'orders_count' => Orders::countByMonth(), 'orders_count' => Orders::countByPeriod($start, $end),
'orders_sum' => Orders::sumByMonth(), 'orders_sum' => Orders::sumByPeriod($start, $end, 'total_shipped'),
'orders_avg' => Orders::avgByMonth(), 'orders_avg' => Orders::avgByPeriod($start, $end, 'total_shipped'),
'offers_count' => Offers::count(),
'clients_count' => Customers::count(),
'preparationLess24H' => Orders::countInPreparationLess24H(),
'preparationLess48H' => Orders::countInPreparationLess48H(),
'preparationMore48H' => Orders::countInPreparationMore48H(),
]; ];
} }
} }

View File

@@ -61,7 +61,7 @@ class Invoices
public static function getNewRef() public static function getNewRef()
{ {
$ref = date('ym') . '00000'; $ref = date('ym') . '00000';
$last_ref = Invoice::orderBy('ref', 'desc')->where('ref', '>', $ref)->first(); $last_ref = Invoice::orderBy('id', 'desc')->first();
return $last_ref ? $last_ref->ref + 1 : $ref + 1; return $last_ref ? $last_ref->ref + 1 : $ref + 1;
} }
@@ -72,6 +72,6 @@ class Invoices
public static function statuses() public static function statuses()
{ {
return ['En attente', 'Non soldée', 'Soldée']; return ['En attente', 'Paiement partiel', 'Soldée', 'Paiement rejeté'];
} }
} }

View File

@@ -7,6 +7,11 @@ use App\Repositories\Core\User\ShopCart;
class Offers class Offers
{ {
public static function count()
{
return Offer::count();
}
public static function getFull($id, $sale_channel_id = false) public static function getFull($id, $sale_channel_id = false)
{ {
$sale_channel_id = $sale_channel_id ? $sale_channel_id : SaleChannels::getDefaultID(); $sale_channel_id = $sale_channel_id ? $sale_channel_id : SaleChannels::getDefaultID();

View File

@@ -4,11 +4,15 @@ namespace App\Repositories\Shop;
use Carbon\Carbon; use Carbon\Carbon;
use App\Models\Shop\Order; use App\Models\Shop\Order;
use App\Repositories\Core\DateStats;
use Illuminate\Support\Arr;
use Illuminate\Support\Str; use Illuminate\Support\Str;
class Orders class Orders
{ {
use DateStats;
public static function saveOrder($data) public static function saveOrder($data)
{ {
$data += $data['basket']; $data += $data['basket'];
@@ -31,21 +35,29 @@ class Orders
return Order::count(); return Order::count();
} }
public static function countByMonth() public static function countInPreparationLess24H()
{ {
$start = Carbon::now()->startOfMonth(); $start = Carbon::now()->subHours(24);
return Order::where('created_at', '>', $start)->count(); $end = Carbon::now();
return Order::preparation()->byPeriod($start, $end, 'updated_at')->count();
} }
public static function sumByMonth() public static function countInPreparationLess48H()
{ {
$start = Carbon::now()->startOfMonth(); $start = Carbon::now()->subHours(48);
return Order::where('created_at', '>', $start)->sum('total_shipped'); $end = Carbon::now();
return Order::preparation()->byPeriod($start, $end, 'updated_at')->count();
} }
public static function avgByMonth() public static function countInPreparationMore48H()
{ {
return self::countByMonth() ? round(self::sumByMonth() / self::countByMonth(), 2) : 0; $start = Carbon::now()->subHours(48);
return Order::preparation()->where('updated_at', '>', $start)->count();
}
public static function getTotalByPeriod($start, $end)
{
return self::sumByPeriod($start, $end, 'total_shipped');
} }
public static function edit($id) public static function edit($id)
@@ -53,7 +65,7 @@ class Orders
return [ return [
'order' => self::get($id, ['customer', 'address', 'detail']), 'order' => self::get($id, ['customer', 'address', 'detail']),
'statuses' => self::statuses(), 'statuses' => self::statuses(),
'payment_types' => self::payment_types(), 'payment_types' => self::paymentTypes(),
'sale_channels' => SaleChannels::getOptions(), 'sale_channels' => SaleChannels::getOptions(),
]; ];
} }
@@ -100,17 +112,23 @@ class Orders
return self::statuses()[$id] ?? false; return self::statuses()[$id] ?? false;
} }
public static function getStatusByName($name)
{
$data = array_flip(self::statuses());
return $data[$name] ?? '';
}
public static function statuses() public static function statuses()
{ {
return ['En attente', 'Expédié', 'Livré']; return ['En attente', 'Préparation', 'Expédié', 'Livré'];
} }
public static function getPaymentType($id) public static function getPaymentType($id)
{ {
return self::payment_types()[$id] ?? false; return self::paymentTypes()[$id] ?? false;
} }
public static function payment_types() public static function paymentTypes()
{ {
return ['', 'CARTE BANCAIRE', 'CHEQUE', 'VIREMENT BANCAIRE']; return ['', 'CARTE BANCAIRE', 'CHEQUE', 'VIREMENT BANCAIRE'];
} }
@@ -118,8 +136,12 @@ class Orders
public static function getNewRef() public static function getNewRef()
{ {
$ref = date('ym') . '00000'; $ref = date('ym') . '00000';
$last_ref = Order::orderBy('ref', 'desc')->where('ref', '>', $ref)->first(); $last_ref = Order::orderBy('id', 'desc')->first();
return $last_ref ? $last_ref->ref + 1 : $ref + 1; return $last_ref ? $last_ref->ref + 1 : $ref + 1;
} }
public static function getModel()
{
return Order::query();
}
} }

View File

@@ -57,3 +57,51 @@ ul .jqtree_common {
body { body {
font-size: 0.8rem; font-size: 0.8rem;
} }
.dashboard {
color: #527C39!important;
}
.dashboard .counter .index {
font-size: 1.6em;
font-weight: 600;
}
.dashboard .counter .value {
font-size: 24px;
font-weight: 600;
}
.dashboard .counter .table {
font-size: 14px;
font-weight: 600;
}
.dashtable .card-header {
padding: 4px 0 4px 10px;
background-color: #527C39!important;
color: white;
}
.dashtable .card-title {
margin: 0;
}
.dashtable td {
padding: 0px;
}
.dashtable .text-muted {
font-size: 0.8em;
}
.dashtable .counter .index {
color: #527C39!important;
font-size: 1.2em;
font-weight: 400;
}
.dashtable .counter .value {
color: #527C39!important;
font-size: 1.4em;
}

View File

@@ -0,0 +1,45 @@
/* require moment.js */
var dateRangePickerLanguage = {
format: "DD/MM/YYYY",
separator: " au ",
locale: {
applyLabel: "Valider",
cancelLabel: "Retour",
fromLabel: "Du",
toLabel: "Au",
customRangeLabel: "Personnalisé",
weekLabel: "S",
daysOfWeek: [
"Dim",
"Lun",
"Mar",
"Mer",
"Jeu",
"Ven",
"Sam"
],
monthNames: [
"Jan",
"Fev",
"Mar",
"Avr",
"Mai",
"Juin",
"Juil",
"Aou",
"Sep",
"Oct",
"Nov",
"Déc"
],
firstDay: 1
},
ranges: {
'Aujourd\'hui': [moment(), moment()],
'Hier': [moment().subtract(1, 'days'), moment().subtract(1, 'days')],
'La semaine dernière': [moment().subtract(6, 'days'), moment()],
'30 derniers jours': [moment().subtract(29, 'days'), moment()],
'Ce mois-ci': [moment().startOf('month'), moment().endOf('month')],
'Le mois dernier': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')]
}
};

View File

@@ -39,6 +39,7 @@
"intervention/imagecache": "^2.4", "intervention/imagecache": "^2.4",
"jasonlewis/expressive-date": "^1.0", "jasonlewis/expressive-date": "^1.0",
"jenssegers/date": "^4.0", "jenssegers/date": "^4.0",
"jeroen-g/blade-macro": "^1.0",
"kalnoy/nestedset": "^6.0", "kalnoy/nestedset": "^6.0",
"kirschbaum-development/eloquent-power-joins": "^2.3", "kirschbaum-development/eloquent-power-joins": "^2.3",
"kmlaravel/laravel-geographical-calculator": "^2.1", "kmlaravel/laravel-geographical-calculator": "^2.1",
@@ -106,6 +107,7 @@
"barryvdh/laravel-debugbar": "^3.8", "barryvdh/laravel-debugbar": "^3.8",
"bestmomo/laravel5-artisan-language": "^0.3", "bestmomo/laravel5-artisan-language": "^0.3",
"beyondcode/laravel-dump-server": "^1.7", "beyondcode/laravel-dump-server": "^1.7",
"enlightn/enlightn": "^2.1",
"fakerphp/faker": "^1.13", "fakerphp/faker": "^1.13",
"fossbarrow/laravel-phpcs": "dev-main", "fossbarrow/laravel-phpcs": "dev-main",
"kevincobain2000/laravel-erd": "^1.3", "kevincobain2000/laravel-erd": "^1.3",

View File

@@ -206,6 +206,7 @@ return [
'successdel' => 'Le module a été correctement effacé', 'successdel' => 'Le module a été correctement effacé',
'confirmdelete' => 'Confirmez-vous la suppression du module ?', 'confirmdelete' => 'Confirmez-vous la suppression du module ?',
], ],
'dashboard' => 'Tableau de bord',
'person' => 'Personne', 'person' => 'Personne',
'processing' => 'En cours', 'processing' => 'En cours',
'all' => 'Tous', 'all' => 'Tous',

View File

@@ -1,27 +1,82 @@
<div class="row"> <x-card title="Aperçu de l'activité">
<div class="col-md-3 col-sm-6 col-xs-12"> <div class="counter">
<a href="{!! route('Admin.Shop.Orders.index') !!}"> <span class="index">Visiteurs en ligne</span>
@include('Admin.Shop.Dashboard.components.infobox', ['count' => $orders_count ?? 0, 'class' => 'bg-aqua', 'icon' => 'ion ion-bag', 'text' => 'Commandes']) <div class="value float-right">40</div>
</a> </div>
<div>
<span class="text-muted">dans les 30 dernières minutes</span>
</div> </div>
<div class="col-md-3 col-sm-6 col-xs-12"> <div class="counter">
<a href="{!! route('Admin.Shop.Invoices.index') !!}"> <span class="index">Paniers Actifs</span>
@include('Admin.Shop.Dashboard.components.infobox', ['count' => $invoices_count ?? 0, 'class' => 'bg-red', 'icon' => 'fa-clock-o', 'text' => 'Factures']) <div class="value float-right">40</div>
</a> </div>
<div>
<span class="text-muted">dans les 30 dernières minutes</span>
</div> </div>
<div class="clearfix visible-sm-block"></div> <x-card title="Etat des commandes" class="dashtable" classBody="p-1 bg-light">
<table class="table table-stripped counter w-100">
<tr>
<td class="index">Commandes</td>
<td class="value text-right">{{ $orders_count }}</td>
</tr>
<tr>
<td class="index">En préparation depuis moins de 24h</td>
<td class="value float-right">{{ $preparationLess24H ?? 0 }}</td>
</tr>
<tr>
<td class="index">En préparation depuis moins de 48h</td>
<td class="value float-right">{{ $preparationLess48H ?? 0 }}</td>
</tr>
<tr>
<td class="index">En préparation depuis plus de 48h</td>
<td class="value float-right">{{ $preparationMore48H ?? 0 }}</td>
</tr>
<tr>
<td class="index">Echec de paiement</td>
<td class="value float-right">{{ $paymentsFailed ?? 0 }}</td>
</tr>
<tr>
<td class="index">
A rembourser<br>
<span class="text-muted">Payés sans stock disponible</span>
</td>
<td class="value float-right">{{ $refunds ?? 0 }}</td>
</tr>
<tr>
<td class="index">
En attente de confirmation<br>
<span class="text-muted">Pour les ventes pro</span>
</td>
<td class="value float-right">{{ $ordersNotConfirmed ?? 0 }}</td>
</tr>
</table>
</x-card>
<div class="col-md-3 col-sm-6 col-xs-12"> <x-card title="Suivi des stocks" class="dashtable" classBody="p-1 bg-light">
<a href="{!!route('Admin.Shop.Orders.index') !!}"> <table class="table table-stripped counter w-100">
@include('Admin.Shop.Dashboard.components.infobox', ['count' => $orders_sum ?? 0, 'class' => 'bg-yellow', 'icon' => 'ion ion-stats-bars', 'text' => 'CA du mois']) <tr>
</a> <td class="index">Stock critique</td>
</div> <td class="value float-right">{{ $stocksWarning ?? 0 }}</td>
</tr>
<tr>
<td class="index">Paramétrage du niveau critique</td>
<td class="value float-right"></td>
</tr>
</table>
</x-card>
<div class="col-md-3 col-sm-6 col-xs-12"> <x-card title="Clients et suivi client" class="dashtable" classBody="p-1 bg-light">
<a href="{!! route('Admin.Shop.Orders.index') !!}"> <table class="table table-stripped counter w-100">
@include('Admin.Shop.Dashboard.components.infobox', ['count' => $orders_avg ?? 0, 'class' => 'bg-green', 'icon' => 'fa-check-square-o', 'text' => 'Panier moyen']) <tr>
</a> <td class="index">Nouveaux clients</td>
</div> <td class="value float-right">{{ $newClients ?? 0 }}</td>
</div> </tr>
<tr>
<td class="index">Exporter le fichier clients</td>
<td class="value float-right"></td>
</tr>
</table>
</x-card>
</x-card>

View File

@@ -2,7 +2,7 @@
<div class="col-sm-3 col-xs-6"> <div class="col-sm-3 col-xs-6">
<div class="description-block border-right"> <div class="description-block border-right">
<span class="description-percentage text-green"><i class="fa fa-caret-up"></i> 17%</span> <span class="description-percentage text-green"><i class="fa fa-caret-up"></i> 17%</span>
<h5 class="description-header">35 210.43 </h5> <h5 class="description-header">{{ $orders_sum ?? 0 }} </h5>
<span class="description-text">TOTAL VENTE</span> <span class="description-text">TOTAL VENTE</span>
</div> </div>
<!-- /.description-block --> <!-- /.description-block -->
@@ -11,7 +11,7 @@
<div class="col-sm-3 col-xs-6"> <div class="col-sm-3 col-xs-6">
<div class="description-block border-right"> <div class="description-block border-right">
<span class="description-percentage text-yellow"><i class="fa fa-caret-left"></i> 0%</span> <span class="description-percentage text-yellow"><i class="fa fa-caret-left"></i> 0%</span>
<h5 class="description-header">10 390.90 </h5> <h5 class="description-header">{{ $orders_avg ?? 0 }} </h5>
<span class="description-text">PANIER MOYEN</span> <span class="description-text">PANIER MOYEN</span>
</div> </div>
<!-- /.description-block --> <!-- /.description-block -->
@@ -20,7 +20,7 @@
<div class="col-sm-3 col-xs-6"> <div class="col-sm-3 col-xs-6">
<div class="description-block border-right"> <div class="description-block border-right">
<span class="description-percentage text-green"><i class="fa fa-caret-up"></i> 20%</span> <span class="description-percentage text-green"><i class="fa fa-caret-up"></i> 20%</span>
<h5 class="description-header">248</h5> <h5 class="description-header">{{ $clients_count ?? 0 }}</h5>
<span class="description-text">NB CLIENTS</span> <span class="description-text">NB CLIENTS</span>
</div> </div>
<!-- /.description-block --> <!-- /.description-block -->
@@ -29,8 +29,8 @@
<div class="col-sm-3 col-xs-6"> <div class="col-sm-3 col-xs-6">
<div class="description-block"> <div class="description-block">
<span class="description-percentage text-red"><i class="fa fa-caret-down"></i> 18%</span> <span class="description-percentage text-red"><i class="fa fa-caret-down"></i> 18%</span>
<h5 class="description-header">1200</h5> <h5 class="description-header">{{ $offers_count ?? 0 }}</h5>
<span class="description-text">NB PRODUITS</span> <span class="description-text">NB OFFRES</span>
</div> </div>
<!-- /.description-block --> <!-- /.description-block -->
</div> </div>

View File

@@ -1,23 +1,11 @@
<div class="row"> <div class="row">
<div class="col-lg-12">
<div class="col-md-8">
@include('Admin.Shop.Dashboard._partials.salesByPeriod') @include('Admin.Shop.Dashboard._partials.salesByPeriod')
</div> </div>
<div class="col-md-4">
@include('Admin.Shop.Dashboard._partials.stock')
</div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-lg-12">
@include('Admin.Shop.Dashboard._partials.latestOrders') @include('Admin.Shop.Dashboard._partials.latestOrders')
</div> </div>
<div class="col-md-4">
@include('Admin.Shop.Dashboard._partials.ordersByTypes')
</div>
</div> </div>

View File

@@ -1,17 +1,38 @@
@extends('layout.index', [ @extends('layout.index', [
'title' => __('dashboard.title'), 'title' => __('Core.dashboard'),
'subtitle' => __('boilerplate::users.list.title'),
'breadcrumb' => [
__('boilerplate::dashboard.title') => 'boilerplate.users.index'
]
]) ])
@include('boilerplate::logs.style') @include('boilerplate::logs.style')
@section('content') @section('content')
@include('Admin.Shop.Dashboard._partials.counter') <div class="btn-group mb-3" role="group" aria-label="Basic example">
@include('Admin.Shop.Dashboard._partials.report') <button type="button" class="btn btn-sm btn-secondary text-nowrap" data-id="day">jour</button>
<button type="button" class="btn btn-sm btn-secondary text-nowrap" data-id="month">mois</button>
<button type="button" class="btn btn-sm btn-secondary text-nowrap" data-id="year">année</button>
<button type="button" class="btn btn-sm btn-secondary text-nowrap" data-id="yesterday">jour-1</button>
<button type="button" class="btn btn-sm btn-secondary text-nowrap" data-id="lastmonth">mois-1</button>
<button type="button" class="btn btn-sm btn-secondary text-nowrap" data-id="lastyear">année-1</button>
@include('components.form.daterangepicker', [
'name' => 'period',
])
</div>
<div class="row dashboard">
<div class="col-lg-3 col-sm-6 col-xs-12">
@include('Admin.Shop.Dashboard._partials.counter')
</div>
<div class="col-lg-9">
@include('Admin.Shop.Dashboard._partials.report')
</div>
</div>
@endsection @endsection
@include('load.form.daterangepicker')
@push('js')
<script>
initDaterangepicker();
</script>
@endpush

View File

@@ -10,9 +10,72 @@
{{ Form::open(['route' => 'Admin.Shop.Invoices.update', 'id' => 'invoice-form', 'autocomplete' => 'off']) }} {{ Form::open(['route' => 'Admin.Shop.Invoices.update', 'id' => 'invoice-form', 'autocomplete' => 'off']) }}
<input type="hidden" name="id" value="{{ $invoice['id'] }}"> <input type="hidden" name="id" value="{{ $invoice['id'] }}">
@include('Admin.Shop.Invoices.form') <x-card>
@include('components.form.buttons.button-save') <div class="row">
<div class="col-6">
<h4> </h4>
</div>
<div class="col-6 text-right">
@include('components.form.buttons.button-save')
</div>
</div>
<div class="row mb-3">
<div class="col-6">
<h3>{{ $invoice['order']['customer']['last_name'] }} {{ $invoice['order']['customer']['first_name'] }}</h3>
<div class="row">
<div class="col-12">
<h6>
@if ($invoice['order']['address'])
{{ $invoice['order']['address']['address'] }}<br/>
@isset ($invoice['order']['address']['address2'])
{{ $invoice['order']['address']['address2'] }}<br/>
@endisset
{{ $invoice['order']['address']['zipcode'] }} {{ $invoice['order']['address']['city'] }}<br/>
@endif
</h6>
</div>
</div>
</div>
<div class="col-6">
<div class="row mb-3">
<div class="col-6" style="font-size: 1.2em; font-weight: 500;">
Facture <br/>
du {{ Carbon\Carbon::parse($invoice['created_at'])->isoFormat('LLLL') }}
</div>
<div class="col-6">
</div>
</div>
<div class="row mb-3">
<div class="col-6">
@include('components.form.select', [
'label' => 'Statut',
'name' => 'status',
'list' => $statuses ?? [],
'value' => $invoice['status'],
'class' => 'select2',
])
</div>
<div class="col-6">
@include('components.form.select', [
'label' => 'Règlement',
'name' => 'payment_type',
'list' => $payment_types ?? [],
'value' => $invoice['order']['payment_type'],
'class' => 'select2',
'disabled' => false,
])
</div>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-12">
@include('Admin.Shop.Orders.partials.detail', ['detail_type' => 'facture', 'order' => $invoice['order']])
</div>
</div>
</x-card>
</form> </form>
@endsection @endsection

View File

@@ -1,6 +1,6 @@
@extends('layout.index', [ @extends('layout.index', [
'title' => __('shop.orders.title'), 'title' => __('shop.orders.title'),
'subtitle' => __('shop.orders.list'), 'subtitle' => __('shop.orders.edit'),
'breadcrumb' => ['Commandes'] 'breadcrumb' => ['Commandes']
]) ])
@@ -8,17 +8,27 @@
{{ Form::open(['route' => 'Admin.Shop.Orders.store', 'id' => 'order-form', 'autocomplete' => 'off']) }} {{ Form::open(['route' => 'Admin.Shop.Orders.store', 'id' => 'order-form', 'autocomplete' => 'off']) }}
<input type="hidden" name="id" value="{{ $order['id'] ?? null }}"> <input type="hidden" name="id" value="{{ $order['id'] ?? null }}">
<x-card> <x-card>
<div class="row">
<div class="col-6">
<h4>{{ $order['delivery']['name'] }} </h4>
</div>
<div class="col-6 text-right">
@include('components.form.buttons.button-save')
</div>
</div>
<div class="row mb-3"> <div class="row mb-3">
<div class="col-6"> <div class="col-6">
<h3>{{ $order['customer']['last_name'] }} {{ $order['customer']['first_name'] }}</h3> <h3>{{ $order['customer']['last_name'] }} {{ $order['customer']['first_name'] }}</h3>
<h4>{{ $order['delivery']['name'] }} </h4>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<h6>
@if ($order['address']) @if ($order['address'])
{{ $order['address']['address'] }}<br/> {{ $order['address']['address'] }}<br/>
@isset ($order['address']['address2']) {{ $order['address']['address2'] }}<br/> @endisset @isset ($order['address']['address2']) {{ $order['address']['address2'] }}<br/> @endisset
{{ $order['address']['zipcode'] }} {{ $order['address']['city'] }}<br/> {{ $order['address']['zipcode'] }} {{ $order['address']['city'] }}<br/>
@endif @endif
</h6>
</div> </div>
</div> </div>
</div> </div>
@@ -29,28 +39,35 @@
du {{ Carbon\Carbon::parse($order['created_at'])->isoFormat('LLLL') }} du {{ Carbon\Carbon::parse($order['created_at'])->isoFormat('LLLL') }}
</div> </div>
<div class="col-6"> <div class="col-6">
<label>Canal de vente</label><br/>
@include('components.form.select', [
'name' => 'sale_channel_id',
'list' => $sale_channels ?? [],
'value' => $order['sale_channel_id'],
'class' => 'select2',
])
</div>
</div>
<div class="row mb-3">
<div class="col-6">
<label>Statut</label><br/>
@include('components.form.select', [ @include('components.form.select', [
'label' => 'Statut',
'name' => 'status', 'name' => 'status',
'list' => $statuses ?? [], 'list' => $statuses ?? [],
'value' => $order['status'], 'value' => $order['status'],
'class' => 'select2', 'class' => 'select2',
]) ])
</div> </div>
<div class="col-6"> </div>
<label>Règlement</label><br/> <div class="row mb-3">
<div class="col-4">
@include('components.form.select', [ @include('components.form.select', [
'label' => 'Canal de vente',
'name' => 'sale_channel_id',
'list' => $sale_channels ?? [],
'value' => $order['sale_channel_id'],
'class' => 'select2',
])
</div>
<div class="col-4">
@include('components.form.input', [
'label' => 'Référence colis',
'name' => 'delivery_ref',
'value' => $order['deivery_ref'],
])
</div>
<div class="col-4">
@include('components.form.select', [
'label' => 'Règlement',
'name' => 'payment_type', 'name' => 'payment_type',
'list' => $payment_types ?? [], 'list' => $payment_types ?? [],
'value' => $order['payment_type'], 'value' => $order['payment_type'],
@@ -62,7 +79,7 @@
</div> </div>
<div class="row mb-3"> <div class="row mb-3">
<div class="col-12"> <div class="col-12">
@include('Admin.Shop.Orders.partials.detail') @include('Admin.Shop.Orders.partials.detail', ['detail_type' => 'commande'])
</div> </div>
</div> </div>
</x-card> </x-card>

View File

@@ -1,18 +1,22 @@
<x-card title="Détail de la commande"> <x-card title="Détail de la {{ $detail_type }}" classBody="mt-3">
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<table class="table table-bordered table-hover w-100 "> <table class="table table-bordered table-hover w-100 ">
<thead class="thead-light"> <thead class="thead-light">
<th>Nom</th> <th>Nom</th>
<th>Quantité</th> <th>Quantité</th>
<th>Prix unitaire</th> <th>PU HT</th>
<th>Total</th> <th>TVA</th>
<th>PU TTC</th>
<th>Total TTC</th>
</thead> </thead>
<tbody> <tbody>
@foreach ($order['detail'] as $detail) @foreach ($order['detail'] as $detail)
<tr> <tr>
<td>{{ $detail['name'] }}</td> <td>{{ $detail['name'] }}</td>
<td align="right">{{ $detail['quantity'] }}</td> <td align="right">{{ $detail['quantity'] }}</td>
<td align="right">{{ $detail['price'] }}</td>
<td align="right">{{ $detail['tax'] }}</td>
<td align="right">{{ $detail['price_taxed'] }}</td> <td align="right">{{ $detail['price_taxed'] }}</td>
<td align="right">{{ $detail['total_taxed'] }}</td> <td align="right">{{ $detail['total_taxed'] }}</td>
</tr> </tr>
@@ -23,6 +27,8 @@
<td style="font-size: 1.2em; font-weight: bold;">Total</td> <td style="font-size: 1.2em; font-weight: bold;">Total</td>
<td></td> <td></td>
<td></td> <td></td>
<td align="right"></td>
<td align="right"></td>
<td align="right" style="font-size: 1.2em; font-weight: bold;">{{ $order['total_taxed'] }}</td> <td align="right" style="font-size: 1.2em; font-weight: bold;">{{ $order['total_taxed'] }}</td>
</tr> </tr>
@if ($order['shipping'] ?? false) @if ($order['shipping'] ?? false)
@@ -30,12 +36,16 @@
<td style="font-size: 1.1em; font-weight: 500;">Livraison</td> <td style="font-size: 1.1em; font-weight: 500;">Livraison</td>
<td align="right"></td> <td align="right"></td>
<td align="right"></td> <td align="right"></td>
<td align="right"></td>
<td align="right"></td>
<td align="right" style="font-size: 1.1em; font-weight: bold;">{{ $order['shipping'] }}</td> <td align="right" style="font-size: 1.1em; font-weight: bold;">{{ $order['shipping'] }}</td>
</tr> </tr>
<tr> <tr>
<td style="font-size: 1.4em; font-weight: bold;">Total à payer</td> <td style="font-size: 1.4em; font-weight: bold;">Total à payer</td>
<td align="right"></td> <td align="right"></td>
<td align="right"></td> <td align="right"></td>
<td align="right">{{ $order['taxes'] }}</td>
<td align="right"></td>
<td align="right" style="font-size: 1.4em; font-weight: bold;">{{ $order['total_shipped'] }}</td> <td align="right" style="font-size: 1.4em; font-weight: bold;">{{ $order['total_shipped'] }}</td>
</tr> </tr>
@endif @endif

View File

@@ -1,6 +1,6 @@
<div @isset($id_card) id="{{ $id_card }}" @endisset class="card {{ $class ?? 'mb-0' }} {{ isset($tabs) ? ($outline ?? config('boilerplate.theme.card.outline', false)) ? 'card-outline-tabs' : 'card-tabs' : ''}} {{ ($outline ?? config('boilerplate.theme.card.outline', false)) ? 'card-outline' : '' }} card-{{ $color ?? config('boilerplate.theme.card.default_color', 'info') }}"> <div @isset($id_card) id="{{ $id_card }}" @endisset class="card {{ $class ?? 'mb-0' }} {{ isset($tabs) ? ($outline ?? config('boilerplate.theme.card.outline', false)) ? 'card-outline-tabs' : 'card-tabs' : ''}} {{ ($outline ?? config('boilerplate.theme.card.outline', false)) ? 'card-outline' : '' }} card-{{ $color ?? config('boilerplate.theme.card.default_color', 'info') }}">
@if($title ?? $header ?? false) @if($title ?? $header ?? false)
<div class="card-header {{ isset($tabs) ? ($outline ?? config('boilerplate.theme.card.outline', false)) ? 'p-0' : 'p-0 pt-1' : '' }} border-bottom-0"> <div class="card-header class="{{ $classHeader ?? '' }} {{ isset($tabs) ? ($outline ?? config('boilerplate.theme.card.outline', false)) ? 'p-0' : 'p-0 pt-1' : '' }} border-bottom-0">
@isset($header) @isset($header)
{{ $header }} {{ $header }}
@else @else

View File

@@ -1,7 +1,7 @@
<?php <?php
Route::middleware('auth')->prefix('Admin')->namespace('Admin')->name('Admin.')->group(function () { Route::middleware('auth')->prefix('Admin')->namespace('Admin')->name('Admin.')->group(function () {
Route::get('', 'HomeController@index')->name('home'); Route::get('{period?}', 'HomeController@index')->name('home');
include __DIR__ . '/Botanic/route.php'; include __DIR__ . '/Botanic/route.php';
include __DIR__ . '/Core/route.php'; include __DIR__ . '/Core/route.php';
include __DIR__ . '/Shop/route.php'; include __DIR__ . '/Shop/route.php';