'datetime', 'orderable_end' => 'datetime', ]; /** * Store in protected variables instead of attributes * Because those are not set in attributes, Laravel will not try to save it to database */ /** * Base Price * * @var float */ protected $priceHt; /** * Base Price after discount * * @var float */ protected $discountedPriceHt; /** * Price VAT included * * @var float */ protected $priceTtc; /** * Price after discount VAT included * * @var float */ protected $discountedPriceTtc; /** * Discount amount * * @var float */ protected $discountAmount; /** * Dsicount rate * * @var float */ protected $discountRate; /** * Bootstrap the model and its traits. * * @return void */ protected static function boot() { parent::boot(); // On data retrived from DB. static::retrieved(function ($model) { $model->priceHt = $model->getPriceHtAttribute(); $model->priceTtc = $model->getPriceTtcAttribute(); $model->discountAmount = $model->getDiscountAmountAttribute(); $model->discountRate = $model->getDiscountRateAttribute(); $model->discountedPriceHt = $model->getDiscountedPriceHtAttribute(); $model->discountedPriceTtc = $model->getDiscountedPriceTtcAttribute(); }); } /** * Price calculations * We need : gross price (prix avant taxe et remises) * discounted price (prix avant taxe avec remises) * net price (prix avec taxe) * net discounted proice (prix avec taxe et remises) */ /** * Utility to bring prices as a pseudo relation * * @return array */ public function getCalcPrices() { $prices = array( 'priceHt' => $this->priceHt, 'discountAmount' => $this->discountAmount, 'discountRate' => $this->discountRate, 'discountedPriceHt' => $this->discountedPriceHt, 'priceTtc' => $this->priceTtc, 'discountedPriceTtc' => $this->discountedPriceTtc, ); return $prices; } /** * Mutator method to set priceHt's value gross price * * @param float $value * @return void */ public function setPriceHtAttribute(float $value) { $this->priceHt = $value; } /** * Get the gross price * Accessor method for priceHt * * @author Olivier Legat * * @return float */ public function getPriceHtAttribute() { if (isset($this->priceHt)) { return $this->priceHt; } else { /** Tenir compte de l'unité de facturation et de l'unité de vente (qui doit être stricte) * si facturation KG et vente piece * prendre le poids, convertir en KG => pre-requis l'unité de poids doit être un enum * multiplier le $this->attributes['price'] par les KG * sinon * value => value */ if (config('bosettings.sell_unit_management') == "strict") { $calculate = ($this->invoicing_unit == InvoicingUnit::kgm()->value && $this->sell_unit == SellUnit::pce()->value); } else { $calculate = false; } if ($calculate) { // Weight converter. $weighted_price = $this->attributes['price'] * ($this->weight * WeightUnit::convert()[$this->weight_unit]); $this->priceHt = round($weighted_price * 1000) / 1000; return $this->priceHt; } else { // No calculations, alias of db property. $this->priceHt = $this->attributes['price']; return $this->priceHt; } }//end if } /** * setter for dicounted price * * @param float $value * @return void */ public function setDiscountedPriceHtAttribute(float $value) { $this->discountedPriceHt = $value; } /** * getter for discounted price * * @return float */ public function getDiscountedPriceHtAttribute() { if (isset($this->discountedPriceHt)) { return $this->discountedPriceHt; } else { $discountedPriceHt = $this->priceHt - $this->discountAmount; $roundingdiscountedPriceHt = round($discountedPriceHt * 1000) / 1000; $this->discountedPriceHt = $roundingdiscountedPriceHt; return $this->discountedPriceHt; } } /** * setter for net price * * @param float $value * @return void */ public function setPriceTtcAttribute(float $value) { $this->priceTtc = $value; } /** * getter for net price * * @return float */ public function getPriceTtcAttribute() { if (isset($this->priceTtc)) { return $this->priceTtc; } else { $priceTtc = $this->priceHt * ( 1 + ( $this->tax->rate / 100)); /** * On travaille avec des centimes puis on redivise par 100 pour avoir des unités monetaires * on augmente la précision à 3 digits, l'affichage formate les prix sur 2 décimales */ $roundingPriceTtc = round($priceTtc * 1000) / 1000; $this->priceTtc = $roundingPriceTtc; return $this->priceTtc; } } /** * setter for net dscounted price * * @param float $value * @return void */ public function setDiscountedPriceTtcAttribute(float $value) { $this->discountedPriceTtc = $value; } /** * getter for net dscounted price * * @return float */ public function getDiscountedPriceTtcAttribute() { if (isset($this->discountedPriceTtc)) { $showPrice = $this->discountedPriceTtc; } else { $discountedPriceTtc = $this->discountedPriceHt * ( 1 + ( $this->tax->rate / 100)); // On travaille avec des centimes puis on redivise par 100 pour avoir des unités monetaires. $roundingDiscountedPriceTTC = round($discountedPriceTtc * 1000) / 1000; $this->discountedPriceTtc = $roundingDiscountedPriceTTC; $showPrice = $this->discountedPriceTtc; } // Prix transmis en fonction du setting show_prices. if (config('bosettings.show_prices_authenticated') == "authenticated") { { if (Auth::guard('customer')->check()) { return $showPrice; } } } if (config('bosettings.show_prices_guest') == "guest") { return $showPrice; } return "-.--"; } /** * Discount calculators */ /** * set discoutn amount * * @param float $value * @return void */ public function setDiscountAmountAttribute(float $value) { $this->discountAmount = $value; } /** * Getter for discount amount * * @return float */ public function getDiscountAmountAttribute() { if (isset($this->discountAmount)) { return $this->discountAmount; } else { $applicablePromotion = $this->promotions->first(); if (null !== $applicablePromotion) { $promo_type = $applicablePromotion->discount_type_id; if ($promo_type == 1) { $discountAmount = $applicablePromotion->discount_value; } else { // On augmente la précision à 3 digits, l'affichage formate les prix sur 2 décimales. $discountAmount = $this->priceHt * ($applicablePromotion->discount_value / 100); $discountAmount = round($discountAmount * 1000) / 1000; } } else { $discountAmount = 0; } $this->discountAmount = $discountAmount; return $this->discountAmount; } } /** * set discount rate * * @param float $value * @return void */ public function setDiscountRateAttribute(float $value) { $this->discountRate = $value; } /** * get discount rate * * @return float */ public function getDiscountRateAttribute() { if (isset($this->discountRate)) { return $this->discountRate; } else { $applicablePromotion = $this->promotions->first(); if (null !== $applicablePromotion) { $promo_type = $applicablePromotion->discount_type_id; if ($promo_type == 1) { // On veut un pourcentage. $discountRate = ($applicablePromotion->discount_value / $this->priceHt) * 100; } else { $discountRate = $applicablePromotion->discount_value; } } else { $discountRate = 0; } $this->discountRate = $discountRate; return $this->discountRate; } } /** * buyablePrice attribute alias * * @param mixed $options * @return float * * @phpcs:disable Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass */ public function getBuyablePrice($options = null) { // @phpcs:enable return $this->priceHt; } /** * BelongsTo range relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function range() { return $this->belongsTo('App\Models\Range', 'range_id'); } /** * hasMany old_slugs relation * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function oldSlugs() { return $this->hasMany('App\Model\OldSlug', 'product_id'); } /** * hasMany stats relation * * @return \Illuminate\Database\Eloquent\Relations\HasMany */ public function stats() { return $this->hasMany('App\Models\Stat', 'product_id'); } /** * belongsToMany orders relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function orders() { return $this->belongsToMany('App\Models\Order', 'orders_products', 'product_id', 'order_id') ->withPivot('quantity'); } /** * Pseudo relationship to additionnal product info * * @param string $productType * @return \Illuminate\Database\Eloquent\Relations\HasOne */ public function additionnalProductInfo(string $productType) { return $this->$productType; } /** * hasOne foodProduct relation * * @return \Illuminate\Database\Eloquent\Relations\HasOne */ public function foodProduct() { return $this->hasOne(FoodProduct::class, 'product_id'); } /** * hasOne anifoodProduct relation * * @return \Illuminate\Database\Eloquent\Relations\HasOne */ public function anifoodProduct() { return $this->hasOne(AnifoodProduct::class, 'product_id'); } /** * hasOne toolProduct relation * * @return \Illuminate\Database\Eloquent\Relations\HasOne */ public function toolProduct() { return $this->hasOne(ToolProduct::class, 'product_id'); } /** * hasOne garmentProduct relation * * @return \Illuminate\Database\Eloquent\Relations\HasOne */ public function garmentProduct() { return $this->hasOne(GarmentProduct::class, 'product_id'); } /** * belongsToMany products relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function products() { return $this->belongsToMany(Product::class, 'products_products', 'product_id', 'associated_id'); } /** * belongsToMany promotions relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function promotions() { $now = Carbon::now(); return $this->belongsToMany(Promotion::class) ->whereDate('date_start', '<=', $now) ->whereDate('date_end', '>=', $now); } /** * belongsTo tax relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function tax() { return $this->belongsTo(TaxRate::class, 'tax_rate_id'); } /** * belongsToMany tags relation * * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany */ public function tags() { return $this->belongsToMany(Tag::class); } }