Offres Spéciales :
commit 2bdbfaec541c3d51489f32e0fa6f7523ca4e4f6f
Author: Olivier Legat <olivier.legat@ldc.fr>
Date: Thu Apr 8 15:48:13 2021 +0200
arrondis de taxe dans le panier
commit ce748bcac15a0b633cacc06b8232cbb92a8e455c
Author: Olivier Legat <olivier.legat@ldc.fr>
Date: Thu Apr 8 11:53:54 2021 +0200
Prix calcules - affichés
commit cc79e7c633d81290371eceabe9864d4d0ee9e4a5
Author: Olivier Legat <olivier.legat@ldc.fr>
Date: Wed Apr 7 18:09:12 2021 +0200
Affichage des promowork in progress => prix remisés
commit 8545d1079da2456f090557eeef005e4d37154a1e
Author: Olivier Legat <olivier.legat@ldc.fr>
Date: Wed Apr 7 13:04:28 2021 +0200
resource BO Promotions
commit d7145835de675da32e57bec3f0b8f06e1e447b27
Author: Olivier Legat <olivier.legat@ldc.fr>
Date: Tue Apr 6 18:23:36 2021 +0200
structure DB, debut BO
This commit is contained in:
parent
293cb74391
commit
bce4c2f88c
40 changed files with 2586 additions and 181 deletions
|
|
@ -39,7 +39,11 @@ class BasketController extends Controller
|
|||
$dbpanier = new Collection();
|
||||
foreach (Cart::content() as $row) {
|
||||
$product = $row->model;
|
||||
$product->additionnalProductInfo = $product->additionnalProductInfo($product->product_type);
|
||||
//$product->additionnalProductInfo = $product->additionnalProductInfo($product->product_type);
|
||||
$product->calculatedPrices = $product->getCalcPrices();
|
||||
|
||||
$row->setTaxRate($product->tax->rate);
|
||||
$row->setDiscountRate($product->discountRate);
|
||||
|
||||
$cartextendedItem = array(
|
||||
'cartItem' => $row,
|
||||
|
|
|
|||
|
|
@ -101,14 +101,23 @@ class OrdersController extends Controller
|
|||
$order_line->order_id = $order->id;
|
||||
$order_line->product_id = $cartItem->model->id;
|
||||
$order_line->quantity = $cartItem->qty;
|
||||
$order_line->unit_price = $cartItem->price;
|
||||
$order_line->unit_discount = 0;
|
||||
//gross unit price
|
||||
$order_line->unit_price = $cartItem->model->priceHt;
|
||||
//discount per unit
|
||||
$order_line->unit_discount = $cartItem->model->discountAmount;
|
||||
//tax rate for this line
|
||||
$order_line->tax_rate = $cartItem->taxRate;
|
||||
$order_line->unit_tax = ($order_line->unit_price * ($order_line->tax_rate / 100));
|
||||
//tax amount par unit
|
||||
$order_line->unit_tax = (($order_line->unit_price - $order_line->unit_discount) * ($order_line->tax_rate / 100));
|
||||
//discount amount for the line
|
||||
$order_line->total_discount = $order_line->unit_discount * $order_line->quantity;
|
||||
$order_line->total_ht = $order_line->unit_price * $order_line->quantity;
|
||||
//gross amount for the line
|
||||
$order_line->total_ht = ($order_line->unit_price - $order_line->unit_discount) * $order_line->quantity;
|
||||
//tax amount for the line
|
||||
$order_line->total_tax = $order_line->unit_tax * $order_line->quantity;
|
||||
//total TTC avec remises de la ligne
|
||||
$order_line->total_ttc = $order_line->total_ht + $order_line->total_tax;
|
||||
|
||||
$order_line->save();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ class ProductsController extends Controller
|
|||
{
|
||||
public function index()
|
||||
{
|
||||
$products = Product::all();
|
||||
$products = Product::paginate(10);
|
||||
return view('bo.products.index', compact('products'));
|
||||
}
|
||||
|
||||
|
|
|
|||
136
app/Http/Controllers/Bo/PromotionsController.php
Normal file
136
app/Http/Controllers/Bo/PromotionsController.php
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Bo;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\DiscountType;
|
||||
use App\Models\Promotion;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PromotionsController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$promotions = Promotion::all();
|
||||
return view('bo.promotions.index', compact('promotions'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$discTypes = DiscountType::all();
|
||||
return view('bo.promotions.create', compact('discTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
$productIds = explode(",", $request->product_id);
|
||||
$discType = $request->discount_type_id;
|
||||
$value = $request->discount_value;
|
||||
$date_start = $request->date_start_date . " " . $request->date_start_time;
|
||||
$date_end = $request->date_end_date . " " . $request->date_end_time;
|
||||
|
||||
$request->validate([]);
|
||||
|
||||
$promotion = new Promotion();
|
||||
$promotion->discount_type_id = $discType;
|
||||
$promotion->discount_value = $value;
|
||||
$promotion->date_start = $date_start;
|
||||
$promotion->date_end = $date_end;
|
||||
$promotion->save();
|
||||
|
||||
//prise en charge de la liaison avec les produits
|
||||
$promotion->products()->sync($productIds);
|
||||
|
||||
return redirect()->route('bo.promotions.index');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function show($id)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function edit($id)
|
||||
{
|
||||
$promotion = Promotion::findOrFail($id);
|
||||
$discTypes = DiscountType::all();
|
||||
return view('bo.promotions.edit', compact('promotion', 'discTypes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function update(Request $request, $id)
|
||||
{
|
||||
$promotion = Promotion::findOrFail($id);
|
||||
|
||||
$productIds = explode(",", $request->product_id);
|
||||
$discType = $request->discount_type_id;
|
||||
$value = $request->discount_value;
|
||||
$date_start = $request->date_start_date . " " . $request->date_start_time;
|
||||
$date_end = $request->date_end_date . " " . $request->date_end_time;
|
||||
|
||||
$request->validate([]);
|
||||
|
||||
$promotion->discount_type_id = $discType;
|
||||
$promotion->discount_value = $value;
|
||||
$promotion->date_start = $date_start;
|
||||
$promotion->date_end = $date_end;
|
||||
$promotion->save();
|
||||
|
||||
//prise en charge de la liaison avec les produits
|
||||
$promotion->products()->sync($productIds);
|
||||
|
||||
return redirect()->route('bo.promotions.edit', $promotion->id)->with('success', 'Modifications enregistrés !');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*
|
||||
* @param int $id
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function destroy($id)
|
||||
{
|
||||
$p = Promotion::findOrFail($id);
|
||||
|
||||
//prise en charge de la liaison avec les produits
|
||||
$p->products()->detach();
|
||||
|
||||
$p->delete();
|
||||
|
||||
return redirect()->route('bo.promotions.index');
|
||||
}
|
||||
}
|
||||
|
|
@ -20,7 +20,9 @@ class ProductsController extends Controller
|
|||
{
|
||||
$range = Range::where('slug', $range_slug)->first();
|
||||
$products = Product::where('range_id', $range->id)->paginate(9);
|
||||
return view('range', compact('range','products'));
|
||||
//find promo within range
|
||||
$offres = Product::where('range_id', $range->id)->has('promotions')->with('promotions')->get();
|
||||
return view('range', compact('range','products','offres'));
|
||||
}
|
||||
|
||||
public function product(Request $request, $product_slug) {
|
||||
|
|
|
|||
42
app/Lib/LDC/CartCalculator.php
Normal file
42
app/Lib/LDC/CartCalculator.php
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
namespace App\Lib\LDC;
|
||||
|
||||
use Gloudemans\Shoppingcart\CartItem;
|
||||
use Gloudemans\Shoppingcart\Contracts\Calculator;
|
||||
|
||||
class CartCalculator implements Calculator
|
||||
{
|
||||
public static function getAttribute(string $attribute, CartItem $cartItem)
|
||||
{
|
||||
$decimals = config('cart.format.decimals', 2);
|
||||
|
||||
switch ($attribute) {
|
||||
case 'discount':
|
||||
return $cartItem->price * ($cartItem->getDiscountRate() / 100);
|
||||
case 'tax':
|
||||
return round($cartItem->priceTarget * ($cartItem->taxRate / 100), $decimals);
|
||||
case 'priceTax':
|
||||
return round($cartItem->priceTarget + $cartItem->tax, $decimals);
|
||||
case 'discountTotal':
|
||||
return round($cartItem->discount * $cartItem->qty, $decimals);
|
||||
case 'priceTotal':
|
||||
return round($cartItem->price * $cartItem->qty, $decimals);
|
||||
case 'subtotal':
|
||||
return max(round($cartItem->priceTotal - $cartItem->discountTotal, $decimals), 0);
|
||||
case 'priceTarget':
|
||||
return round(($cartItem->priceTotal - $cartItem->discountTotal) / $cartItem->qty, $decimals);
|
||||
case 'taxTotal':
|
||||
//taxe pour un item multiplié par la quantité
|
||||
$unit_price = max($cartItem->price - $cartItem->discount,0);
|
||||
$unit_tax = round($unit_price * ($cartItem->taxRate / 100), $decimals);
|
||||
$taxTotal = round($unit_tax * $cartItem->qty, $decimals);
|
||||
//return round($cartItem->subtotal * ($cartItem->taxRate / 100), $decimals);
|
||||
return $taxTotal;
|
||||
case 'total':
|
||||
return round($cartItem->subtotal + $cartItem->taxTotal, $decimals);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
app/Models/DiscountType.php
Normal file
17
app/Models/DiscountType.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class DiscountType extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
public function promotions() {
|
||||
return $this->hasMany(Promotion::class, 'discount_type_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ class Order extends Model
|
|||
return $this->belongsToMany(Product::class, 'order_lines', 'order_id', 'product_id');
|
||||
}
|
||||
|
||||
//Relations
|
||||
public function lines()
|
||||
{
|
||||
return $this->hasMany(OrderLine::class);
|
||||
|
|
@ -33,4 +34,10 @@ class Order extends Model
|
|||
{
|
||||
return $this->hasOne(Timeslot::class);
|
||||
}
|
||||
|
||||
//Formattages
|
||||
public function getFormattedTotalTtcAttribute()
|
||||
{
|
||||
return $this->attributes['formattedTotalTtc'] = sprintf('%s €', number_format($this->attributes['total'], 2, ',', ' '));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ class OrderLine extends Model
|
|||
{
|
||||
use HasFactory;
|
||||
|
||||
//Relations
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class);
|
||||
|
|
@ -18,4 +19,10 @@ class OrderLine extends Model
|
|||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
|
||||
//Formattages
|
||||
public function getFormattedTotalTtcAttribute()
|
||||
{
|
||||
return $this->attributes['formattedTotalTtc'] = sprintf('%s €', number_format($this->attributes['total_ttc'], 2, ',', ' '));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
|
@ -14,18 +15,200 @@ class Product extends Model implements Buyable
|
|||
use SoftDeletes;
|
||||
use CanBeBought;
|
||||
|
||||
//special formatted attribute price
|
||||
public function getFormattedPriceAttribute()
|
||||
/**
|
||||
* Store in protected variables instead of attributes
|
||||
* Because those are not set in attributes, Laravel will not try to save it to database
|
||||
*/
|
||||
protected $priceHt;
|
||||
|
||||
protected $discountedPriceHt;
|
||||
|
||||
protected $priceTtc;
|
||||
|
||||
protected $discountedPriceTtc;
|
||||
|
||||
protected $discountAmount;
|
||||
|
||||
protected $discountRate;
|
||||
|
||||
/**
|
||||
* init prices on boot
|
||||
*/
|
||||
protected static function boot()
|
||||
{
|
||||
return $this->attributes['formattedPrice'] = sprintf('%s €', number_format($this->attributes['price'], 2, ',', ' '));
|
||||
parent::boot();
|
||||
|
||||
//on data retrived from DB
|
||||
static::retrieved(function ($model) {
|
||||
$model->priceHt = $model->getPriceHtAttribute();
|
||||
$model->priceTtc = $model->getPriceTtcAttribute();
|
||||
$model->discountAmount = $model->getDiscountAmountAttribute();
|
||||
$model->discountRate = $model->getDiscountRateAttribute();
|
||||
$model->discountedPriceHt = $model->getDiscountedPriceHtAttribute();
|
||||
$model->discountedPriceTtc = $model->getDiscountedPriceTtcAttribute();
|
||||
});
|
||||
}
|
||||
|
||||
public function getFormattedPriceTTCAttribute()
|
||||
|
||||
/**
|
||||
* Price calculations
|
||||
* We need : gross price (prix avant taxe et remises)
|
||||
* discounted price (prix avant taxe avec remises)
|
||||
* net price (prix avec taxe)
|
||||
* net discounted proice (prix avec taxe et remises)
|
||||
*/
|
||||
|
||||
//Utility to bring prices as a pseudo relation
|
||||
public function getCalcPrices()
|
||||
{
|
||||
$ttc = $this->attributes['price'] * 1.2;
|
||||
return $this->attributes['formattedPriceTTC'] = sprintf('%s €', number_format($ttc, 2, ',', ' '));
|
||||
//$prices = new Collection();
|
||||
$prices = array(
|
||||
'priceHt' => $this->priceHt,
|
||||
'discountAmount' => $this->discountAmount,
|
||||
'discountRate' => $this->discountRate,
|
||||
'discountedPriceHt' => $this->discountedPriceHt,
|
||||
'priceTtc' => $this->priceTtc,
|
||||
'discountedPriceTtc' => $this->discountedPriceTtc,
|
||||
);
|
||||
//$prices->add($cartextendedItem);
|
||||
return $prices;
|
||||
}
|
||||
|
||||
//gross price
|
||||
/**
|
||||
* Mutator method to set priceHt's value
|
||||
*/
|
||||
public function setPriceHtAttribute($value)
|
||||
{
|
||||
$this->priceHt = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the gross price
|
||||
* Accessor method for priceHt
|
||||
*
|
||||
* @author Olivier Legat <olivier.legat@ldc.fr>
|
||||
*/
|
||||
public function getPriceHtAttribute()
|
||||
{
|
||||
if(isset($this->priceHt)) {
|
||||
return $this->priceHt;
|
||||
} else {
|
||||
//no calculations, alias of db property
|
||||
return $this->priceHt = $this->attributes['price'];
|
||||
}
|
||||
}
|
||||
|
||||
//discounted price
|
||||
public function setDiscountedPriceHtAttribute($value)
|
||||
{
|
||||
$this->discountedPriceHt = $value;
|
||||
}
|
||||
|
||||
public function getDiscountedPriceHtAttribute()
|
||||
{
|
||||
if (isset($this->discountedPriceHt)) {
|
||||
return $this->discountedPriceHt;
|
||||
} else {
|
||||
return $this->discountedPriceHt = $this->priceHt - $this->discountAmount;
|
||||
}
|
||||
}
|
||||
|
||||
//net price
|
||||
public function setPriceTtcAttribute($value)
|
||||
{
|
||||
$this->priceTtc = $value;
|
||||
}
|
||||
|
||||
public function getPriceTtcAttribute()
|
||||
{
|
||||
if (isset($this->priceTtc)) {
|
||||
return $this->priceTtc;
|
||||
} else {
|
||||
return $this->priceTtc = $this->priceHt * ( 1 + ( $this->tax->rate / 100));
|
||||
}
|
||||
}
|
||||
|
||||
//net discounted price
|
||||
public function setDiscountedPriceTtcAttribute($value)
|
||||
{
|
||||
$this->discountedPriceTtc = $value;
|
||||
}
|
||||
|
||||
public function getDiscountedPriceTtcAttribute()
|
||||
{
|
||||
if (isset($this->discountedPriceTtc)) {
|
||||
return $this->discountedPriceTtc;
|
||||
} else {
|
||||
return $this->discountedPriceTtc = $this->discountedPriceHt * ( 1 + ( $this->tax->rate / 100));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Discount calc
|
||||
*/
|
||||
|
||||
//montant de remise
|
||||
public function setDiscountAmountAttribute($value)
|
||||
{
|
||||
$this->discountAmount = $value;
|
||||
}
|
||||
|
||||
public function getDiscountAmountAttribute()
|
||||
{
|
||||
if (isset($this->discountAmount)) {
|
||||
return $this->discountAmount;
|
||||
} else {
|
||||
$applicablePromotion = $this->promotions->first();
|
||||
if (null !== $applicablePromotion) {
|
||||
$promo_type = $applicablePromotion->discount_type_id;
|
||||
if ($promo_type == 1) {
|
||||
$discountAmount = $applicablePromotion->discount_value;
|
||||
} else {
|
||||
$discountAmount = $this->priceHt * ($applicablePromotion->discount_value / 100);
|
||||
}
|
||||
} else {
|
||||
$discountAmount = 0;
|
||||
}
|
||||
return $this->discountAmount = $discountAmount;
|
||||
}
|
||||
}
|
||||
|
||||
//taux de remise
|
||||
public function setDiscountRateAttribute($value)
|
||||
{
|
||||
$this->discountRate = $value;
|
||||
}
|
||||
|
||||
public function getDiscountRateAttribute()
|
||||
{
|
||||
if (isset($this->discountRate)) {
|
||||
return $this->discountRate;
|
||||
} else {
|
||||
$applicablePromotion = $this->promotions->first();
|
||||
if (null !== $applicablePromotion) {
|
||||
$promo_type = $applicablePromotion->discount_type_id;
|
||||
if ($promo_type == 1) {
|
||||
//on veut un pourcentage
|
||||
$discountRate = ($applicablePromotion->discount_value / $this->priceHt) * 100;
|
||||
} else {
|
||||
$discountRate = $applicablePromotion->discount_value;
|
||||
}
|
||||
} else {
|
||||
$discountRate = 0;
|
||||
}
|
||||
return $this->discountRate = $discountRate;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// //Buyable interface
|
||||
// public function getBuyablePrice($options = null)
|
||||
// {
|
||||
// return $this->discountedPriceHt;
|
||||
// }
|
||||
|
||||
//Relations
|
||||
public function range()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Range', 'range_id');
|
||||
|
|
@ -62,8 +245,23 @@ class Product extends Model implements Buyable
|
|||
|
||||
|
||||
//relationship to associated products
|
||||
public function associated_products()
|
||||
public function associatedProducts()
|
||||
{
|
||||
return $this->belongsToMany(Product::class, 'products_products', 'product_id', 'associated_id');
|
||||
}
|
||||
|
||||
//offres speciales
|
||||
public function promotions()
|
||||
{
|
||||
$now = Carbon::now();
|
||||
return $this->belongsToMany(Promotion::class)
|
||||
->whereDate('date_start', '<=', $now)
|
||||
->whereDate('date_end', '>=', $now);
|
||||
}
|
||||
|
||||
//taxe
|
||||
public function tax()
|
||||
{
|
||||
return $this->belongsTo(TaxRate::class, 'tax_rate_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
31
app/Models/Promotion.php
Normal file
31
app/Models/Promotion.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Promotion extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'date_start' => 'datetime',
|
||||
'date_end' => 'datetime',
|
||||
];
|
||||
|
||||
public function products()
|
||||
{
|
||||
return $this->belongsToMany(Product::class);
|
||||
}
|
||||
|
||||
public function discountType()
|
||||
{
|
||||
return $this->belongsTo(DiscountType::class, 'discount_type_id');
|
||||
}
|
||||
}
|
||||
17
app/Models/TaxRate.php
Normal file
17
app/Models/TaxRate.php
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class TaxRate extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $timestamps = false;
|
||||
|
||||
public function products() {
|
||||
return $this->hasMany(Product::class, 'tax_rate_id');
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ namespace App\Providers;
|
|||
use App\Models\Range;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
|
|
@ -32,5 +33,10 @@ class AppServiceProvider extends ServiceProvider
|
|||
// on partage les ranges (gammes produit)
|
||||
$ranges = Range::all();
|
||||
View::share('ranges', $ranges);
|
||||
|
||||
Blade::directive('fmt_currency', function ($expression) {
|
||||
/* return "<?php echo sprintf('%s €', number_format($expression, 2, ',', ' ')); ?>"; */
|
||||
return "<?php echo sprintf('%s €', $expression); ?>";
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@ return [
|
|||
|
|
||||
*/
|
||||
|
||||
'calculator' => \Gloudemans\Shoppingcart\Calculation\DefaultCalculator::class,
|
||||
//'calculator' => \Gloudemans\Shoppingcart\Calculation\DefaultCalculator::class,
|
||||
'calculator' => \App\Lib\LDC\CartCalculator::class,
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -70,9 +71,9 @@ return [
|
|||
|
||||
'decimals' => 2,
|
||||
|
||||
'decimal_point' => ',',
|
||||
'decimal_point' => '.',
|
||||
|
||||
'thousand_separator' => ' ',
|
||||
'thousand_separator' => '',
|
||||
|
||||
],
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Database\Seeders\DiscountTypesSeeder;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateDiscountTypesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('discount_types', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('label');
|
||||
});
|
||||
|
||||
$seeder = new DiscountTypesSeeder();
|
||||
$seeder->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('discount_types');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreatePromotionsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('promotions', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->foreignId('discount_type_id')->default(1)->constrained('discount_types');
|
||||
$table->float('discount_value')->default(0);
|
||||
$table->timestamp('date_start')->nullable();
|
||||
$table->timestamp('date_end')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('promotions');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateProductPromotionTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('product_promotion', function (Blueprint $table) {
|
||||
$table->foreignId('product_id')->constrained('products'); //produit considéré
|
||||
$table->foreignId('promotion_id')->constrained('promotions'); //promotion associée
|
||||
$table->collation = 'utf8mb4_unicode_ci';
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('product_promotion');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?php
|
||||
|
||||
use Database\Seeders\TaxRatesSeeder;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateTaxRatesTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('tax_rates', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('label');
|
||||
$table->float('rate');
|
||||
});
|
||||
|
||||
$seeder = new TaxRatesSeeder();
|
||||
$seeder->run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('tax_rates');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddFieldsToProductsTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->foreignId('tax_rate_id')->after('price_buy')->default(1)->constrained('tax_rates');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('products', function (Blueprint $table) {
|
||||
$table->dropForeign(['tax_rate_id']);
|
||||
$table->dropColumn('tax_rate_id');
|
||||
});
|
||||
}
|
||||
}
|
||||
26
database/seeders/DiscountTypesSeeder.php
Normal file
26
database/seeders/DiscountTypesSeeder.php
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\DiscountType;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class DiscountTypesSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$montant = new DiscountType();
|
||||
$montant->label = "Montant";
|
||||
|
||||
$pourcentage = new DiscountType();
|
||||
$pourcentage->label = "Pourcentage";
|
||||
|
||||
$montant->save();
|
||||
$pourcentage->save();
|
||||
}
|
||||
}
|
||||
28
database/seeders/TaxRatesSeeder.php
Normal file
28
database/seeders/TaxRatesSeeder.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use App\Models\TaxRate;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class TaxRatesSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function run()
|
||||
{
|
||||
$highTva = new TaxRate();
|
||||
$highTva->label = "TVA 20%";
|
||||
$highTva->rate = 20;
|
||||
|
||||
$lowTva = new TaxRate();
|
||||
$lowTva->label = "TVA 5.5%";
|
||||
$lowTva->rate = 5.5;
|
||||
|
||||
$highTva->save();
|
||||
$lowTva->save();
|
||||
}
|
||||
}
|
||||
15
package-lock.json
generated
15
package-lock.json
generated
|
|
@ -8271,6 +8271,12 @@
|
|||
"integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=",
|
||||
"dev": true
|
||||
},
|
||||
"smooth-dnd": {
|
||||
"version": "0.12.1",
|
||||
"resolved": "https://registry.npmjs.org/smooth-dnd/-/smooth-dnd-0.12.1.tgz",
|
||||
"integrity": "sha512-Dndj/MOG7VP83mvzfGCLGzV2HuK1lWachMtWl/Iuk6zV7noDycIBnflwaPuDzoaapEl3Pc4+ybJArkkx9sxPZg==",
|
||||
"dev": true
|
||||
},
|
||||
"snapdragon": {
|
||||
"version": "0.8.2",
|
||||
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
|
||||
|
|
@ -9356,6 +9362,15 @@
|
|||
"vue-style-loader": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"vue-smooth-dnd": {
|
||||
"version": "0.8.1",
|
||||
"resolved": "https://registry.npmjs.org/vue-smooth-dnd/-/vue-smooth-dnd-0.8.1.tgz",
|
||||
"integrity": "sha512-eZVVPTwz4A1cs0+CjXx/ihV+gAl3QBoWQnU6+23Gp59t0WBU99z7ducBQ4FvjBamqOlg8SDOE5eFHQedxwB4Wg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"smooth-dnd": "0.12.1"
|
||||
}
|
||||
},
|
||||
"vue-style-loader": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz",
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"bootstrap": "^4.5.0",
|
||||
"bootstrap": "^4.6.0",
|
||||
"cross-env": "^7.0",
|
||||
"jquery": "^3.6",
|
||||
"laravel-mix": "^5.0.1",
|
||||
|
|
@ -21,6 +21,7 @@
|
|||
"sass-loader": "^8.0.2",
|
||||
"swiper": "^6.3.4",
|
||||
"toastify-js": "^1.10.0",
|
||||
"vue-smooth-dnd": "^0.8.1",
|
||||
"vue-template-compiler": "^2.6.12"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
921
public/b-o/js/app.js
vendored
921
public/b-o/js/app.js
vendored
File diff suppressed because one or more lines are too long
516
public/canard/js/app.js
vendored
516
public/canard/js/app.js
vendored
|
|
@ -2321,6 +2321,10 @@ __webpack_require__.r(__webpack_exports__);
|
|||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
/* harmony default export */ __webpack_exports__["default"] = ({
|
||||
props: [],
|
||||
computed: {
|
||||
|
|
@ -2341,7 +2345,8 @@ __webpack_require__.r(__webpack_exports__);
|
|||
success: false,
|
||||
errors: false,
|
||||
showConfirmEmpty: false,
|
||||
response: ''
|
||||
response: '',
|
||||
promotion_slide: -1
|
||||
};
|
||||
},
|
||||
mounted: function mounted() {
|
||||
|
|
@ -2437,6 +2442,28 @@ __webpack_require__.r(__webpack_exports__);
|
|||
type: 'updateCartTotals',
|
||||
cartTotals: result[1]
|
||||
});
|
||||
},
|
||||
hover: function hover(zone, row_id) {
|
||||
console.log(this.promotion_slide);
|
||||
eval("this." + zone + "='" + row_id + "';");
|
||||
console.log(this.promotion_slide);
|
||||
},
|
||||
//general purpose TODO : globalize
|
||||
numFormatter: function numFormatter(num) {
|
||||
return new Intl.NumberFormat('fr-FR', {
|
||||
style: 'currency',
|
||||
currency: 'EUR'
|
||||
}).format(num);
|
||||
},
|
||||
dateFormatter: function dateFormatter(str) {
|
||||
var d = new Date(str);
|
||||
var options = {
|
||||
weekday: 'long',
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric'
|
||||
};
|
||||
return d.toLocaleDateString("fr-FR", options);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -41554,22 +41581,6 @@ var render = function() {
|
|||
[_vm._m(1), _vm._v(" "), _vm._m(2)]
|
||||
),
|
||||
_vm._v(" "),
|
||||
_c(
|
||||
"div",
|
||||
{
|
||||
directives: [
|
||||
{
|
||||
name: "show",
|
||||
rawName: "v-show",
|
||||
value: !_vm.emptybasket,
|
||||
expression: "!(emptybasket)"
|
||||
}
|
||||
],
|
||||
staticClass: "message-box"
|
||||
},
|
||||
[_vm._m(3)]
|
||||
),
|
||||
_vm._v(" "),
|
||||
_c("div", {
|
||||
directives: [
|
||||
{
|
||||
|
|
@ -41690,10 +41701,7 @@ var render = function() {
|
|||
"article",
|
||||
{
|
||||
staticClass:
|
||||
"ds-product-card--largehorizontal ds-product-card",
|
||||
attrs: {
|
||||
id: "3560070820542"
|
||||
}
|
||||
"ds-product-card--largehorizontal ds-product-card"
|
||||
},
|
||||
[
|
||||
_c(
|
||||
|
|
@ -41723,7 +41731,7 @@ var render = function() {
|
|||
]
|
||||
),
|
||||
_vm._v(" "),
|
||||
_vm._m(4, true),
|
||||
_vm._m(3, true),
|
||||
_vm._v(" "),
|
||||
_c(
|
||||
"div",
|
||||
|
|
@ -41824,7 +41832,7 @@ var render = function() {
|
|||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n " +
|
||||
"\n " +
|
||||
_vm._s(
|
||||
item
|
||||
.cartItem
|
||||
|
|
@ -41836,7 +41844,7 @@ var render = function() {
|
|||
.product
|
||||
.weight_unit
|
||||
) +
|
||||
"\r\n "
|
||||
"\n "
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -41881,13 +41889,13 @@ var render = function() {
|
|||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n " +
|
||||
"\n " +
|
||||
_vm._s(
|
||||
item
|
||||
.cartItem
|
||||
.name
|
||||
) +
|
||||
"\r\n "
|
||||
"\n "
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -41911,13 +41919,13 @@ var render = function() {
|
|||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n " +
|
||||
"\n " +
|
||||
_vm._s(
|
||||
item
|
||||
.product
|
||||
.sell_unit
|
||||
) +
|
||||
"\r\n "
|
||||
"\n "
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -41934,6 +41942,318 @@ var render = function() {
|
|||
"ds-product-card--largehorizontal-infos-sec"
|
||||
},
|
||||
[
|
||||
_vm._l(
|
||||
item.product
|
||||
.promotions,
|
||||
function(
|
||||
promotion
|
||||
) {
|
||||
return _c(
|
||||
"div",
|
||||
{
|
||||
directives: [
|
||||
{
|
||||
name:
|
||||
"show",
|
||||
rawName:
|
||||
"v-show",
|
||||
value:
|
||||
item
|
||||
.product
|
||||
.calculatedPrices
|
||||
.discountAmount >
|
||||
0,
|
||||
expression:
|
||||
"item.product.calculatedPrices.discountAmount>0"
|
||||
}
|
||||
],
|
||||
staticClass:
|
||||
"ds-product-card--largehorizontal-promotion"
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"div",
|
||||
[
|
||||
_c(
|
||||
"div",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-description promotion-description--loyalty"
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"div",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-description__labels",
|
||||
on: {
|
||||
mouseover: function(
|
||||
$event
|
||||
) {
|
||||
return _vm.hover(
|
||||
"promotion_slide",
|
||||
item
|
||||
.cartItem
|
||||
.rowId
|
||||
)
|
||||
},
|
||||
mouseleave: function(
|
||||
$event
|
||||
) {
|
||||
return _vm.hover(
|
||||
"promotion_slide",
|
||||
"-1"
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"p",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-label",
|
||||
attrs: {
|
||||
title:
|
||||
item
|
||||
.product
|
||||
.calculatedPrices
|
||||
.discountRate +
|
||||
"% d'économies"
|
||||
}
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"span",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-label__txt"
|
||||
},
|
||||
[
|
||||
_vm._v(
|
||||
_vm._s(
|
||||
item
|
||||
.product
|
||||
.calculatedPrices
|
||||
.discountRate
|
||||
) +
|
||||
"% d'économies"
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
_vm._v(
|
||||
" "
|
||||
),
|
||||
_c(
|
||||
"svg",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-description__icon-info",
|
||||
attrs: {
|
||||
focusable:
|
||||
"false"
|
||||
}
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"use",
|
||||
{
|
||||
attrs: {
|
||||
"xmlns:xlink":
|
||||
"http://www.w3.org/1999/xlink",
|
||||
"xlink:href":
|
||||
"#icon-info"
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
_vm._v(
|
||||
" "
|
||||
),
|
||||
_c(
|
||||
"section",
|
||||
{
|
||||
directives: [
|
||||
{
|
||||
name:
|
||||
"show",
|
||||
rawName:
|
||||
"v-show",
|
||||
value:
|
||||
_vm.promotion_slide ==
|
||||
item
|
||||
.cartItem
|
||||
.rowId,
|
||||
expression:
|
||||
"promotion_slide == item.cartItem.rowId"
|
||||
}
|
||||
],
|
||||
staticClass:
|
||||
"promotion-slide"
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"header",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-slide__header promotion-slide__header--loyalty"
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"p",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-slide__header-txt"
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"svg",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-slide__icon-promo",
|
||||
attrs: {
|
||||
focusable:
|
||||
"false"
|
||||
}
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"use",
|
||||
{
|
||||
attrs: {
|
||||
"xmlns:xlink":
|
||||
"http://www.w3.org/1999/xlink",
|
||||
"xlink:href":
|
||||
"#icon-carrefour-loyalty-card-hightlighted"
|
||||
}
|
||||
}
|
||||
)
|
||||
]
|
||||
),
|
||||
_vm._v(
|
||||
" "
|
||||
),
|
||||
_c(
|
||||
"span",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-slide__header-label"
|
||||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\n Economisé\n "
|
||||
)
|
||||
]
|
||||
),
|
||||
_vm._v(
|
||||
" "
|
||||
),
|
||||
_c(
|
||||
"span",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-slide__header-discount"
|
||||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\n " +
|
||||
_vm._s(
|
||||
_vm.numFormatter(
|
||||
(Math.round(
|
||||
(item
|
||||
.product
|
||||
.calculatedPrices
|
||||
.priceTtc -
|
||||
item
|
||||
.product
|
||||
.calculatedPrices
|
||||
.discountedPriceTtc) *
|
||||
100
|
||||
) /
|
||||
100) *
|
||||
item
|
||||
.cartItem
|
||||
.qty
|
||||
)
|
||||
) +
|
||||
"\n "
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
_vm._v(
|
||||
" "
|
||||
),
|
||||
_c(
|
||||
"p",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-slide__txt"
|
||||
},
|
||||
[
|
||||
_c(
|
||||
"span",
|
||||
[
|
||||
_c(
|
||||
"b",
|
||||
[
|
||||
_vm._v(
|
||||
_vm._s(
|
||||
item
|
||||
.product
|
||||
.calculatedPrices
|
||||
.discountRate
|
||||
) +
|
||||
"% d'économies"
|
||||
)
|
||||
]
|
||||
),
|
||||
_c(
|
||||
"br"
|
||||
)
|
||||
]
|
||||
),
|
||||
_vm._v(
|
||||
" "
|
||||
),
|
||||
_c(
|
||||
"span",
|
||||
{
|
||||
staticClass:
|
||||
"promotion-slide__end-date"
|
||||
},
|
||||
[
|
||||
_vm._v(
|
||||
"Offre valable jusqu'au " +
|
||||
_vm._s(
|
||||
_vm.dateFormatter(
|
||||
promotion.date_end
|
||||
)
|
||||
)
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
}
|
||||
),
|
||||
_vm._v(" "),
|
||||
_c(
|
||||
"div",
|
||||
{
|
||||
|
|
@ -41963,18 +42283,16 @@ var render = function() {
|
|||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n " +
|
||||
"\n " +
|
||||
_vm._s(
|
||||
item
|
||||
.cartItem
|
||||
.price *
|
||||
(1 +
|
||||
item
|
||||
.cartItem
|
||||
.taxRate /
|
||||
100)
|
||||
_vm.numFormatter(
|
||||
item
|
||||
.product
|
||||
.calculatedPrices
|
||||
.discountedPriceTtc
|
||||
)
|
||||
) +
|
||||
"€ TTC\r\n "
|
||||
"\n "
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -42073,13 +42391,13 @@ var render = function() {
|
|||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n " +
|
||||
"\n " +
|
||||
_vm._s(
|
||||
item
|
||||
.cartItem
|
||||
.qty
|
||||
) +
|
||||
"\r\n "
|
||||
"\n "
|
||||
)
|
||||
]
|
||||
),
|
||||
|
|
@ -42143,14 +42461,15 @@ var render = function() {
|
|||
" "
|
||||
),
|
||||
_vm._m(
|
||||
5,
|
||||
4,
|
||||
true
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
],
|
||||
2
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -42187,7 +42506,7 @@ var render = function() {
|
|||
"products-brief-data products-brief--items"
|
||||
},
|
||||
[
|
||||
_vm._m(6),
|
||||
_vm._m(5),
|
||||
_vm._v(" "),
|
||||
_c("dd", [
|
||||
_c(
|
||||
|
|
@ -42198,9 +42517,13 @@ var render = function() {
|
|||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n " +
|
||||
_vm._s(_vm.cartTotals.totalTTC) +
|
||||
" €\r\n "
|
||||
"\n " +
|
||||
_vm._s(
|
||||
_vm.numFormatter(
|
||||
_vm.cartTotals.totalTTC
|
||||
)
|
||||
) +
|
||||
"\n "
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -42256,7 +42579,7 @@ var render = function() {
|
|||
]
|
||||
),
|
||||
_vm._v(
|
||||
"\r\n Vider le panier\r\n "
|
||||
"\n Vider le panier\n "
|
||||
)
|
||||
]
|
||||
)
|
||||
|
|
@ -42290,7 +42613,7 @@ var render = function() {
|
|||
"div",
|
||||
{ staticClass: "modal__container" },
|
||||
[
|
||||
_vm._m(7),
|
||||
_vm._m(6),
|
||||
_vm._v(" "),
|
||||
_c(
|
||||
"div",
|
||||
|
|
@ -42322,14 +42645,14 @@ var render = function() {
|
|||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n Oui, vider mon panier\r\n "
|
||||
"\n Oui, vider mon panier\n "
|
||||
)
|
||||
]
|
||||
)
|
||||
]
|
||||
),
|
||||
_vm._v(" "),
|
||||
_vm._m(8)
|
||||
_vm._m(7)
|
||||
])
|
||||
]
|
||||
)
|
||||
|
|
@ -42343,7 +42666,7 @@ var render = function() {
|
|||
)
|
||||
]),
|
||||
_vm._v(" "),
|
||||
_vm._m(9)
|
||||
_vm._m(8)
|
||||
])
|
||||
])
|
||||
])
|
||||
|
|
@ -42364,7 +42687,7 @@ var render = function() {
|
|||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n Total\r\n "
|
||||
"\n Total\n "
|
||||
)
|
||||
]
|
||||
),
|
||||
|
|
@ -42377,15 +42700,17 @@ var render = function() {
|
|||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n " +
|
||||
_vm._s(_vm.cartTotals.totalTTC) +
|
||||
" €\r\n "
|
||||
"\n " +
|
||||
_vm._s(
|
||||
_vm.numFormatter(_vm.cartTotals.totalTTC)
|
||||
) +
|
||||
"\n "
|
||||
)
|
||||
]
|
||||
)
|
||||
]),
|
||||
_vm._v(" "),
|
||||
_vm._m(10)
|
||||
_vm._m(9)
|
||||
]
|
||||
)
|
||||
]
|
||||
|
|
@ -42470,9 +42795,7 @@ var staticRenderFns = [
|
|||
var _c = _vm._self._c || _h
|
||||
return _c("div", { staticClass: "basket-panel__title-wrapper" }, [
|
||||
_c("span", { staticClass: "title title_medium" }, [
|
||||
_vm._v(
|
||||
"\r\n Aperçu panier\r\n "
|
||||
)
|
||||
_vm._v("\n Aperçu panier\n ")
|
||||
])
|
||||
])
|
||||
},
|
||||
|
|
@ -42486,52 +42809,6 @@ var staticRenderFns = [
|
|||
[_c("span", [_vm._v("Fermer")])]
|
||||
)
|
||||
},
|
||||
function() {
|
||||
var _vm = this
|
||||
var _h = _vm.$createElement
|
||||
var _c = _vm._self._c || _h
|
||||
return _c("div", { staticClass: "message-box__inner" }, [
|
||||
_c(
|
||||
"div",
|
||||
{
|
||||
staticClass:
|
||||
"message-box__heading message-box__icon message-box__icon--low"
|
||||
},
|
||||
[
|
||||
_vm._v(
|
||||
"\r\n Vous n’êtes pas connecté\r\n "
|
||||
)
|
||||
]
|
||||
),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "message-box__body" }, [
|
||||
_vm._v(
|
||||
"\r\n Connectez-vous ou créez votre compte pour passer votre commande\r\n "
|
||||
)
|
||||
]),
|
||||
_vm._v(" "),
|
||||
_c("a", {
|
||||
staticClass: "message-box__alert-title",
|
||||
attrs: { href: "#", target: "" }
|
||||
}),
|
||||
_vm._v(" "),
|
||||
_c("div", { staticClass: "message-box__actions" }, [
|
||||
_c("div", [
|
||||
_c("a", { attrs: { href: "/connexion" } }, [
|
||||
_vm._v(
|
||||
"\r\n Me connecter\r\n "
|
||||
)
|
||||
]),
|
||||
_vm._v(" "),
|
||||
_c("a", { attrs: { href: "/inscription" } }, [
|
||||
_vm._v(
|
||||
"\r\n Créer mon compte\r\n "
|
||||
)
|
||||
])
|
||||
])
|
||||
])
|
||||
])
|
||||
},
|
||||
function() {
|
||||
var _vm = this
|
||||
var _h = _vm.$createElement
|
||||
|
|
@ -42586,7 +42863,7 @@ var staticRenderFns = [
|
|||
return _c("div", { staticClass: "modal__body" }, [
|
||||
_c("div", { staticClass: "checkout-clear-basket__modal__title" }, [
|
||||
_vm._v(
|
||||
"\r\n Voulez-vous réellement vider votre panier ?\r\n "
|
||||
"\n Voulez-vous réellement vider votre panier ?\n "
|
||||
)
|
||||
])
|
||||
])
|
||||
|
|
@ -42620,7 +42897,7 @@ var staticRenderFns = [
|
|||
_c("section", { staticClass: "checkout-loyalty-info__top-section" }, [
|
||||
_c("h3", { staticClass: "ds-title ds-title--bold ds-title--xs" }, [
|
||||
_vm._v(
|
||||
"\r\n Avantages fidélité\r\n "
|
||||
"\n Avantages fidélité\n "
|
||||
)
|
||||
])
|
||||
])
|
||||
|
|
@ -42639,7 +42916,7 @@ var staticRenderFns = [
|
|||
_c("a", { attrs: { href: "/commande/recap" } }, [
|
||||
_c("span", { staticClass: "pl-button__label" }, [
|
||||
_vm._v(
|
||||
"\r\n Commander\r\n "
|
||||
"\n Commander\n "
|
||||
)
|
||||
])
|
||||
])
|
||||
|
|
@ -56304,11 +56581,14 @@ module.exports = function(module) {
|
|||
|
||||
"use strict";
|
||||
__webpack_require__.r(__webpack_exports__);
|
||||
/* harmony import */ var swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! swiper/swiper-bundle */ "./node_modules/swiper/swiper-bundle.js");
|
||||
/* harmony import */ var swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
|
||||
/* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm.js");
|
||||
/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js");
|
||||
/* harmony import */ var jquery__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(jquery__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! swiper/swiper-bundle */ "./node_modules/swiper/swiper-bundle.js");
|
||||
/* harmony import */ var swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! toastify-js */ "./node_modules/toastify-js/src/toastify.js");
|
||||
/* harmony import */ var toastify_js__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(toastify_js__WEBPACK_IMPORTED_MODULE_2__);
|
||||
/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm.js");
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -56316,7 +56596,7 @@ __webpack_require__(/*! ./bootstrap */ "./resources/views/front/canard/js/bootst
|
|||
|
||||
__webpack_require__(/*! ./cart.js */ "./resources/views/front/canard/js/cart.js");
|
||||
|
||||
window.Toastify = toastify_js__WEBPACK_IMPORTED_MODULE_1___default.a;
|
||||
window.Toastify = toastify_js__WEBPACK_IMPORTED_MODULE_2___default.a;
|
||||
window.Vue = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.common.js"); // Vuex
|
||||
|
||||
|
||||
|
|
@ -56338,7 +56618,7 @@ Vue.component('basket-counter', {
|
|||
},
|
||||
template: '<span class="header-actions__item-icon icon icon_cart"><span class="icon__count">{{ count }}</span></span>'
|
||||
});
|
||||
var store = new vuex__WEBPACK_IMPORTED_MODULE_2__["default"].Store({
|
||||
var store = new vuex__WEBPACK_IMPORTED_MODULE_3__["default"].Store({
|
||||
state: {
|
||||
panier: {},
|
||||
cartTotals: {}
|
||||
|
|
@ -56372,7 +56652,7 @@ var app = new Vue({
|
|||
$(document).ready(function () {
|
||||
//document is ready we can free css transitions
|
||||
$('.preload').removeClass("preload");
|
||||
var mainslider = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0___default.a('.mainslider .swiper-container', {
|
||||
var mainslider = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1___default.a('.mainslider .swiper-container', {
|
||||
pagination: {
|
||||
el: '.mainslider__pagination',
|
||||
bulletClass: 'slider-bullet',
|
||||
|
|
@ -56380,7 +56660,7 @@ $(document).ready(function () {
|
|||
clickable: true
|
||||
}
|
||||
});
|
||||
var rp_slider = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0___default.a('.rp-slider .swiper-container', {
|
||||
var rp_slider = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1___default.a('.rp-slider .swiper-container', {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 40,
|
||||
navigation: {
|
||||
|
|
@ -56412,7 +56692,7 @@ $(document).ready(function () {
|
|||
}
|
||||
}
|
||||
});
|
||||
var rp_slider_mobile = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_0___default.a('.related-products-mobile .swiper-container', {
|
||||
var rp_slider_mobile = new swiper_swiper_bundle__WEBPACK_IMPORTED_MODULE_1___default.a('.related-products-mobile .swiper-container', {
|
||||
slidesPerView: 4,
|
||||
spaceBetween: 20,
|
||||
navigation: {
|
||||
|
|
|
|||
6
resources/js/app.js
vendored
6
resources/js/app.js
vendored
|
|
@ -1,7 +1,13 @@
|
|||
require('./bootstrap');
|
||||
window.Vue = require('vue');
|
||||
|
||||
// Vuex
|
||||
// import Vuex from 'vuex';
|
||||
// import { Container, Draggable } from 'vue-smooth-dnd';
|
||||
// import { applyDrag, generateItems } from './helpers';
|
||||
|
||||
Vue.component('faq', require('./components/Faq.vue').default);
|
||||
Vue.component('products-cards-dnd', require('./components/ProductsCardsDnd.vue').default);
|
||||
|
||||
const app = new Vue({
|
||||
el: '#app',
|
||||
|
|
|
|||
214
resources/js/components/ProductsCardsDnd.vue
Normal file
214
resources/js/components/ProductsCardsDnd.vue
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
<template>
|
||||
<div class="wide-page">
|
||||
|
||||
<div class="columns">
|
||||
|
||||
<div v-for="(items, index) in groups"
|
||||
:key="index"
|
||||
class="column"
|
||||
>
|
||||
<div>
|
||||
<label>
|
||||
<input type="checkbox" v-model="flags[index].drop"> Accept Drop
|
||||
</label>
|
||||
<label>
|
||||
<input type="checkbox" v-model="flags[index].animate"> Animate Drop
|
||||
</label>
|
||||
</div>
|
||||
<Container :data-index="index" group-name="column"
|
||||
|
||||
:get-child-payload="itemIndex => getChildPayload(index, itemIndex)"
|
||||
:should-accept-drop="(src, payload) => getShouldAcceptDrop(index, src, payload)"
|
||||
:should-animate-drop="(src, payload) => getShouldAnimateDrop(index, src, payload)"
|
||||
|
||||
@drag-start="onDragStart"
|
||||
@drag-enter="onDragEnter(index)"
|
||||
@drag-leave="onDragLeave(index)"
|
||||
@drag-end="onDragEnd"
|
||||
@drop="onDrop(index, $event)"
|
||||
>
|
||||
<Draggable v-for="item in items" :key="item.id">
|
||||
<div class="draggable-item">
|
||||
{{ item.data }}
|
||||
</div>
|
||||
</Draggable>
|
||||
</Container>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<div>
|
||||
<button @click="removeColumn()" :disabled="groups.length === 1">Remove Column</button>
|
||||
<button @click="addColumn()">Add Column</button>
|
||||
</div>
|
||||
<div>
|
||||
<label v-for="(key, name) in logs" :key="name">
|
||||
<input type="checkbox" v-model="logs[name]"> {{ name }}
|
||||
</label>
|
||||
<hr>
|
||||
<label>
|
||||
<input type="checkbox" v-model="logPayload"> Log payload
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Container, Draggable } from 'vue-smooth-dnd'
|
||||
import { applyDrag, generateItems } from '../helpers'
|
||||
import Vue from 'vue'
|
||||
|
||||
let i = 0
|
||||
|
||||
function id () {
|
||||
return `item-${++i}`
|
||||
}
|
||||
|
||||
function generate (num) {
|
||||
return generateItems(5, i => ({
|
||||
id: id(),
|
||||
data: `Draggable ${num} - ${i + 1}`
|
||||
}))
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'Events',
|
||||
|
||||
components: {
|
||||
Container,
|
||||
Draggable
|
||||
},
|
||||
|
||||
data () {
|
||||
return {
|
||||
groups: [],
|
||||
flags: [],
|
||||
logs: {
|
||||
'get-child-payload': true,
|
||||
'should-accept-drop': false,
|
||||
'should-animate-drop': false,
|
||||
'drag-start': true,
|
||||
'drag-end': true,
|
||||
'drag-enter': true,
|
||||
'drag-leave': true,
|
||||
'drop': true
|
||||
},
|
||||
logPayload: true
|
||||
}
|
||||
},
|
||||
|
||||
created () {
|
||||
this.addColumn()
|
||||
},
|
||||
|
||||
methods: {
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// callbacks
|
||||
|
||||
getChildPayload (groupIndex, itemIndex) {
|
||||
this.log('get-child-payload', groupIndex, itemIndex)
|
||||
return this.groups[groupIndex][itemIndex]
|
||||
},
|
||||
|
||||
getShouldAcceptDrop (index, sourceContainerOptions, payload) {
|
||||
this.log('should-accept-drop', sourceContainerOptions, payload)
|
||||
return this.flags[index].drop
|
||||
},
|
||||
|
||||
getShouldAnimateDrop (index, sourceContainerOptions, payload) {
|
||||
this.log('should-animate-drop', sourceContainerOptions, payload)
|
||||
return this.flags[index].animate
|
||||
},
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// events
|
||||
|
||||
onDragStart (...args) {
|
||||
this.log('drag-start', ...args)
|
||||
},
|
||||
|
||||
onDragEnd (...args) {
|
||||
this.log('drag-end', ...args)
|
||||
},
|
||||
|
||||
onDragEnter (...args) {
|
||||
this.log('drag-enter', ...args)
|
||||
},
|
||||
|
||||
onDragLeave (...args) {
|
||||
this.log('drag-leave', ...args)
|
||||
},
|
||||
|
||||
onDrop (groupIndex, dropResult) {
|
||||
let result = applyDrag(this.groups[groupIndex], dropResult)
|
||||
Vue.set(this.groups, groupIndex, result)
|
||||
this.log('drop', dropResult)
|
||||
},
|
||||
|
||||
// -----------------------------------------------------------------------------------------------------------------
|
||||
// app
|
||||
|
||||
addColumn () {
|
||||
this.groups.push(generate(this.groups.length + 1))
|
||||
this.flags.push({drop: true, animate: true})
|
||||
},
|
||||
|
||||
removeColumn () {
|
||||
this.groups.pop()
|
||||
this.flags.pop()
|
||||
},
|
||||
|
||||
log (name, ...args) {
|
||||
if (this.logs[name]) {
|
||||
this.logPayload
|
||||
? console.log(name, ...args)
|
||||
: console.log(name)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.controls {
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.controls > div {
|
||||
padding-top: 1em;
|
||||
}
|
||||
|
||||
label {
|
||||
display: block;
|
||||
line-height: 1.6em;
|
||||
}
|
||||
|
||||
.columns {
|
||||
display: flex;
|
||||
justify-content: stretch;
|
||||
}
|
||||
|
||||
.column {
|
||||
margin-right: 20px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.column .smooth-dnd-container.vertical {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
</style>
|
||||
26
resources/js/helpers.js
vendored
Normal file
26
resources/js/helpers.js
vendored
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
//for testing purposes
|
||||
export const applyDrag = (arr, dragResult) => {
|
||||
const { removedIndex, addedIndex, payload } = dragResult
|
||||
if (removedIndex === null && addedIndex === null) return arr
|
||||
|
||||
const result = [...arr]
|
||||
let itemToAdd = payload
|
||||
|
||||
if (removedIndex !== null) {
|
||||
itemToAdd = result.splice(removedIndex, 1)[0]
|
||||
}
|
||||
|
||||
if (addedIndex !== null) {
|
||||
result.splice(addedIndex, 0, itemToAdd)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
export const generateItems = (count, creator) => {
|
||||
const result = []
|
||||
for (let i = 0; i < count; i++) {
|
||||
result.push(creator(i))
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
@ -51,5 +51,7 @@
|
|||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
{{ $products->links() }}
|
||||
|
||||
@endsection
|
||||
|
||||
|
|
|
|||
54
resources/views/bo/promotions/create.blade.php
Normal file
54
resources/views/bo/promotions/create.blade.php
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
@extends('layouts.bo-layout')
|
||||
|
||||
@section('content')
|
||||
<form action="{{route('bo.promotions.store')}}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2"><a href="{{route('bo.promotions.index')}}" class="h2 text-decoration-none"><</a> Promotions <small class="text-muted">Création</small></h1>
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Enregistrer</a>
|
||||
</div>
|
||||
</div>
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
{{-- //TODO implementer plus tard <products-cards-dnd></products-cards-dnd> --}}
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Produit *</label>
|
||||
<input type="text" id="product_id" name="product_id" class="form-control" placeholder="Produit * " value="{{ old('product_id') }}" required>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col">
|
||||
<label for="discount_type_id">Type de remise *</label>
|
||||
<select class="custom-select" id="discount_type_id" name="discount_type_id">
|
||||
@foreach($discTypes as $discType)
|
||||
<option value="{{$discType->id}}">{{$discType->label}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col">
|
||||
<label for="discount_value">Valeur *</label>
|
||||
<input type="number" id="discount_value" name="discount_value" min="0" step=".01" class="form-control" value="{{ old('discount_value') }}" required>
|
||||
<small class="text-muted"> montant ou pourcentage de remise selon le type choisi </small>
|
||||
</div>
|
||||
<div class="form-group col">
|
||||
<label for="date_start_date">Début <small class="text-muted"> de la promotion </small></label>
|
||||
<input type="date" id="date_start_date" name="date_start_date" class="form-control" value="{{ old('date_start_date') }}" required>
|
||||
<input type="time" id="date_start_time" name="date_start_time" class="form-control" value="{{ old('date_start_time') }}" required>
|
||||
</div>
|
||||
<div class="form-group col">
|
||||
<label for="date_end_date">Fin <small class="text-muted"> de la promotion </small></label>
|
||||
<input type="date" id="date_end_date" name="date_end_date" class="form-control" value="{{ old('date_end_date') }}" required>
|
||||
<input type="time" id="date_end_time" name="date_end_time" class="form-control" value="{{ old('date_end_time') }}" required>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
56
resources/views/bo/promotions/edit.blade.php
Normal file
56
resources/views/bo/promotions/edit.blade.php
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
@extends('layouts.bo-layout')
|
||||
|
||||
@section('content')
|
||||
<form action="{{route('bo.promotions.update', $promotion->id)}}" method="POST" enctype="multipart/form-data">
|
||||
@method('PUT')
|
||||
@csrf
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2"><a href="{{route('bo.promotions.index')}}" class="h2 text-decoration-none"><</a> Promotion <small class="text-muted">Modification</small></h1>
|
||||
@if (session('success'))
|
||||
<span class="float-center text-success">{{ session('success') }}</span>
|
||||
@endif
|
||||
<div class="btn-toolbar mb-2 mb-md-0">
|
||||
<button type="submit" class="btn btn-sm btn-primary">Enregistrer</a>
|
||||
</div>
|
||||
</div>
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="form-group">
|
||||
<label for="name">Produit *</label>
|
||||
<input type="text" id="product_id" name="product_id" class="form-control" placeholder="Produit * " value="{{ old('product_id', implode(",",$promotion->products->pluck('id')->all())) }}" required>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-group col">
|
||||
<label for="discount_type_id">Type de remise *</label>
|
||||
<select class="custom-select" id="discount_type_id" name="discount_type_id">
|
||||
@foreach($discTypes as $discType)
|
||||
<option value="{{$discType->id}}" @if ($discType->id === $promotion->discount_type_id) selected @endif>{{$discType->label}}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group col">
|
||||
<label for="discount_value">Valeur *</label>
|
||||
<input type="number" id="discount_value" name="discount_value" min="0" step=".01" class="form-control" value="{{ old('discount_value',$promotion->discount_value) }}" required>
|
||||
<small class="text-muted"> montant ou pourcentage de remise selon le type choisi </small>
|
||||
</div>
|
||||
<div class="form-group col">
|
||||
<label for="date_start_date">Début <small class="text-muted"> de la promotion </small></label>
|
||||
<input type="date" id="date_start_date" name="date_start_date" class="form-control" value="{{ old('date_start_date', date_format($promotion->date_start, "Y-m-d")) }}" required>
|
||||
<input type="time" id="date_start_time" name="date_start_time" class="form-control" value="{{ old('date_start_time', date_format($promotion->date_start, "H:i")) }}" required>
|
||||
</div>
|
||||
<div class="form-group col">
|
||||
<label for="date_end_date">Fin <small class="text-muted"> de la promotion </small></label>
|
||||
<input type="date" id="date_end_date" name="date_end_date" class="form-control" value="{{ old('date_end_date', date_format($promotion->date_end, "Y-m-d")) }}" required>
|
||||
<input type="time" id="date_end_time" name="date_end_time" class="form-control" value="{{ old('date_end_time', date_format($promotion->date_end, "H:i")) }}" required>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
@endsection
|
||||
61
resources/views/bo/promotions/index.blade.php
Normal file
61
resources/views/bo/promotions/index.blade.php
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
@extends('layouts.bo-layout')
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom">
|
||||
<h1 class="h2">Promotions <small class="text-muted">Liste</small></h1>
|
||||
|
||||
@if ($errors->any())
|
||||
@foreach($errors->all() as $error)
|
||||
<span class="float-center text-danger">{{ $error }}</span>
|
||||
@endforeach
|
||||
@endif
|
||||
<a href="{{route('bo.promotions.create')}}" class="btn btn-primary float-right">Créer une promotion</a>
|
||||
</div>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<th scope="col">Type</th>
|
||||
<th scope="col">Valeur</th>
|
||||
<th scope="col">Début</th>
|
||||
<th scope="col">Fin</th>
|
||||
<th scope="col">Produits Concernés</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($promotions as $promotion)
|
||||
<tr>
|
||||
<td>{{$promotion->discountType->label}}</>
|
||||
<td>{{$promotion->discount_value}}</>
|
||||
<td>{{$promotion->date_start}}</td>
|
||||
<td>{{$promotion->date_end}}</td>
|
||||
<td style="display: flex;">
|
||||
@foreach ($promotion->products as $product)
|
||||
<div class="card col-md-3">
|
||||
<img class="card-img-top" src="/images/produits/{{$product->picture}}" alt="{{$product->name}}">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title"><a href="{{route('bo.products.edit', $product->id)}}">{{$product->name}}</a></h5>
|
||||
<small class="text-muted">Prix HT avant promo : {{$product->price}}</small>
|
||||
<p class="card-text">Prix HT après promo :
|
||||
@if ($promotion->discountType->id == 1)
|
||||
{{$product->price-$promotion->discount_value}}
|
||||
@else
|
||||
{{$product->price-($product->price*$promotion->discount_value/100)}}
|
||||
@endif
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<a href="{{route('bo.promotions.edit', $promotion->id)}}" class="btn btn-sm btn-primary">Éditer</a>
|
||||
<form action="{{route('bo.promotions.destroy', $promotion->id)}}" method="POST" class="d-inline">
|
||||
@method('DELETE')
|
||||
@csrf
|
||||
<input type="submit" class="btn btn-sm btn-danger" value="Supprimer"
|
||||
onclick="return confirm('Êtes-vous sûr(e) ?')">
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
@endsection
|
||||
1
resources/views/front/canard/js/app.js
vendored
1
resources/views/front/canard/js/app.js
vendored
|
|
@ -1,3 +1,4 @@
|
|||
import { isWindow } from 'jquery';
|
||||
import Swiper from 'swiper/swiper-bundle';
|
||||
import Toastify from "toastify-js";
|
||||
require('./bootstrap');
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@
|
|||
<span>Fermer</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="message-box" v-show="!(emptybasket)">
|
||||
<!-- <div class="message-box" v-show="!(emptybasket)">
|
||||
<div class="message-box__inner">
|
||||
<div class="message-box__heading message-box__icon message-box__icon--low">
|
||||
Vous n’êtes pas connecté
|
||||
|
|
@ -79,9 +79,9 @@
|
|||
</a></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="no-slot-alert" v-show="!(emptybasket)">
|
||||
<!-- what is the purpose of this one ? -->
|
||||
<!-- show next available collection slot ? -->
|
||||
</div>
|
||||
<div class="basket-panel__content basket-panel__content--smooth-scroll" v-show="!(emptybasket)">
|
||||
<section class="cart-tile cart-tile--open" drivetype="drive">
|
||||
|
|
@ -132,7 +132,7 @@
|
|||
<ol>
|
||||
<!-- boucleproduits -->
|
||||
<li class="basket-products-list__product-card basket-products-list__product-card--no-margin" v-for="item in panier">
|
||||
<article class="ds-product-card--largehorizontal ds-product-card" id="3560070820542">
|
||||
<article class="ds-product-card--largehorizontal ds-product-card">
|
||||
<div class="ds-product-card--largehorizontal-icons">
|
||||
<div title="Supprimer" class="product-card-delete" @click="removeItem(item.cartItem.rowId)"></div>
|
||||
</div>
|
||||
|
|
@ -193,38 +193,43 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="ds-product-card--largehorizontal-infos-sec">
|
||||
<!-- promotion
|
||||
<div class="ds-product-card--largehorizontal-promotion">
|
||||
<!-- promotion -->
|
||||
<div class="ds-product-card--largehorizontal-promotion" v-show="item.product.calculatedPrices.discountAmount>0" v-for="promotion in item.product.promotions">
|
||||
<div>
|
||||
<div class="promotion-description promotion-description--loyalty">
|
||||
<div class="promotion-description__labels">
|
||||
<p title="20% d'économies" class="promotion-label"><span class="promotion-label__txt">20% d'économies</span></p>
|
||||
</div> <svg focusable="false" class="promotion-description__icon-info">
|
||||
<div class="promotion-description__labels" @mouseover="hover('promotion_slide',item.cartItem.rowId)" @mouseleave="hover('promotion_slide','-1')">
|
||||
<p :title="item.product.calculatedPrices.discountRate+'% d\'économies'" class="promotion-label">
|
||||
<span class="promotion-label__txt">{{ item.product.calculatedPrices.discountRate }}% d'économies</span>
|
||||
</p>
|
||||
</div>
|
||||
<svg focusable="false" class="promotion-description__icon-info">
|
||||
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-info"></use>
|
||||
</svg>
|
||||
</div>
|
||||
<section class="promotion-slide" style="display: none;">
|
||||
<section class="promotion-slide" v-show="promotion_slide == item.cartItem.rowId">
|
||||
<header class="promotion-slide__header promotion-slide__header--loyalty">
|
||||
<p class="promotion-slide__header-txt"><svg focusable="false" class="promotion-slide__icon-promo">
|
||||
<p class="promotion-slide__header-txt">
|
||||
<svg focusable="false" class="promotion-slide__icon-promo">
|
||||
<use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#icon-carrefour-loyalty-card-hightlighted"></use>
|
||||
</svg>
|
||||
<span class="promotion-slide__header-label">
|
||||
Cagnottés sur la carte
|
||||
Economisé
|
||||
</span>
|
||||
<span class="promotion-slide__header-discount">
|
||||
{{ numFormatter((Math.round((item.product.calculatedPrices.priceTtc - item.product.calculatedPrices.discountedPriceTtc)*100)/100) * item.cartItem.qty) }}
|
||||
</span>
|
||||
<span class="promotion-slide__header-discount">0,01€</span>
|
||||
</p>
|
||||
</header>
|
||||
<p class="promotion-slide__txt"><span><b>20% d'économies</b><br></span>
|
||||
<span class="promotion-slide__end-date">Offre valable jusqu'au 09/03/2021</span>
|
||||
<p class="promotion-slide__txt"><span><b>{{ item.product.calculatedPrices.discountRate }}% d'économies</b><br></span>
|
||||
<span class="promotion-slide__end-date">Offre valable jusqu'au {{ dateFormatter(promotion.date_end) }}</span>
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
<div class="ds-product-card--largehorizontal-pricing">
|
||||
<div class="product-card-price">
|
||||
<div class="product-card-price__price"><span class="ds-title product-card-price__price--final ds-title--m product-card-price__discount--fid">
|
||||
{{ (item.cartItem.price * (1+item.cartItem.taxRate/100)) }}€ TTC
|
||||
{{ numFormatter(item.product.calculatedPrices.discountedPriceTtc) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -275,7 +280,7 @@
|
|||
</dt>
|
||||
<dd>
|
||||
<div class="ds-body-text ds-body-text--weight-bold ds-body-text--size-m">
|
||||
{{cartTotals.totalTTC}} €
|
||||
{{numFormatter(cartTotals.totalTTC)}}
|
||||
</div>
|
||||
</dd>
|
||||
</dl>
|
||||
|
|
@ -335,7 +340,7 @@
|
|||
Total
|
||||
</h2>
|
||||
<h2 class="ds-title ds-title--bold ds-title--m ds-title--bright">
|
||||
{{cartTotals.totalTTC}} €
|
||||
{{numFormatter(cartTotals.totalTTC)}}
|
||||
</h2>
|
||||
</div>
|
||||
<button class="pl-button pl-button--primary pl-button--light">
|
||||
|
|
@ -384,6 +389,7 @@ export default {
|
|||
errors:false,
|
||||
showConfirmEmpty:false,
|
||||
response: '',
|
||||
promotion_slide: -1
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -476,6 +482,20 @@ export default {
|
|||
type: 'updateCartTotals',
|
||||
cartTotals: result[1]
|
||||
});
|
||||
},
|
||||
hover(zone,row_id) {
|
||||
console.log(this.promotion_slide);
|
||||
eval("this."+zone+"='"+row_id+"';");
|
||||
console.log(this.promotion_slide);
|
||||
},
|
||||
//general purpose TODO : globalize
|
||||
numFormatter(num) {
|
||||
return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(num);
|
||||
},
|
||||
dateFormatter(str) {
|
||||
let d=new Date(str);
|
||||
var options = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' };
|
||||
return d.toLocaleDateString("fr-FR",options);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,52 +1,55 @@
|
|||
<div class="product-list">
|
||||
{{-- Section offre spéciale --}}
|
||||
@foreach ($offres as $product)
|
||||
<div class="product-list__block product-list__block_wide desktop">
|
||||
<form class="pl-item pl-item_wide">
|
||||
<div class="pl-item pl-item_wide">
|
||||
<div class="pl-item__panel">Offre spéciale</div>
|
||||
<div class="pl-item__content">
|
||||
<a class="pl-item__title title title_xs" href="#">Bloc de foie gras avec 30% de morceaux 450 g en terrine </a>
|
||||
<a class="pl-item__title title title_xs" href="{{route('product', ['productSlug' => $product->slug])}}">{{ $product->name }}</a>
|
||||
<div class="pl-item__row">
|
||||
<div class="pl-item__row-block">
|
||||
<a class="pl-item__image" href="#"><img src="{{ asset(config('app.theme').'/img/demo/product_wide.png') }}" /></a>
|
||||
<a class="pl-item__image" href="{{route('product', ['productSlug' => $product->slug])}}"><img src="{{ asset('/images/produits/' . $product->picture )}}" /></a>
|
||||
</div>
|
||||
<div class="pl-item__row-block">
|
||||
<div class="pl-item-description">
|
||||
Etiam sed sodales turpis. Ut pulvinar scelerisque dui. Nulla volutpat velit a ligula tristique rutrum. Cras mi tellus, viverra ut imperdiet in, dignissim nec nulla.
|
||||
{!! $product->description !!}
|
||||
</div>
|
||||
<div class="pl-item__bottom">
|
||||
<div class="pl-item__price">
|
||||
<span class="pl-item__newprice title title_small">3,80€/pièce</span>
|
||||
10,00€/pièce
|
||||
<span class="pl-item__newprice title title_small">@fmt_currency($product->discountedPriceTtc) / {{ $product->sell_unit }}</span>
|
||||
@fmt_currency($product->priceTtc) / {{ $product->sell_unit }}
|
||||
</div>
|
||||
<button class="pl-item__btn btn btn_blue"></button>
|
||||
<button class="pl-item__btn btn btn_blue" @click="addtocart({{ $product->id }},1)"></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="product-list__block mobile">
|
||||
<form class="pl-item pl-item_offre">
|
||||
<div class="pl-item pl-item_offre">
|
||||
<div class="pl-item__panel">Offre spéciale</div>
|
||||
<a class="pl-item__title title title_xs" href="#">Bloc de foie gras avec 30% de morceaux 450 g en terrine</a>
|
||||
<a class="pl-item__image" href="#"><img src="{{ asset(config('app.theme').'/img/demo/pl_1.png') }}" /></a>
|
||||
<a class="pl-item__title title title_xs" href="{{route('product', ['productSlug' => $product->slug])}}">{{ $product->name }}</a>
|
||||
<a class="pl-item__image" href="{{route('product', ['productSlug' => $product->slug])}}"><img src="{{ asset('/images/produits/' . $product->picture )}}" /></a>
|
||||
<div class="pl-item__bottom">
|
||||
<div class="pl-item__prices">
|
||||
<span class="pl-item__newprice title title_small">3,80€/pièce</span>
|
||||
<div class="pl-item__price">10,00€/pièce</div>
|
||||
<span class="pl-item__newprice title title_small">@fmt_currency($product->discountedPriceTtc) / {{ $product->sell_unit }}</span>
|
||||
<div class="pl-item__price">@fmt_currency($product->priceTtc)/{{ $product->sell_unit }}</div>
|
||||
</div>
|
||||
<button class="pl-item__btn btn btn_blue"></button>
|
||||
<button class="pl-item__btn btn btn_blue" @click="addtocart({{ $product->id }},1)"></button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endforeach
|
||||
{{-- Fin Section offre spéciale --}}
|
||||
@foreach ($products as $product)
|
||||
<div class="product-list__block">
|
||||
<div class="pl-item">
|
||||
<a class="pl-item__title title title_xs" href="{{route('product', ['productSlug' => $product->slug])}}">{{ $product->name }}</a>
|
||||
<a class="pl-item__image" href="{{route('product', ['productSlug' => $product->slug])}}"><img src="{{ asset('/images/produits/' . $product->picture )}}" /></a>
|
||||
<div class="pl-item__bottom">
|
||||
<div class="pl-item__price">{{ $product->formattedPriceTTC }}/{{ $product->sell_unit }}</div>
|
||||
<div class="pl-item__price">@fmt_currency($product->discountedPriceTtc)/{{ $product->sell_unit }}</div>
|
||||
<button class="pl-item__btn btn btn_blue" @click="addtocart({{ $product->id }},1)"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
</div>
|
||||
|
||||
<div class="product__trade">
|
||||
<div class="product__price title title_small mb0">{{ $product->formattedPriceTTC }}/pièce</div>
|
||||
<div class="product__price title title_small mb0">@fmt_currency($product->discountedPriceTtc)/{{$product->sell_unit}}</div>
|
||||
<div class="product__qty">
|
||||
<span class="product__qty-btn product__qty-btn_minus" @click="num--">-</span>
|
||||
<input class="product__qty-input form__input" type="text" value="1" name="product_qty" id="product_qty" v-model="num">
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ Une confirmation vient de vous être envoyée sur l’adresse mail {{ $order->cu
|
|||
<div class="order__line">
|
||||
<div class="qtt">{{ $line->quantity }} x</div>
|
||||
<div class="designation">{{ $line->product->name }}</div>
|
||||
<div class="price">{{ $line->total_ttc }} €</div>
|
||||
<div class="price">{{ $line->formattedTotalTtc }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
<div class="order_total">
|
||||
<div>Total</div>
|
||||
<div>{{ $order->total }} €</div>
|
||||
<div>{{ $order->formattedTotalTtc }}</div>
|
||||
</div>
|
||||
<div class="message">
|
||||
A retirer le <b>{{$order->timeslot->day}} à {{$order->timeslot->time}}</b>, à l’adresse suivante :</br>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
</div>
|
||||
<div class="ds-product-card__shimzone--small">
|
||||
<div class="ds-body-text ds-product-card__perunitlabel ds-body-text--size-s ds-body-text--color-standard-3">
|
||||
{{ $cartItem->price }} € / {{ $cartItem->model->sell_unit }}
|
||||
@fmt_currency($cartItem->model->discountedPriceTtc) / {{ $cartItem->model->sell_unit }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="ds-product-card--largehorizontal-badges">
|
||||
|
|
@ -95,8 +95,8 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order_recap__row order_recap_unitprice">{{ $cartItem->price }} €</div>
|
||||
<div class="order_recap__row order_recap_totalprice">{{ $cartItem->price * $cartItem->qty }} €</div>
|
||||
<div class="order_recap__row order_recap_unitprice">@fmt_currency($cartItem->model->discountedPriceTtc)</div>
|
||||
<div class="order_recap__row order_recap_totalprice">{{ sprintf('%s €', number_format($cartItem->model->discountedPriceTtc * $cartItem->qty, 2, ',', ' ')) }}</div>
|
||||
@endforeach
|
||||
<!--start footer-->
|
||||
<div class="order_recap__footer order_recap_action"></div>
|
||||
|
|
|
|||
|
|
@ -60,6 +60,49 @@
|
|||
<a class="nav-link" href="{{route('bo.ranges.index')}}">Gammes de produits</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="accordion" id="accordionExample">
|
||||
{{-- <div class="card">
|
||||
<div class="card-header" id="headingProduits">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseProduits" aria-expanded="true" aria-controls="collapseOne">
|
||||
Produits
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div id="collapseProduits" class="collapse" aria-labelledby="headingProduits" tata-parent="#accordionExample">
|
||||
<div class="card-body">
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{route('bo.products.index')}}">Produits</a>
|
||||
<a class="nav-link" href="{{route('bo.ranges.index')}}">Gammes de produits</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div> --}}
|
||||
<div class="card">
|
||||
<div class="card-header" id="headingMerchandising">
|
||||
<h2 class="mb-0">
|
||||
<button class="btn btn-link btn-block text-left" type="button" data-toggle="collapse" data-target="#collapseMerchandising" aria-expanded="true" aria-controls="collapseOne">
|
||||
Merchandising
|
||||
</button>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div id="collapseMerchandising" class="collapse {{ (request()->routeIs('bo.promotions*')) ? 'show' : '' }}" aria-labelledby="headingMerchandising" tata-parent="#accordionExample">
|
||||
<div class="card-body">
|
||||
<ul class="nav flex-column mb-2">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{{route('bo.promotions.index')}}">Promotions</a>
|
||||
<a class="nav-link" href="#">Mise en avant</a>
|
||||
<a class="nav-link" href="#">Associations de produits</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">
|
||||
<span>COMMANDES</span>
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ use App\Http\Controllers\Bo\ContentController;
|
|||
use App\Http\Controllers\Bo\FaqController;
|
||||
use App\Http\Controllers\Bo\SettingsController;
|
||||
use App\Http\Controllers\Bo\OrdersController;
|
||||
//use App\Http\Controllers\Bo\RangesController;
|
||||
// AUTH
|
||||
use App\Http\Controllers\Auth\LoginController;
|
||||
|
||||
|
|
@ -55,7 +56,7 @@ Route::prefix('ajax')
|
|||
Route::post('/empty-cart', [BasketController::class, 'emptyCart'])->name('cart.empty');
|
||||
});
|
||||
|
||||
Route::namespace('Bo')
|
||||
Route::namespace('App\Http\Controllers\Bo')
|
||||
->prefix('bo')
|
||||
->name('bo.')
|
||||
->middleware(['auth', 'is-admin'])
|
||||
|
|
@ -73,7 +74,8 @@ Route::namespace('Bo')
|
|||
]);
|
||||
Route::get('/products/create/{product_type}', [\App\Http\Controllers\Bo\ProductsController::class, 'create'])
|
||||
->name('products.create');
|
||||
Route::resource('ranges', '\App\Http\Controllers\Bo\RangesController');
|
||||
Route::resource('ranges', RangesController::class);
|
||||
Route::resource('promotions', PromotionsController::class);
|
||||
// Commandes
|
||||
Route::get('/orders', [OrdersController::class, 'index'])->name('orders');
|
||||
Route::get('/orders/{reference}', [OrdersController::class, 'changeStatus'])->name('change-order-status');
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue