wip
This commit is contained in:
30
app/Models/Ecommerce/Product/Order/Concerns/HasPayments.php
Normal file
30
app/Models/Ecommerce/Product/Order/Concerns/HasPayments.php
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Ecommerce\Product\Order\Concerns;
|
||||
|
||||
trait HasPayments
|
||||
{
|
||||
/**
|
||||
* Total price for order
|
||||
*/
|
||||
public function total(): float
|
||||
{
|
||||
return $this->items->sum('total');
|
||||
}
|
||||
|
||||
/**
|
||||
* Return total order with shipping.
|
||||
*/
|
||||
public function fullPriceWithShipping(): string
|
||||
{
|
||||
return floatval($this->total()) + floatval($this->shippingPrice()) + floatval($this->additional_tax);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatted payment type
|
||||
*/
|
||||
public function formattedPaymentType(): string
|
||||
{
|
||||
return $this->paymentType?->name;
|
||||
}
|
||||
}
|
||||
32
app/Models/Ecommerce/Product/Order/Concerns/HasShipping.php
Normal file
32
app/Models/Ecommerce/Product/Order/Concerns/HasShipping.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Ecommerce\Product\Order\Concerns;
|
||||
|
||||
use App\Models\Ecommerce\Product\Order\Shipping\OrderShipping;
|
||||
|
||||
trait HasShipping
|
||||
{
|
||||
/**
|
||||
* Shipping price
|
||||
*/
|
||||
public function shippingPrice(): int
|
||||
{
|
||||
return intval($this->shipping_price) ?: OrderShipping::priceFor($this->shipping_method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatted shipping method
|
||||
*/
|
||||
public function formattedShippingMethod(): string
|
||||
{
|
||||
return OrderShipping::formattedShippingMethod($this->shipping_method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Full address for the order
|
||||
*/
|
||||
public function fullAddress(): string
|
||||
{
|
||||
return OrderShipping::fullAddress($this->region, $this->province_id, $this->customer_address);
|
||||
}
|
||||
}
|
||||
72
app/Models/Ecommerce/Product/Order/Concerns/HasStatus.php
Normal file
72
app/Models/Ecommerce/Product/Order/Concerns/HasStatus.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Ecommerce\Product\Order\Concerns;
|
||||
|
||||
use App\Models\Ecommerce\Product\Order\Status\OrderStatus;
|
||||
|
||||
trait HasStatus
|
||||
{
|
||||
/**
|
||||
* Return the correct order status formatted.
|
||||
*/
|
||||
public function formatted_status(): string
|
||||
{
|
||||
return OrderStatus::formattedStatusFor($this->status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can order be cancelled?
|
||||
*/
|
||||
public function canBeCancelled(): bool
|
||||
{
|
||||
return $this->isPending();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if order is pending
|
||||
*/
|
||||
public function isPending(): bool
|
||||
{
|
||||
return $this->status === OrderStatus::PENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if order is registered
|
||||
*/
|
||||
public function isRegistered(): bool
|
||||
{
|
||||
return $this->status === OrderStatus::REGISTER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if order is paid
|
||||
*/
|
||||
public function isPaid(): bool
|
||||
{
|
||||
return $this->status === OrderStatus::PAID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if order is completed
|
||||
*/
|
||||
public function isCompleted(): bool
|
||||
{
|
||||
return $this->status === OrderStatus::COMPLETED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if order is completed
|
||||
*/
|
||||
public function isCancelled(): bool
|
||||
{
|
||||
return $this->status === OrderStatus::CANCELLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark order as paid
|
||||
*/
|
||||
public function markAsPaid(): void
|
||||
{
|
||||
$this->update(['status' => OrderStatus::PAID]);
|
||||
}
|
||||
}
|
||||
87
app/Models/Ecommerce/Product/Order/Order.php
Normal file
87
app/Models/Ecommerce/Product/Order/Order.php
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Ecommerce\Product\Order;
|
||||
|
||||
use App\Models\Ecommerce\Product\Order\Concerns\HasPayments;
|
||||
use App\Models\Ecommerce\Product\Order\Concerns\HasShipping;
|
||||
use App\Models\Ecommerce\Product\Order\Concerns\HasStatus;
|
||||
use App\Models\System\Settings\Location\Province;
|
||||
use App\Models\System\Settings\Payments\PaymentType;
|
||||
use App\Models\User;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Illuminate\Database\Eloquent\SoftDeletes;
|
||||
|
||||
class Order extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasPayments;
|
||||
use HasShipping;
|
||||
use HasStatus;
|
||||
use SoftDeletes;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'number',
|
||||
'status',
|
||||
'shipping_method',
|
||||
'shipping_price',
|
||||
'payment_type_id',
|
||||
'notes',
|
||||
'customer_name',
|
||||
'customer_phone',
|
||||
'customer_address',
|
||||
'delivery_time',
|
||||
'delivery_at',
|
||||
'region',
|
||||
'user_id',
|
||||
'additional_tax',
|
||||
'province_id',
|
||||
'source_app',
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be cast.
|
||||
*/
|
||||
protected $casts = [
|
||||
'delivery_at' => 'date',
|
||||
];
|
||||
|
||||
/**
|
||||
* User (customer)
|
||||
*/
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Related Province
|
||||
*/
|
||||
public function province(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Province::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Order items
|
||||
*/
|
||||
public function items(): HasMany
|
||||
{
|
||||
return $this->hasMany(OrderItem::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment types
|
||||
*/
|
||||
public function paymentType(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(PaymentType::class, 'payment_type_id');
|
||||
}
|
||||
}
|
||||
64
app/Models/Ecommerce/Product/Order/OrderItem.php
Normal file
64
app/Models/Ecommerce/Product/Order/OrderItem.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Ecommerce\Product\Order;
|
||||
|
||||
use App\Models\Ecommerce\Channel\Channel;
|
||||
use App\Models\Ecommerce\Product\Product\Product;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
|
||||
class OrderItem extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array<string>
|
||||
*/
|
||||
protected $fillable = [
|
||||
'product_name',
|
||||
'product_id',
|
||||
'order_id',
|
||||
'channel_id',
|
||||
'quantity',
|
||||
'unit_price_amount',
|
||||
'unit_cost_amount',
|
||||
];
|
||||
|
||||
/**
|
||||
* Related order (parent)
|
||||
*/
|
||||
public function order(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Order::class, 'order_id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Related product
|
||||
*/
|
||||
public function product(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Product::class, 'product_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Related Channel
|
||||
*/
|
||||
public function channel(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Channel::class, 'channel_id', 'id');
|
||||
}
|
||||
|
||||
/**
|
||||
* Total price
|
||||
*/
|
||||
public function total(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn () => (float) $this->unit_price_amount * (int) $this->quantity
|
||||
);
|
||||
}
|
||||
}
|
||||
88
app/Models/Ecommerce/Product/Order/Payment/OrderPayment.php
Normal file
88
app/Models/Ecommerce/Product/Order/Payment/OrderPayment.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Ecommerce\Product\Order\Payment;
|
||||
|
||||
use App\Models\System\Settings\Payments\PaymentType;
|
||||
use App\Repositories\System\Cache\CacheRepository;
|
||||
|
||||
class OrderPayment
|
||||
{
|
||||
/**
|
||||
* Cash
|
||||
*/
|
||||
public const CASH = 'cash';
|
||||
|
||||
/**
|
||||
* ATM
|
||||
*/
|
||||
public const ATM = 'atm';
|
||||
|
||||
/**
|
||||
* Online (halkbank)
|
||||
*/
|
||||
public const ONLINE = 'online';
|
||||
|
||||
/**
|
||||
* Online (halkbank)
|
||||
*/
|
||||
public const HALK_BANK = 'halk_bank';
|
||||
|
||||
/**
|
||||
* Online (senagat)
|
||||
*/
|
||||
public const SENAGAT_BANK = 'senegat_bank';
|
||||
|
||||
/**
|
||||
* Online (rysgal)
|
||||
*/
|
||||
public const RYSGAL_BANK = 'rysgal_bank';
|
||||
|
||||
/**
|
||||
* Online (wneshka)
|
||||
*/
|
||||
public const WNESHKA_BANK = 'wneshka_bank';
|
||||
|
||||
/**
|
||||
* Default payment value
|
||||
*/
|
||||
public static function default(): ?string
|
||||
{
|
||||
return CacheRepository::make(
|
||||
name: 'cs-nova-models-default-order-payment',
|
||||
value: fn () => PaymentType::where('code', 'cash')->pluck('id')->first(),
|
||||
time: 60 * 60 * 24
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Payment values
|
||||
*/
|
||||
public static function values(): array
|
||||
{
|
||||
return CacheRepository::make(
|
||||
name: 'cs-nova-models-order-payments',
|
||||
value: fn () => PaymentType::pluck('name', 'id')->toArray()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Old but good types
|
||||
*
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public static function oldButGoodTypes(): array
|
||||
{
|
||||
return [
|
||||
static::ATM => __('ATM'),
|
||||
static::CASH => __('Cash'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatted payment type for given "type"
|
||||
*/
|
||||
public static function formattedPaymentTypeFor(string $type): string
|
||||
{
|
||||
return static::values()[$type] ?? self::CASH;
|
||||
}
|
||||
}
|
||||
201
app/Models/Ecommerce/Product/Order/Shipping/OrderShipping.php
Normal file
201
app/Models/Ecommerce/Product/Order/Shipping/OrderShipping.php
Normal file
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Ecommerce\Product\Order\Shipping;
|
||||
|
||||
use App\Models\Ecommerce\Product\Order\Order;
|
||||
use App\Models\System\Settings\Location\Province;
|
||||
use App\Models\System\Settings\Location\Region;
|
||||
|
||||
class OrderShipping
|
||||
{
|
||||
/*
|
||||
* Shipping methods
|
||||
*
|
||||
* standart - basic
|
||||
* express - fast
|
||||
* self_pickup - self pickup
|
||||
* region - deliver to regions (mr, ah, dz, lb, bn)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Standart shipping
|
||||
*/
|
||||
public const STANDART = 'standart';
|
||||
|
||||
/**
|
||||
* Express shipping
|
||||
*/
|
||||
public const EXPRESS = 'express';
|
||||
|
||||
/**
|
||||
* On own - self pickup
|
||||
*/
|
||||
public const SELF_PICKUP = 'self_pickup';
|
||||
|
||||
/**
|
||||
* Region - shipping to regions (mr, ah, ...)
|
||||
*/
|
||||
public const REGION = 'region';
|
||||
|
||||
/*
|
||||
* Shipping method prices
|
||||
*
|
||||
* standart - 20
|
||||
* express - 30
|
||||
* self pickup - 0
|
||||
* region - 40
|
||||
*/
|
||||
|
||||
/**
|
||||
* Standart shipping price
|
||||
*/
|
||||
public const STANDART_PRICE = 20;
|
||||
|
||||
/**
|
||||
* Express shipping price
|
||||
*/
|
||||
public const EXPRESS_PRICE = 30;
|
||||
|
||||
/**
|
||||
* Self pickup shipping price
|
||||
*/
|
||||
public const SELF_PICKUP_PRICE = 0;
|
||||
|
||||
/**
|
||||
* Region shipping price
|
||||
*/
|
||||
public const REGION_PRICE = 40;
|
||||
|
||||
/**
|
||||
* Order delivery times
|
||||
*
|
||||
* morning
|
||||
* evening
|
||||
*/
|
||||
|
||||
/**
|
||||
* Morning time 09 - 12:00
|
||||
*/
|
||||
public const MORNING = '09:00 - 12:00';
|
||||
|
||||
/**
|
||||
* Evening time 13:00 - 18:00
|
||||
*/
|
||||
public const EVENING = '13:00 - 18:00';
|
||||
|
||||
/**
|
||||
* Default shipping value
|
||||
*/
|
||||
public static function default(): string
|
||||
{
|
||||
return static::STANDART;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default shipping time value
|
||||
*/
|
||||
public static function defaultTime(): string
|
||||
{
|
||||
return static::EVENING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shipping values
|
||||
*/
|
||||
public static function values(): array
|
||||
{
|
||||
return [
|
||||
self::STANDART => __('Standart'),
|
||||
self::EXPRESS => __('Express'),
|
||||
self::SELF_PICKUP => __('Self Pickup'),
|
||||
self::REGION => __('Region'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Prices
|
||||
*/
|
||||
public static function prices(): array
|
||||
{
|
||||
return [
|
||||
self::STANDART => self::STANDART_PRICE,
|
||||
self::EXPRESS => self::EXPRESS_PRICE,
|
||||
self::SELF_PICKUP => self::SELF_PICKUP_PRICE,
|
||||
self::REGION => self::REGION_PRICE,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Shipping times
|
||||
*/
|
||||
public static function times(): array
|
||||
{
|
||||
return [
|
||||
self::MORNING => self::MORNING,
|
||||
self::EVENING => self::EVENING,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get price for specific shipping
|
||||
*/
|
||||
public static function priceFor(string $type): int
|
||||
{
|
||||
return static::prices()[$type] ?? self::STANDART_PRICE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order shipping price
|
||||
*
|
||||
* @param Order $order
|
||||
*/
|
||||
public static function orderShippingPrice($order): int
|
||||
{
|
||||
if ($order->region === Region::AG) {
|
||||
return static::priceFor($order->shipping_method);
|
||||
}
|
||||
|
||||
if (in_array($order->province_id, [
|
||||
12,
|
||||
43,
|
||||
45,
|
||||
83,
|
||||
56,
|
||||
22,
|
||||
])) {
|
||||
return 30;
|
||||
}
|
||||
|
||||
return static::REGION_PRICE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatted shipping method
|
||||
*/
|
||||
public static function formattedShippingMethod(string $shippingMethod): string
|
||||
{
|
||||
return static::values()[$shippingMethod] ?? __('Standart');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get full address
|
||||
*/
|
||||
public static function fullAddress($region, $province, $customer_address): string
|
||||
{
|
||||
$address = '';
|
||||
|
||||
if ($region) {
|
||||
$address .= Region::labelFor($region);
|
||||
}
|
||||
|
||||
if ($province = Province::where('id', $province)->first('name')) {
|
||||
$address .= ', '.$province->name;
|
||||
}
|
||||
|
||||
if ($customer_address) {
|
||||
$address .= ','.$customer_address;
|
||||
}
|
||||
|
||||
return $address;
|
||||
}
|
||||
}
|
||||
89
app/Models/Ecommerce/Product/Order/Status/OrderStatus.php
Normal file
89
app/Models/Ecommerce/Product/Order/Status/OrderStatus.php
Normal file
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models\Ecommerce\Product\Order\Status;
|
||||
|
||||
class OrderStatus
|
||||
{
|
||||
/**
|
||||
* Pending orders are brand new orders that have not been processed yet.
|
||||
*/
|
||||
public const PENDING = 'pending';
|
||||
|
||||
/**
|
||||
* Orders that has been registered..
|
||||
*/
|
||||
public const REGISTER = 'register';
|
||||
|
||||
/**
|
||||
* Orders that has been paid..
|
||||
*/
|
||||
public const PAID = 'paid';
|
||||
|
||||
/**
|
||||
* Orders fulfilled completely.
|
||||
*/
|
||||
public const COMPLETED = 'completed';
|
||||
|
||||
/**
|
||||
* Order that has been cancelled.
|
||||
*/
|
||||
public const CANCELLED = 'cancelled';
|
||||
|
||||
/**
|
||||
* Default status value
|
||||
*/
|
||||
public static function default(): string
|
||||
{
|
||||
return static::PENDING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Status Values
|
||||
*/
|
||||
public static function values(): array
|
||||
{
|
||||
return [
|
||||
self::PENDING => __('Pending'),
|
||||
self::REGISTER => __('Registered'),
|
||||
self::PAID => __('Paid'),
|
||||
self::COMPLETED => __('Completed'),
|
||||
self::CANCELLED => __('Cancelled'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Formatted status for given "status"
|
||||
*/
|
||||
public static function formattedStatusFor(string $status): string
|
||||
{
|
||||
return static::values()[$status] ?? __('None');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tailwind
|
||||
*/
|
||||
public static function classes(): array
|
||||
{
|
||||
return [
|
||||
self::PENDING => 'warning',
|
||||
self::REGISTER => 'info',
|
||||
self::PAID => 'primary',
|
||||
self::COMPLETED => 'success',
|
||||
self::CANCELLED => 'danger',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* HEX Colors
|
||||
*/
|
||||
public static function colors(): array
|
||||
{
|
||||
return [
|
||||
self::PENDING => '#F5573B',
|
||||
self::REGISTER => '#F2CB22',
|
||||
self::PAID => '#098F56',
|
||||
self::COMPLETED => '#8FC15D',
|
||||
self::CANCELLED => '#d70206',
|
||||
];
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user