DateCast::class, 'support_instalments' => 'boolean', 'discount' => FloatConvertCasting::class, 'discount_percentage' => FloatConvertCasting::class, 'shipping' => FloatConvertCasting::class, 'shipping_rate' => FloatConvertCasting::class, 'total_without_tax' => FloatConvertCasting::class, 'subtotal' => FloatConvertCasting::class, 'total_with_tax' => FloatConvertCasting::class, 'total_coupons' => FloatConvertCasting::class, 'total' => FloatConvertCasting::class, 'total_cogs' => FloatConvertCasting::class, 'tax_value' => FloatConvertCasting::class, 'products_tax_value' => FloatConvertCasting::class, 'total_tax_value' => FloatConvertCasting::class, 'tendered' => FloatConvertCasting::class, 'change' => FloatConvertCasting::class, ]; public $dispatchesEvents = [ 'created' => OrderAfterCreatedEvent::class, 'updated' => OrderAfterUpdatedEvent::class, ]; protected $dispatchableFieldsEvents = [ 'payment_status' => OrderAfterPaymentStatusChangedEvent::class, ]; public function products() { return $this->hasMany( OrderProduct::class, 'order_id' ); } public function refundedProducts() { return $this->hasMany( OrderProductRefund::class, 'order_id' ); } public function user() { return $this->hasOne( User::class, 'id', 'author_id' ); } public function refunds() { return $this->hasMany( OrderRefund::class, 'order_id', 'id' ); } public function payments() { return $this->hasMany( OrderPayment::class, 'order_id' ); } public function customer() { return $this->hasOne( Customer::class, 'id', 'customer_id' ); } public function taxes() { return $this->hasMany( OrderTax::class, 'order_id', 'id' ); } public function tax_group() { return $this->hasOne( TaxGroup::class, 'id', 'tax_group_id' ); } public function coupons() { return $this->hasMany( OrderCoupon::class, 'order_id', 'id' ); } public function instalments() { return $this->hasMany( OrderInstalment::class, 'order_id', 'id' ); } public function shipping_address() { return $this->hasOne( OrderShippingAddress::class ); } public function billing_address() { return $this->hasOne( OrderBillingAddress::class ); } public function order_addresses() { return $this->hasMany( OrderAddress::class ); } public function settings() { return $this->hasMany( OrderSetting::class, 'order_id' ); } public function scopeFrom( Builder $query, string $range_starts ) { return $query->where( 'created_at', '>=', $range_starts ); } public function scopeTo( Builder $query, string $range_ends ) { return $query->where( 'created_at', '<=', $range_ends ); } public function scopePaid( Builder $query ) { return $query->where( 'payment_status', self::PAYMENT_PAID ); } public function scopeRefunded( Builder $query ) { return $query->where( 'payment_status', self::PAYMENT_REFUNDED ); } public function scopePaymentStatus( Builder $query, string $status ) { return $query->where( 'payment_status', $status ); } public function scopePaymentExpired( Builder $query ) { $date = app()->make( DateService::class ); return $query ->whereIn( 'payment_status', [ Order::PAYMENT_PARTIALLY, Order::PAYMENT_UNPAID ] ) ->where( 'final_payment_date', '<>', null ) ->where( 'final_payment_date', '<', $date->now()->toDateTimeString() ); } public function scopePaymentStatusIn( Builder $query, array $statuses ) { return $query->whereIn( 'payment_status', $statuses ); } /** * Will return conditionnaly the merged products * or all the product if it's enabled or disabled. * * @return array */ public function getCombinedProductsAttribute() { if ( ns()->option->get( 'ns_invoice_merge_similar_products', 'no' ) === 'yes' ) { $combinaison = []; $this->products()->with( 'unit' )->get()->each( function ( $product ) use ( &$combinaison ) { $values = $product->toArray(); extract( $values ); $keys = array_keys( $combinaison ); $stringified = Hook::filter( 'ns-products-combinaison-identifier', $product_id . '-' . $order_id . '-' . $discount . '-' . $product_category_id . '-' . $status, $product ); $combinaisonAttributes = Hook::filter( 'ns-products-combinaison-attributes', [ 'quantity', 'total_price_net', 'total_price', 'total_purchase_price', 'total_price_gross', 'discount', ] ); if ( in_array( $stringified, $keys ) ) { foreach ( $combinaisonAttributes as $attribute ) { $combinaison[ $stringified ][ $attribute ] += (float) $product->$attribute; } } else { $rawProduct = $product->toArray(); unset( $rawProduct[ 'id' ] ); unset( $rawProduct[ 'created_at' ] ); unset( $rawProduct[ 'updated_at' ] ); unset( $rawProduct[ 'procurement_product_id' ] ); $combinaison[ $stringified ] = $rawProduct; } } ); /** * that's nasty. */ return collect( json_decode( json_encode( $combinaison ) ) ); } return $this->products()->get(); } public function accountingJournals(): MorphMany { return $this->morphMany( AccountingJournal::class, 'source', 'source_type', 'source_id' ); } }