mivita/app/Services/Yard.php
2020-07-01 16:13:38 +02:00

312 lines
No EOL
10 KiB
PHP

<?php
namespace App\Services;
use App\Models\ShippingCountry;
use \Gloudemans\Shoppingcart\Cart;
use Gloudemans\Shoppingcart\CartItem;
use Illuminate\Session\SessionManager;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Support\Collection;
class Yard extends Cart
{
private $shipping_price = 0;
private $shipping_tax = 0;
private $shipping_country_id = 0; //default de
private $ysession;
private $yinstance;
public function __construct(SessionManager $session, Dispatcher $events)
{
$this->ysession = $session;
$this->yinstance = sprintf('%s.%s', 'cart', 'shipping_extras');
if($this->getShippingExtra('shipping_price')){
$this->shipping_price = (float) ($this->getShippingExtra('shipping_price'));
}
if($this->getShippingExtra('shipping_tax')){
$this->shipping_tax = (float) ($this->getShippingExtra('shipping_tax'));
}
if($this->getShippingExtra('shipping_country_id')){
$this->shipping_country_id = $this->getShippingExtra('shipping_country_id');
}
parent::__construct($session, $events);
if($this->shipping_country_id == 0){
$shippingCountry = ShippingCountry::first();
if($shippingCountry){
$this->shipping_country_id = $shippingCountry->id;
}
}
if($this->shipping_price == 0){
self::instance('shopping')->setShippingCountryWithPrice($this->shipping_country_id);
}
}
public static function getTaxRate()
{
return config('cart.tax');
}
public function putShippingExtra($key, $value){
$content = $this->getYContent();
$content->put($key, $value);
$this->ysession->put($this->yinstance, $content);
}
public function getShippingExtra($key){
$content = $this->getYContent();
if ($content->has($key)){
return $content->get($key);
}
return false;
}
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 getYContent()
{
if (is_null($this->ysession->get($this->yinstance))) {
return new Collection([]);
}
return $this->ysession->get($this->yinstance);
}
public function reCalculateShippingPrice(){
$this->calculateShippingPrice();
}
public function setShippingCountryWithPrice($shipping_country_id)
{
$this->shipping_country_id = $shipping_country_id;
$this->putShippingExtra('shipping_country_id', $shipping_country_id);
$this->calculateShippingPrice();
}
private function calculateShippingPrice(){
$shippingCountry = ShippingCountry::find($this->shipping_country_id);
$shipping = $shippingCountry->shipping;
if($this->weight() == 0){
$shipping_price = $shipping->shipping_prices->first();
$shipping_price->price = 0;
}else{
//first by price
$shipping_price = $this->shippingPriceByTotal($shipping->shipping_prices, $this->total(2, '.', ''));
//sec by weight
if(!$shipping_price){
$shipping_price = $this->shippingPriceByWeight($shipping->shipping_prices, $this->weight());
}
//default
if(!$shipping_price){
$shipping_price = $shipping->shipping_prices->first();
}
}
if($shipping_price){
$this->shipping_price = $shipping_price->price;
$this->shipping_tax = $shipping_price->tax_rate;
$this->putShippingExtra('shipping_price', $this->shipping_price);
$this->putShippingExtra('shipping_tax', $this->shipping_tax);
}
}
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);
}
//
private function shippingTax($decimals = null, $decimalPoint = null, $thousandSeperator = null){
$shippingTax = $this->shipping_price / (100 + $this->shipping_tax) * $this->shipping_tax;
return $this->numberFormat($shippingTax, $decimals, $decimalPoint, $thousandSeperator);
}
private function subShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null){
$subShipping = $this->shipping_price - $this->shippingTax($decimals, $decimalPoint, $thousandSeperator);
return $this->numberFormat($subShipping, $decimals, $decimalPoint, $thousandSeperator);
}
public function subtotalWithShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
$subtotal = $this->subtotal(2, '.', '') + $this->subShipping(2, '.', '');
return $this->numberFormat($subtotal, $decimals, $decimalPoint, $thousandSeperator);
}
public function taxWithShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
$totalTax = $this->tax(2, '.', '');
$shippingTax = $this->shippingTax(2, '.', '');
return $this->numberFormat(($totalTax+$shippingTax), $decimals, $decimalPoint, $thousandSeperator);
}
public function totalWithShipping($decimals = null, $decimalPoint = null, $thousandSeperator = null)
{
$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;
}
/**
* 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)
{
$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)
{
$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) {
$priceTax = $cartItem->price / (100 + $cartItem->taxRate) * $cartItem->taxRate;
return $subTotal + ($cartItem->qty * ($cartItem->price - $priceTax));
}, 0);
return $this->numberFormat($subTotal, $decimals, $decimalPoint, $thousandSeperator);
}
public function destroy()
{
$this->ysession->remove($this->yinstance);
parent::destroy();
}
/**
* Get the Formated number
*
* @param $value
* @param $decimals
* @param $decimalPoint
* @param $thousandSeperator
* @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);
}
}