HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/shop.komma.nl/app/Orders/Models/Order.php
<?php
namespace App\Orders\Models;

use App\Orders\Product\OrderedProduct;
use App\Users\SiteUser;
use Illuminate\Support\Collection;
use Komma\KMS\Core\Attributes\Models\Traits\HasThumbnailInterface;
use Komma\KMS\Core\Attributes\Models\Traits\HasThumbnailTrait;
use Komma\KMS\Core\Entities\DisplayNameInterface;
use Komma\KMS\Core\Entities\DisplayNameTrait;
use App\Orders\OrderStatus;
use App\Orders\Product\HasOrderedProducts;
use App\Orders\ProductComposite\OrderedProductComposite;
use App\Orders\ProductGroup\HasOrderedProductGroups;
use App\Orders\ProductGroup\HasOrderedProductGroupsInterface;
use App\Orders\Product\HasOrderedProductsInterface;
use App\Payment\Transaction;
use App\Shipments\Shipment;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use InvalidArgumentException;


/**
 * App\Orders\Models\Order
 *
 * @property int $id
 * @property string $order_number
 * @property string $invoice_number
 * @property string|null $credit_invoice_number
 * @property string $status
 * @property int|null $subtotal Sum of all products, vat inclusive
 * @property int $shipping_costs The shipping costs including vat
 * @property int|null $total total order price (inc, shipping costs, vat, shipping etc)
 * @property int $site_user_id
 * @property string $first_name
 * @property string|null $last_name_prefix
 * @property string|null $last_name
 * @property string $email
 * @property string $telephone
 * @property string|null $invoice_company
 * @property string|null $invoice_street
 * @property string|null $invoice_house_number
 * @property string|null $invoice_postal_code
 * @property string|null $invoice_city
 * @property string $invoice_country_iso3 ISO 3166-1 alpha-3 - three-letter country codes
 * @property string|null $shipping_street
 * @property string|null $shipping_house_number
 * @property string|null $shipping_postal_code
 * @property string|null $shipping_city
 * @property string $shipping_country_iso3 ISO 3166-1 alpha-3 - three-letter country codes
 * @property string $remarks Example: don't deliver at neighbours place when not at home
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property-read SiteUser $customer
 * @property-read \Illuminate\Database\Eloquent\Collection|Transaction[] $latestTransactions
 * @property-read int|null $latest_transactions_count
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Orders\ProductGroup\OrderedProductGroup[] $orderedGroups
 * @property-read int|null $ordered_groups_count
 * @property-read \Illuminate\Database\Eloquent\Collection|OrderedProductComposite[] $orderedProductComposites
 * @property-read int|null $ordered_product_composites_count
 * @property-read \Illuminate\Database\Eloquent\Collection|OrderedProduct[] $orderedProducts
 * @property-read int|null $ordered_products_count
 * @property-write mixed $customer_info
 * @property-write mixed $total_price
 * @property-write mixed $total_price_ex
 * @property-write mixed $vat_amount
 * @property-read \Illuminate\Database\Eloquent\Collection|Transaction[] $transactions
 * @property-read int|null $transactions_count
 * @method static \Illuminate\Database\Eloquent\Builder|Order newModelQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Order newQuery()
 * @method static \Illuminate\Database\Eloquent\Builder|Order query()
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereCreatedAt($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereCreditInvoiceNumber($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereEmail($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereFirstName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereInvoiceCity($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereInvoiceCompany($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereInvoiceCountryIso3($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereInvoiceHouseNumber($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereInvoiceNumber($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereInvoicePostalCode($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereInvoiceStreet($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereLastName($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereLastNamePrefix($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereOrderNumber($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereRemarks($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereShippingCity($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereShippingCosts($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereShippingCountryIso3($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereShippingHouseNumber($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereShippingPostalCode($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereShippingStreet($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereSiteUserId($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereStatus($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereSubtotal($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereTelephone($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereTotal($value)
 * @method static \Illuminate\Database\Eloquent\Builder|Order whereUpdatedAt($value)
 * @mixin \Eloquent
 * @property-read \Illuminate\Database\Eloquent\Collection|Shipment[] $shipments
 * @property-read int|null $shipments_count
 */
class Order extends Model implements HasThumbnailInterface, HasOrderedProductsInterface, HasOrderedProductGroupsInterface, DisplayNameInterface
{
    protected $name = '';
    use DisplayNameTrait;
    use HasThumbnailTrait;
    use HasOrderedProducts;
    use HasOrderedProductGroups;

    protected $guarded = ['id'];

    /** @var array The attributes that define the shipping address */
    public $shippingAttributeNames = ['shipping_street', 'shipping_house_number', 'shipping_postal_code', 'shipping_city', 'shipping_country_iso3'];

    /** @var array The attributes that define the invoice address */
    public $invoiceAttributeNames = ['invoice_street', 'invoice_house_number', 'invoice_postal_code', 'invoice_city', 'invoice_country_iso3'];

    /** @var array The attributes that define the customer */
    public $userDetailAttributeNames = ['first_name', 'last_name_prefix', 'last_name', 'email', 'telephone'];


    public function __construct(array $attributes = [])
    {
        $this->name = ucfirst(__('KMS::orders.order'));
        parent::__construct($attributes);
    }

    /*
    * Transient properties on Eloquent models
    * These are not saved to database.
    */
    protected $class = Order::class;

    /**
     * Mutates the customer_info attribute
     * @param SiteUser $user
     */
    public function setCustomerInfoAttribute($user)
    {
        if (is_numeric($user)) {
            $user = SiteUser::find($user);
            if (!$user) {
                return;
            }
        }

        $formatted = __('kms/site_users.first_name') . ': ' . $user->first_name . PHP_EOL;
        $formatted .= __('kms/site_users.last_name') . ': ' . $user->last_name . PHP_EOL;
        $formatted .= __('kms/site_users.email') . ': ' . $user->email . PHP_EOL;
        $formatted .= '' . PHP_EOL;
        $formatted .= __('shop/orders.invoice_address') . ':' . PHP_EOL;
        $formatted .= $user->street . ' ' . $user->house_number . ', ' . $user->zip_code . ', ' . $user->city . ', ' . $user->country . PHP_EOL;

        $this->attributes['customer_info'] = $formatted;
    }

    /**
     * Returns true if the order has been paid.
     */
    public function hasBeenPaid()
    {
        return in_array($this->status, [
            OrderStatus::AWAITING_FULFILLMENT,
            OrderStatus::AWAITING_SHIPMENT,
            OrderStatus::AWAITING_PICKUP,
            OrderStatus::PARTIALLY_SHIPPED,
            OrderStatus::COMPLETED,
            OrderStatus::SHIPPED,
            OrderStatus::REFUNDED,
            OrderStatus::PARTIALLY_REFUNDED
        ]);
    }

    public function customer(): BelongsTo
    {
        return $this->belongsTo(SiteUser::class, 'site_user_id');
    }

    public function orderedProductComposites():HasMany
    {
        return $this->HasMany(OrderedProductComposite::class);
    }

    /**
     * Returns all the shipping address attributes and their values
     *
     * @return array
     */
    public function getShippingAddressAttributes()
    {
        $attributes = [];
        foreach($this->shippingAttributeNames as $attributeName) $attributes[$attributeName] = $this->getAttribute($attributeName);
        return $attributes;
    }

    /**
     * Returns all the invoice address attributes and their values
     *
     * @return array
     */
    public function getInvoiceAddressAttributes()
    {
        $attributes = [];
        foreach($this->invoiceAttributeNames as $attributeName) $attributes[$attributeName] = $this->getAttribute($attributeName);
        return $attributes;
    }

    /**
     * Returns the payment transactions for the order.
     * Like successful, canceled, refunded payments.
     * But they are sorted on the created_at date.
     *
     * @return HasMany
     */
    public function latestTransactions(): HasMany
    {
        return $this->transactions()->orderBy('created_at');
    }

    /**
     * Returns the payment transactions for the order.
     * Like successful, canceled, refunded payments
     *
     * @return HasMany
     */
    public function transactions(): HasMany
    {
        return $this->hasMany(Transaction::class);
    }

    //Mutators
    public function setTotalPriceExAttribute($newValue) {
        //Check that the value is an integer. Else throw an exception. The number needs to get rounded properly first.
        if($newValue - floor($newValue) != 0) throw new InvalidArgumentException('The total_price_ex attribute must be an integer or a floating point number ending with zero decimals or have a decimal of .0');
        $this->attributes['total_price_ex'] = $newValue;
    }
    public function setTotalPriceAttribute($newValue) {
        //Check that the value is an integer. Else throw an exception. The number needs to get rounded properly first.
        if($newValue - floor($newValue) != 0) throw new InvalidArgumentException('The total_price attribute must be an integer or a floating point number ending with zero decimals or have a decimal of .0');
        $this->attributes['total_price'] = $newValue;
    }
    public function setVatAmountAttribute($newValue) {
        //Check that the value is an integer. Else throw an exception. The number needs to get rounded properly first.
        if($newValue - floor($newValue) != 0) throw new InvalidArgumentException('The vat_amount attribute must be an integer or a floating point number ending with zero decimals or have a decimal of .0');
        $this->attributes['vat_amount'] = $newValue;
    }

    public function __get($key)
    {
        if($key == 'name' && isset($this->attributes['id'])) return ucfirst(__('shop/orders.order')).' '.$this->attributes['id'];
        return parent::__get($key);
    }

    /**
     * Returns a status name for css that eventually will determine the color when this transaction is displayed.
     *
     * @return string
     */
    public function statusColor(): string {
        switch ($this->status) {
            case OrderStatus::PENDING:
            case OrderStatus::AWAITING_PAYMENT:
            case OrderStatus::AWAITING_FULFILLMENT:
            case OrderStatus::AWAITING_SHIPMENT:
            case OrderStatus::AWAITING_PICKUP:
            case OrderStatus::PARTIALLY_SHIPPED:
            case OrderStatus::PARTIALLY_REFUNDED:
            case OrderStatus::VERIFICATION:
                return 'pending';
            case OrderStatus::COMPLETED:
            case OrderStatus::SHIPPED:
            case OrderStatus::REFUNDED:
                return 'positive';
            case OrderStatus::CANCELED:
            case OrderStatus::DECLINED:
            case OrderStatus::DISPUTED:
                return 'negative';
            case OrderStatus::NEW:
            default:
                return 'default';
        }
    }

    /**
     * We use this function for now because carbon's localisation system is not picking up the
     * app locale like it should. And therefore a localized ::format is not working.
     *
     * @return string
     */
    public function displayOrderDate(): string {
        return $this->created_at->day .
            ' '.
            ucfirst(__('calendar.month_names')[$this->created_at->month - 1]) .
            ' '.
            $this->created_at->year;
    }

    public function getDisplayName(): ?string
    {
        return implode(' ', [__('KMS::orders.order'), $this->order_number]);
    }

    /**
     * @return null|string
     */
    public function customerDisplayName():?string
    {
        // If it is a new model the section name will filled by model.section.new
        if($this->last_name_prefix && $this->last_name_prefix !== '') return $this->first_name . ' ' . $this->last_name_prefix . ' ' . $this->last_name;
        return $this->first_name . ' ' . $this->last_name;
    }

    /**
     * @return HasMany
     */
    public function shipments(): HasMany
    {
        return $this->hasMany(Shipment::class);
    }
}