Remove order line + shipping point select

This commit is contained in:
Jérémy Munsch 2022-12-05 17:36:24 +01:00
parent 5aa0a479fd
commit e7fbe920e1
No known key found for this signature in database
GPG key ID: 18361AF3BFEC0FEC
5 changed files with 228 additions and 116 deletions

View file

@ -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 ---

View 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'));
}
}
]
];
}
}

View file

@ -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());
}
}

View file

@ -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, ',', ' ')
);
}
}

View file

@ -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');
}
}