Remove order line + shipping point select
This commit is contained in:
parent
5aa0a479fd
commit
e7fbe920e1
5 changed files with 228 additions and 116 deletions
|
|
@ -2,10 +2,14 @@
|
|||
|
||||
namespace App\Http\Controllers\Fo;
|
||||
|
||||
use App\Enums\Order\DeliveryStatus;
|
||||
use App\Enums\Order\OrderProcess;
|
||||
use App\Enums\Order\PaymentStatus;
|
||||
use App\Enums\Order\ValidationStatus;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests\Fo\Orders\ShippingModeFormRequest;
|
||||
use App\Models\DeliveryMode;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderLine;
|
||||
use Carbon\Carbon;
|
||||
use Gloudemans\Shoppingcart\Facades\Cart;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
|
@ -28,8 +32,6 @@ class OrderController extends Controller
|
|||
$this->assertDoesNotHaveEmptyBasket();
|
||||
$this->setOrderProcessStep(OrderProcess::reviewBasket());
|
||||
|
||||
$activestep = 2;
|
||||
|
||||
/** @var \Gloudemans\Shoppingcart\Cart */
|
||||
$basket = app('basket');
|
||||
$messages = [];
|
||||
|
|
@ -43,14 +45,13 @@ class OrderController extends Controller
|
|||
$basketItems = $this->basketToList($basket);
|
||||
|
||||
return view('front.order-tunnel.basket-recap', compact(
|
||||
'activestep',
|
||||
'basket',
|
||||
'basketItems'
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Select shipping Mode
|
||||
* Select shipping Mode And create Session Order
|
||||
*
|
||||
* @return \Illuminate\Contracts\View\View
|
||||
*/
|
||||
|
|
@ -64,10 +65,60 @@ class OrderController extends Controller
|
|||
|
||||
// * CREATE ORDER
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\DeliveryMode> */
|
||||
$deliveyModes = app('DeliveryModesGlobal');
|
||||
/** @var \App\Models\Customer $customer */
|
||||
$customer = auth('frontend')->user();
|
||||
|
||||
return view('front.order-tunnel.shipping-mode');
|
||||
/** @var \Gloudemans\Shoppingcart\Cart */
|
||||
$basket = app('basket');
|
||||
|
||||
/** @var \App\Models\Order|null $order */
|
||||
$order = Order::getCurrentOrder();
|
||||
|
||||
// * If there was a previous order that was not ended use the ID.
|
||||
/** @var \App\Models\Order */
|
||||
$order = $order ?? new Order();
|
||||
$order->delivery_status = DeliveryStatus::pending();
|
||||
$order->payment_status = PaymentStatus::pending();
|
||||
$order->validation_status = ValidationStatus::pending();
|
||||
$order->assignBasket($basket);
|
||||
$order->customer()->associate($customer);
|
||||
|
||||
// * Save Session Order
|
||||
Session::put('currentOrder', $order);
|
||||
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\DeliveryMode> */
|
||||
$deliveryModes = app('DeliveryModesGlobal');
|
||||
|
||||
return view('front.order-tunnel.shipping-mode', \compact('deliveryModes'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Save shipping Mode
|
||||
*
|
||||
* @param \App\Http\Requests\Fo\Orders\ShippingModeFormRequest $request
|
||||
* @return \Illuminate\Contracts\View\View|\Illuminate\Contracts\View\Factory
|
||||
*/
|
||||
public function shippingModeSubmit(ShippingModeFormRequest $request)
|
||||
{
|
||||
$this->assertDoesNotHaveEmptyBasket();
|
||||
$this->setOrderProcessStep(OrderProcess::shippingMethod());
|
||||
|
||||
/** @var \App\Models\DeliveryMode $mode */
|
||||
if (!($mode = DeliveryMode::availables()->whereId($request->mode)->first())) {
|
||||
$e = new \RuntimeException('Mode de livraison non disponible', 1);
|
||||
report($e);
|
||||
Session::flash('error', trans('Mode de livraison non disponible'));
|
||||
return \back()->withException($e);
|
||||
}
|
||||
|
||||
/** @var \App\Models\Order $order */
|
||||
$order = Order::getCurrentOrder();
|
||||
|
||||
$order->deliveryMode()->associate($mode);
|
||||
|
||||
Session::put('currentOrder', $order);
|
||||
|
||||
return \response()->redirectToRoute('orders.shipping');
|
||||
}
|
||||
|
||||
// * --- FIN TUNNEL DE COMMANDE ---
|
||||
|
|
|
|||
47
app/Http/Requests/Fo/Orders/ShippingModeFormRequest.php
Normal file
47
app/Http/Requests/Fo/Orders/ShippingModeFormRequest.php
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Requests\Fo\Orders;
|
||||
|
||||
use App\Enums\DeliveryMode\DeliveryModeEnum;
|
||||
use App\Models\DeliveryMode;
|
||||
use Illuminate\Foundation\Http\FormRequest;
|
||||
use Kwaadpepper\Enum\Rules\EnumIsValidRule;
|
||||
|
||||
class ShippingModeFormRequest extends FormRequest
|
||||
{
|
||||
/**
|
||||
* Determine if the user is authorized to make this request.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function authorize()
|
||||
{
|
||||
return auth('frontend')->check();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the validation rules that apply to the request.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rules()
|
||||
{
|
||||
$mode = null;
|
||||
try {
|
||||
$mode = DeliveryModeEnum::make(\intval($this->mode));
|
||||
} catch (\TypeError | \BadMethodCallException $e) {
|
||||
$mode = null;
|
||||
}
|
||||
return [
|
||||
'mode' => [
|
||||
'required', new EnumIsValidRule(DeliveryModeEnum::class),
|
||||
// phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed
|
||||
function ($attribute, $value, $fail) use ($mode) {
|
||||
if (!DeliveryMode::availables()->whereId($mode)->first()) {
|
||||
$fail(trans('Mode de livraison non disponible'));
|
||||
}
|
||||
}
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -5,16 +5,30 @@ namespace App\Models;
|
|||
use App\Enums\Order\DeliveryStatus;
|
||||
use App\Enums\Order\PaymentStatus;
|
||||
use App\Enums\Order\ValidationStatus;
|
||||
use Gloudemans\Shoppingcart\Cart;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Session;
|
||||
use Kwaadpepper\Enum\Traits\CastsEnums;
|
||||
|
||||
/**
|
||||
* Order
|
||||
*
|
||||
* @property boolean can_be_cancelled Can the order be cancelled ?
|
||||
* @property integer total_ttc Total ttc in cents
|
||||
* @property string formated_total_ttc Total ttc in euro
|
||||
* @property-read string $reference The order unique reference string.
|
||||
* @property array $basket The order serialized basket.
|
||||
* @property string $email The customer email used for this order.
|
||||
* @property boolean $mail_sent Has the confirmation mail been sent to the customer.
|
||||
* @property array $shipping The shipping address info.
|
||||
* @property array $billing The billing address info.
|
||||
* @property integer $total_discounted Total discounted on this order in cents.
|
||||
* @property integer $total_ttc Total payed fro mthe customer in cents.
|
||||
* @property integer $total_ht Total without taxes in cents.
|
||||
* @property integer $total_weight Total weight in gramms.
|
||||
* @property \App\Enums\Order\ValidationStatus $validation_status The order validation status.
|
||||
* @property \App\Enums\Order\PaymentStatus $payment_status The order payment status.
|
||||
* @property \App\Enums\Order\DeliveryStatus $delivery_status The order delivery status.
|
||||
*
|
||||
* @property-read boolean $can_be_cancelled Can the order be cancelled ?
|
||||
*
|
||||
* @package App\Models
|
||||
*/
|
||||
|
|
@ -34,6 +48,15 @@ class Order extends Model
|
|||
'delivery_status' => DeliveryStatus::class
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast to native types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $casts = [
|
||||
'basket' => 'array',
|
||||
];
|
||||
|
||||
/**
|
||||
* Perform any actions required after the model boots.
|
||||
*
|
||||
|
|
@ -62,16 +85,6 @@ class Order extends Model
|
|||
return $this->belongsToMany(Product::class, 'order_lines', 'order_id', 'product_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* hasMany lines relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
*/
|
||||
public function lines()
|
||||
{
|
||||
return $this->hasMany(OrderLine::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* BelongsTo customer relation
|
||||
*
|
||||
|
|
@ -121,34 +134,6 @@ class Order extends Model
|
|||
$this->delivery_status->equals(DeliveryStatus::pending());
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter formated_total_ttc
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedTotalTtcAttribute(): string
|
||||
{
|
||||
return sprintf(
|
||||
'%s €',
|
||||
number_format($this->total_ttc / 100, 2, ',', ' ')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter total_ttc
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getTotalTtcAttribute(): int
|
||||
{
|
||||
/** @var \Illuminate\Database\Eloquent\Collection<\App\Models\OrderLine> */
|
||||
$lines = $this->lines;
|
||||
return $lines->reduce(function ($previous, OrderLine $next) {
|
||||
/** @var int|null $previous */
|
||||
return \intval($previous) + $next->getRawOriginal('total_ttc');
|
||||
});
|
||||
}
|
||||
|
||||
// * SETTER
|
||||
|
||||
/**
|
||||
|
|
@ -180,4 +165,37 @@ class Order extends Model
|
|||
throw new \RuntimeException("La commande '{$model->id}' ne peut être annulée");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get updated current session order
|
||||
*
|
||||
* @return null|\App\Models\Order
|
||||
*/
|
||||
public static function getCurrentOrder(): ?self
|
||||
{
|
||||
/** @var \App\Models\Order|null $order */
|
||||
if ($order = Session::get('currentOrder')) {
|
||||
// * Refresh order if exists in DB.
|
||||
$order = Order::where('id', $order->id)
|
||||
->orWhere('reference', $order->ref)
|
||||
->first() ?? $order;
|
||||
}
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inject the basket items into the order.
|
||||
*
|
||||
* @param \Gloudemans\Shoppingcart\Cart $basket
|
||||
* @return void
|
||||
* @throws \Illuminate\Validation\ValidationException If a product from the basket is not accessible anymore.
|
||||
*/
|
||||
public function assignBasket(Cart $basket): void
|
||||
{
|
||||
$this->basket = $basket->content();
|
||||
$this->total_discounted = \intval($basket->discount());
|
||||
$this->total_ttc = \intval($basket->total());
|
||||
$this->total_ht = \intval($this->total_ttc - $basket->tax());
|
||||
$this->total_weight = \intval($basket->weight());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* OrderLine
|
||||
*
|
||||
* @property string formated_total_ht Total ht in euro
|
||||
* @property string formated_total_ttc Total ttc in euro
|
||||
*
|
||||
* @package App\Models
|
||||
*/
|
||||
class OrderLine extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* BelongsTo order relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function order()
|
||||
{
|
||||
return $this->belongsTo(Order::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* BelongsTo product relation
|
||||
*
|
||||
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
*/
|
||||
public function product()
|
||||
{
|
||||
return $this->belongsTo(Product::class);
|
||||
}
|
||||
|
||||
// * METHODS
|
||||
|
||||
/**
|
||||
* Getter formated_total_ht
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedTotalHtAttribute(): string
|
||||
{
|
||||
return sprintf(
|
||||
'%s €',
|
||||
number_format($this->total_ht / 100, 2, ',', ' ')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter formated_total_ttc
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedTotalTtcAttribute(): string
|
||||
{
|
||||
return sprintf(
|
||||
'%s €',
|
||||
number_format($this->total_ttc / 100, 2, ',', ' ')
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class AddMoveOrderLinesIntoOrders extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
// * Trucate Orders
|
||||
Schema::drop('order_lines');
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
|
||||
DB::table('timeslots')->truncate();
|
||||
DB::table('orders')->truncate();
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
|
||||
// * Create json basket field on orders.
|
||||
Schema::table('orders', function (Blueprint $table) {
|
||||
$table->json('basket')
|
||||
->default('[]')
|
||||
->after('reference');
|
||||
});
|
||||
// * Unset orders default value.
|
||||
Schema::table('orders', function (Blueprint $table) {
|
||||
$table->json('basket')
|
||||
->change()
|
||||
->default(null)
|
||||
->comment('Le panier sérialisé des produits de la commande.');
|
||||
});
|
||||
|
||||
Schema::table('orders', function (Blueprint $table) {
|
||||
$table->string('email')->after('basket')
|
||||
->comment('Adresse email de facturation (envoi du mail de confirmation)');
|
||||
$table->boolean('mail_sent')->after('email')->comment('Le mail de commande est envoyé au client.');
|
||||
$table->json('shipping')->after('mail_sent')->comment('Adresse de livraison');
|
||||
$table->json('billing')->after('shipping')->nullable()->comment('Adresse de facturation');
|
||||
$table->integer('total_discounted')->after('billing')
|
||||
->comment('Total des remises du panier en centimes, somme des lignes (discount * qty)');
|
||||
$table->integer('total_ttc')->after('total_discounted')
|
||||
->comment('Total TTC facturé en centimes, somme des lignes (prix - remise + TVA) * qty');
|
||||
$table->integer('total_ht')->after('total_ttc')
|
||||
->comment('Total HT facturé en centimes, somme des lignes (prix - remise )* qty');
|
||||
$table->integer('total_weight')->after('total_ht')->comment('Poids total en grammes');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
* @throws \Exception Wont do this.
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
throw new \Exception('Wont roll back this');
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue