initShippingExtras) { $this->initShippingExtras = true; // erst true, sonst wird es immer wieder aufgerufen $this->makeShippingExtras($instance); } return $this; } private function makeShippingExtras($instance) { if ($this->getYardExtra('shipping_price')) { $this->shipping_price = (float) ($this->getYardExtra('shipping_price')); } if ($this->getYardExtra('shipping_price_net')) { $this->shipping_price_net = (float) ($this->getYardExtra('shipping_price_net')); } if ($this->getYardExtra('shipping_tax_rate')) { $this->shipping_tax_rate = (float) ($this->getYardExtra('shipping_tax_rate')); } if ($this->getYardExtra('shipping_tax')) { $this->shipping_tax = (float) ($this->getYardExtra('shipping_tax')); } if ($this->getYardExtra('shipping_country_id')) { $this->shipping_country_id = $this->getYardExtra('shipping_country_id'); } if ($this->getYardExtra('shipping_is_for')) { $this->shipping_is_for = $this->getYardExtra('shipping_is_for'); } if ($this->getYardExtra('num_comp')) { $this->num_comp = $this->getYardExtra('num_comp'); } if ($this->getYardExtra('user_tax_free')) { $this->user_tax_free = $this->getYardExtra('user_tax_free'); } if ($this->getYardExtra('shipping_free')) { $this->shipping_free = $this->getYardExtra('shipping_free'); } if ($this->getYardExtra('user_reverse_charge')) { $this->user_reverse_charge = $this->getYardExtra('user_reverse_charge'); } if ($this->getYardExtra('user_country_id')) { $this->user_country_id = $this->getYardExtra('user_country_id'); } if ($this->getYardExtra('user_country')) { $this->user_country = $this->getYardExtra('user_country'); } if (gettype($this->shipping_country_id) !== 'object' && $this->shipping_country_id == 0) { $shippingCountry = ShippingCountry::first(); if ($shippingCountry) { $this->shipping_country_id = $shippingCountry->id; } } if ($this->shipping_price == 0) { self::instance($instance)->setShippingCountryWithPrice($this->shipping_country_id, $this->shipping_is_for); } } public function getTaxRate() { return config('cart.tax'); } public function putYardExtra($key, $value) { $content = $this->getYContent(); $content->put($key, $value); $this->putShippingExtras($content); // $this->ysession->put($this->yinstance, $content); } public function getYardExtra($key) { $content = $this->getYContent(); if ($content->has($key)) { return $content->get($key); } return false; } public function getYContent() { return $this->getShippingExtras(); /* if (is_null($this->ysession->get($this->yinstance))) { return new Collection([]); } return $this->ysession->get($this->yinstance);*/ } public function getShippingCountryName() { $shippingCountry = ShippingCountry::find($this->shipping_country_id); if ($shippingCountry && $shippingCountry->country) { return $shippingCountry->country->getLocated(); } return ''; } public function getShippingCountryCountryId() { $shippingCountry = ShippingCountry::find($this->shipping_country_id); if ($shippingCountry && $shippingCountry->country) { return $shippingCountry->country->id; } return 1; // default DE } public function getShippingCountryId() { return $this->shipping_country_id; } public function getShippingPrice() { return $this->shipping_price; } public function reCalculateShippingPrice() { $this->calculateShippingPrice(); } /** * Höchstes Versandgewicht (in Gramm) des aktuell gesetzten Versandlandes. * Ergibt sich aus der obersten Gewichtsstufe (max. weight_to). 0 = keine Begrenzung ermittelbar. */ public function getMaxWeight(): int { $shippingCountry = ShippingCountry::find($this->shipping_country_id); if (! $shippingCountry || ! $shippingCountry->shipping) { return 0; } return (int) $shippingCountry->shipping->shipping_prices->max('weight_to'); } /** * Prüft, ob das Warenkorbgewicht zzgl. des optionalen Zusatzgewichts das * Maximalgewicht des Versandlandes überschreiten würde. */ public function exceedsMaxWeight(int $additionalWeight = 0): bool { $maxWeight = $this->getMaxWeight(); if ($maxWeight <= 0) { return false; } return ($this->weight() + $additionalWeight) > $maxWeight; } public function setShippingCountryWithPrice($shipping_country_id, $shipping_is_for = 'ot-member') { $this->shipping_country_id = $shipping_country_id; $this->putYardExtra('shipping_country_id', $shipping_country_id); $this->shipping_is_for = $shipping_is_for; $this->putYardExtra('shipping_is_for', $shipping_is_for); $this->calculateShippingPrice(); } public function setUserPriceInfos($user_price_infos = []) { $this->shipping_free = isset($user_price_infos['shipping_free']) ? $user_price_infos['shipping_free'] : false; $this->putYardExtra('shipping_free', $this->shipping_free); $this->user_tax_free = $user_price_infos['user_tax_free']; $this->putYardExtra('user_tax_free', $this->user_tax_free); $this->user_reverse_charge = $user_price_infos['user_reverse_charge']; $this->putYardExtra('user_reverse_charge', $this->user_reverse_charge); $this->user_country_id = $user_price_infos['user_country_id']; $this->putYardExtra('user_country_id', $this->user_country_id); $this->user_country = Country::findOrFail($user_price_infos['user_country_id']); $this->putYardExtra('user_country', $this->user_country); } public function getUserPriceInfos() { return [ 'user_tax_free' => $this->user_tax_free, 'user_reverse_charge' => $this->user_reverse_charge, 'user_country_id' => $this->user_country_id, 'shipping_free' => $this->shipping_free, ]; } public function getUserCountryId() { return $this->user_country_id; } public function getUserCountry() { return $this->user_country; } public function getUserTaxFree() { return $this->user_tax_free ? true : false; } public function getShippingFree() { return $this->shipping_free; } public function getShippingFreeMissingValue() { if ($this->shipping_free && $this->total(2, '.', '') < $this->shipping_free) { return $this->shipping_free - $this->total(2, '.', ''); } return 0; } private function calculateShippingPrice() { $shippingCountry = ShippingCountry::find($this->shipping_country_id); if (! $shippingCountry) { return; } $shipping = $shippingCountry->shipping; $shipping_price = $shipping->shipping_prices->first(); if (! $shipping_price) { return; } if ($this->allItemsFreeShippingConsultant() || $this->weight() == 0) { $shipping_price->price = 0; $shipping_price->price_comp = 0; } else { if ($this->shipping_free && $this->total(2, '.', '') >= $this->shipping_free) { if ($this->weightByFreeShipping() == 0) { $shipping_price->price = 0; $shipping_price->price_comp = 0; } else { $shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weightByFreeShipping()); } } else { $shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weight()); // first by price // $shipping_price = $this->shippingPriceByTotal($shipping->shipping_prices, $this->total(2, '.', '')); // sec by weight // if(!$shipping_price){ // } } // default: Über der höchsten Gewichtsstufe die teuerste (höchste) Stufe nehmen, // nicht die günstigste. Im Normalfall wird das Hinzufügen vorher gestoppt (siehe exceedsMaxWeight()). if (! $shipping_price) { $shipping_price = $shipping->shipping_prices->sortByDesc('weight_to')->first(); } } if ($shipping_price) { $price = $shipping_price->price; $this->num_comp = 0; // compensation is checked in Settings if (Shop::isCompProducts($this->shipping_is_for)) { $price = $shipping_price->price_comp; $this->num_comp = $shipping_price->num_comp; } $this->shipping_price = $price; $this->shipping_tax_rate = $shipping_price->tax_rate; $this->shipping_price_net = round($price / ((100 + $shipping_price->tax_rate) / 100), 2); $this->shipping_tax = round($price / (100 + $shipping_price->tax_rate) * 100, 2); $this->putYardExtra('num_comp', $this->num_comp); $this->putYardExtra('shipping_price', $this->shipping_price); $this->putYardExtra('shipping_tax_rate', $this->shipping_tax_rate); $this->putYardExtra('shipping_tax', $this->shipping_tax); $this->putYardExtra('shipping_price_net', $this->shipping_price_net); } } private function shippingPriceByTotal($prices, $total) { foreach ($prices as $price) { if ($price->total_from > 0 && $price->total_to > 0) { if ($total >= $price->total_from && $total <= $price->total_to) { return $price; } } } return false; } private function shippingPriceByWeight($prices, $weight) { foreach ($prices as $price) { if ($price->weight_from > 0 && $price->weight_to > 0) { if ($weight >= $price->weight_from && $weight <= $price->weight_to) { return $price; } } } return false; } /** * @param null $decimals * @param null $decimalPoint * @param null $thousandSeperator * @return string */ public function shipping($decimals = null, $decimalPoint = null, $thousandSeperator = null) { return $this->numberFormat($this->shipping_price, $decimals, $decimalPoint, $thousandSeperator); } public function shippingNet($decimals = null, $decimalPoint = null, $thousandSeperator = null) { return $this->numberFormat($this->shipping_price_net, $decimals, $decimalPoint, $thousandSeperator); } // private function shippingTax($decimals = null, $decimalPoint = null, $thousandSeperator = null) { return $this->numberFormat($this->shipping_tax, $decimals, $decimalPoint, $thousandSeperator); } /* private function subShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null){ $subShipping = $this->shipping_price_net return $this->numberFormat($subShipping, $decimals, $decimalPoint, $thousandSeperator); }*/ // netto public function subtotalWithShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null) { $subtotal = (float) $this->shipping_price_net + $this->subtotal(2, '.', ''); return $this->numberFormat($subtotal, $decimals, $decimalPoint, $thousandSeperator); } public function taxWithShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null) { if ($this->user_tax_free) { return $this->numberFormat(0, $decimals, $decimalPoint, $thousandSeperator); } $total = $this->totalWithShipping(2, '.', ''); // $totalTax = (float) $this->tax(2, '.', '') + $this->shipping_tax; $totalTax = $this->subtotalWithShipping(2, '.', ''); return $this->numberFormat(($total - $totalTax), $decimals, $decimalPoint, $thousandSeperator); } public function totalWithShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null) { if ($this->user_tax_free) { $total = (float) ($this->subtotal(2, '.', '')) + $this->shipping_price_net; } else { $total = (float) ($this->total(2, '.', '')) + $this->shipping_price; } return $this->numberFormat($total, $decimals, $decimalPoint, $thousandSeperator); } /** * Get the total price of the items in the cart. * * @param int $decimals * @param string $decimalPoint * @param string $thousandSeperator * @return string */ public function weight($decimals = null, $decimalPoint = null, $thousandSeperator = null) { $content = $this->getContent(); $total = $content->reduce(function ($total, CartItem $cartItem) { return $total + ($cartItem->options->weight ? ($cartItem->options->weight * $cartItem->qty) : 0); }, 0); return $total; } public function weightByFreeShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null) { $content = $this->getContent(); $total = $content->reduce(function ($total, CartItem $cartItem) { if ($cartItem->options->no_free_shipping) { return $total + ($cartItem->options->weight ? ($cartItem->options->weight * $cartItem->qty) : 0); } return $total; }, 0); return $total; } public function allItemsFreeShippingConsultant() { $content = $this->getContent(); if ($content->isEmpty()) { return false; } return $content->every(function (CartItem $cartItem) { return (bool) $cartItem->options->free_shipping_consultant; }); } public function points() { $content = $this->getContent(); $total = $content->reduce(function ($total, CartItem $cartItem) { // Punkte als Float konvertieren (falls als String mit Komma gespeichert) $points = $cartItem->options->points ? Util::reFormatNumber($cartItem->options->points) : 0; return $total + ($points * $cartItem->qty); }, 0); return $total; } public function compCount() { $content = $this->getContent(); $count = parent::count(); $comp_count = $content->reduce(function ($comp_count, CartItem $cartItem) { return $cartItem->options->comp ? $comp_count + 1 : $comp_count; }, 0); return $count - $comp_count; } /** * Get the total price of the items in the cart. * * @param int $decimals * @param string $decimalPoint * @param string $thousandSeperator * @return string */ public function total($decimals = null, $decimalPoint = null, $thousandSeperator = null, $withFees = true) { $content = $this->getContent(); $total = $content->reduce(function ($total, CartItem $cartItem) { return $total + ($cartItem->qty * $cartItem->price); }, 0); return $this->numberFormat($total, $decimals, $decimalPoint, $thousandSeperator); } /** * Get the total tax of the items in the cart. * * @param int $decimals * @param string $decimalPoint * @param string $thousandSeperator * @return float */ public function tax($decimals = null, $decimalPoint = null, $thousandSeperator = null, $withFees = true) { $content = $this->getContent(); $tax = $content->reduce(function ($tax, CartItem $cartItem) { $priceTax = $cartItem->price / (100 + $cartItem->taxRate) * $cartItem->taxRate; return $tax + ($cartItem->qty * $priceTax); }, 0); return $this->numberFormat($tax, $decimals, $decimalPoint, $thousandSeperator); } /** * Get the subtotal (total - tax) of the items in the cart. * * @param int $decimals * @param string $decimalPoint * @param string $thousandSeperator * @return float */ public function subtotal($decimals = null, $decimalPoint = null, $thousandSeperator = null) { $content = $this->getContent(); $subTotal = $content->reduce(function ($subTotal, CartItem $cartItem) { $price_net = $cartItem->price / ((100 + $cartItem->taxRate) / 100); return $subTotal + ($cartItem->qty * $price_net); }, 0); return $this->numberFormat($subTotal, $decimals, $decimalPoint, $thousandSeperator); } public function getCartItemByProduct($product_id, $set_price = 'with') { if ($product = Product::find($product_id)) { $image = ''; if ($product->images->count()) { $image = $product->images->first()->slug; } $price = $product->price; if ($set_price === 'with') { $cartItem = $this->getCartItem($product->id, $product->getLang('name'), 1, $price, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission, 'no_free_shipping' => $product->no_free_shipping, 'show_on' => $product->show_on]); $price = $product->getPriceWith(false, true, $this->getUserCountry()); } if ($set_price === 'withTaxFree') { $cartItem = $this->getCartItem($product->id, $product->getLang('name'), 1, $price, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points, 'no_commission' => $product->no_commission, 'no_free_shipping' => $product->no_free_shipping, 'show_on' => $product->show_on]); $price = $product->getPriceWith($this->getUserTaxFree(), false, $this->getUserCountry()); } $content = $this->getContent(); if ($content->has($cartItem->rowId)) { return $content->get($cartItem->rowId); } return $cartItem; } return null; } public function getCartItem($id, $name = null, $qty = null, $price = null, array $options = []) { if ($id instanceof Buyable) { $cartItem = CartItem::fromBuyable($id, $qty ?: []); } elseif (is_array($id)) { $cartItem = CartItem::fromArray($id); } else { $cartItem = CartItem::fromAttributes($id, $name, $price, $options); } return $cartItem; } public function destroy() { // $this->ysession->remove($this->yinstance); parent::destroy(); } public function rowPriceNet(CartItem $row, $decimals = null, $decimalPoint = null, $thousandSeperator = null) { $price = round($row->price / ((100 + $row->taxRate) / 100), 4); return $this->numberFormat($price, $decimals, $decimalPoint, $thousandSeperator); } public function rowSubtotalNet(CartItem $row, $decimals = null, $decimalPoint = null, $thousandSeperator = null) { $price = round($row->price / ((100 + $row->taxRate) / 100), 4); return $this->numberFormat(($price * $row->qty), $decimals, $decimalPoint, $thousandSeperator); } public function isPriceCurrency() { return ($this->user_country && $this->user_country->currency) ? true : false; } public function getPriceCurrencyUnit() { return ($this->user_country && $this->user_country->currency) ? $this->user_country->currency_unit : false; } public function convertCurrency($value = 0, $decimals = null, $decimalPoint = null, $thousandSeperator = null) { if ($this->isPriceCurrency()) { $faktor = isset($this->user_country->currency_faktor) ? $this->user_country->currency_faktor : 1; $value = Util::reFormatNumber($value); return $this->numberFormat($value, $decimals, $decimalPoint, $thousandSeperator); } return ''; } public function getCurrencyByKey($key = false, ?CartItem $row = null, $decimals = null, $decimalPoint = null, $thousandSeperator = null) { if ($this->isPriceCurrency()) { $rNumber = 0; $faktor = isset($this->user_country->currency_faktor) ? $this->user_country->currency_faktor : 1; switch ($key) { case 'rowPriceNetCurrency': if ($row) { $price = round($row->price / ((100 + $row->taxRate) / 100), 4); $rNumber = $price * $faktor; } break; case 'rowSubtotalCurrency': if ($row) { $price = round($row->price / ((100 + $row->taxRate) / 100), 4); $rNumber = $price * $faktor * $row->qty; } break; case 'subtotal': $rNumber = (float) ($this->subtotal(2, '.', '')) * $faktor; break; case 'price': $rNumber = (float) $row->price * $faktor; break; case 'shippingNet': $rNumber = (float) ($this->shippingNet(2, '.', '')) * $faktor; break; case 'subtotalWithShipping': $rNumber = (float) ($this->subtotalWithShipping(2, '.', '')) * $faktor; break; case 'taxWithShipping': $rNumber = (float) ($this->taxWithShipping(2, '.', '')) * $faktor; break; case 'totalWithShipping': $rNumber = (float) ($this->totalWithShipping(2, '.', '')) * $faktor; break; case 'total': $rNumber = (float) ($this->total(2, '.', '')) * $faktor; break; case 'shipping': $rNumber = (float) ($this->shipping(2, '.', '')) * $faktor; break; } return $this->numberFormat($rNumber, $decimals, $decimalPoint, $thousandSeperator); } return ''; } public function getNumComp() { return $this->num_comp; } public function getCompProductBy($comp, $product_id = false) { foreach ($this->content() as $row) { if ($row->options->comp == $comp) { return $row->options->product_id; } } return false; } public function getContentByOrder() { $ret = []; $comp = []; foreach ($this->content() as $row) { if ($row->options->comp) { $comp[100 + $row->options->comp] = $row; } else { $ret[] = $row; } } ksort($comp); $ret = array_merge($ret, $comp); return $ret; } /** * Get the Formated number * * @return string */ protected function numberFormat($value, $decimals, $decimalPoint, $thousandSeperator) { if (is_null($decimals)) { $decimals = is_null(config('cart.format.decimals')) ? 2 : config('cart.format.decimals'); } if (is_null($decimalPoint)) { $decimalPoint = is_null(config('cart.format.decimal_point')) ? '.' : config('cart.format.decimal_point'); } if (is_null($thousandSeperator)) { $thousandSeperator = is_null(config('cart.format.thousand_seperator')) ? ',' : config('cart.format.thousand_seperator'); } return number_format($value, $decimals, $decimalPoint, $thousandSeperator); } public function myStore($identifier, array $eventOptions = []) { // Remove any existing identifiers // Although possibly first or update could work in future $this ->getConnection() ->table($this->getTableName()) ->where('identifier', $identifier) ->delete(); // Insert into the database with the new cart $content = $this->getContent(); $this->getConnection()->table($this->getTableName())->insert([ 'identifier' => $identifier, 'instance' => $this->currentInstance(), 'content' => serialize($content), ]); $eventOptions = array_merge([ 'cartInstance' => $this->currentInstance(), ], $eventOptions); // $this->events->dispatch('cart.stored', $eventOptions); } /** * Restore the cart with the given identifier. * * @param mixed $identifier * @return void */ }