'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 */ protected $priceHt; protected $discountedPriceHt; protected $priceTtc; protected $discountedPriceTtc; protected $discountAmount; protected $discountRate; /** * init prices on boot */ 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 public function getCalcPrices() { //$prices = new Collection(); $prices = array( 'priceHt' => $this->priceHt, 'discountAmount' => $this->discountAmount, 'discountRate' => $this->discountRate, 'discountedPriceHt' => $this->discountedPriceHt, 'priceTtc' => $this->priceTtc, 'discountedPriceTtc' => $this->discountedPriceTtc, ); //$prices->add($cartextendedItem); return $prices; } //gross price /** * Mutator method to set priceHt's value */ public function setPriceHtAttribute($value) { $this->priceHt = $value; } /** * Get the gross price * Accessor method for priceHt * * @author Olivier Legat */ 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]); return $this->priceHt = round($weighted_price * 1000) / 1000; } else { //no calculations, alias of db property return $this->priceHt = $this->attributes['price']; } } } //discounted price public function setDiscountedPriceHtAttribute($value) { $this->discountedPriceHt = $value; } public function getDiscountedPriceHtAttribute() { if (isset($this->discountedPriceHt)) { return $this->discountedPriceHt; } else { $discountedPriceHt = $this->priceHt - $this->discountAmount; $roundingdiscountedPriceHt = round($discountedPriceHt * 1000) / 1000; return $this->discountedPriceHt = $roundingdiscountedPriceHt; } } //net price public function setPriceTtcAttribute($value) { $this->priceTtc = $value; } 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; return $this->priceTtc = $roundingPriceTtc; } } //net discounted price public function setDiscountedPriceTtcAttribute($value) { $this->discountedPriceTtc = $value; } 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; $showPrice = $this->discountedPriceTtc = $roundingDiscountedPriceTTC; } //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 calc */ //montant de remise public function setDiscountAmountAttribute($value) { $this->discountAmount = $value; } 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; } return $this->discountAmount = $discountAmount; } } //taux de remise public function setDiscountRateAttribute($value) { $this->discountRate = $value; } 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; } return $this->discountRate = $discountRate; } } // //Buyable interface public function getBuyablePrice($options = null) { return $this->priceHt; } //Relations public function range() { return $this->belongsTo('App\Models\Range', 'range_id'); } public function old_slugs() { return $this->hasMany('App\Model\OldSlug', 'product_id'); } public function stats() { return $this->hasMany('App\Models\Stat', 'product_id'); } public function orders() { return $this->belongsToMany('App\Models\Order', 'orders_products', 'product_id', 'order_id') ->withPivot('quantity'); } //relationship to additionnal product info public function additionnalProductInfo($productType) { return $this->$productType; } //possible additionnals public function foodProduct() { return $this->hasOne(FoodProduct::class, 'product_id'); } public function anifoodProduct() { return $this->hasOne(AnifoodProduct::class, 'product_id'); } public function toolProduct() { return $this->hasOne(ToolProduct::class, 'product_id'); } public function garmentProduct() { return $this->hasOne(GarmentProduct::class, 'product_id'); } //relationship to associated products public function products() { return $this->belongsToMany(Product::class, 'products_products', 'product_id', 'associated_id'); } //offres speciales public function promotions() { $now = Carbon::now(); return $this->belongsToMany(Promotion::class) ->whereDate('date_start', '<=', $now) ->whereDate('date_end', '>=', $now); } //taxe public function tax() { return $this->belongsTo(TaxRate::class, 'tax_rate_id'); } //tags public function tags() { return $this->belongsToMany(Tag::class); } }