552 lines
No EOL
18 KiB
PHP
552 lines
No EOL
18 KiB
PHP
<?php
|
|
namespace App\Services;
|
|
|
|
|
|
|
|
|
|
use App\Models\Homeparty;
|
|
|
|
class HomepartyCart
|
|
{
|
|
/*private $shipping_price = 0;
|
|
private $shipping_price_net = 0;
|
|
private $shipping_tax_rate = 0;
|
|
private $shipping_tax = 0;
|
|
private $shipping_country_id = 0; //default de
|
|
private $shipping_is_for;
|
|
private $num_comp;
|
|
private $ysession;
|
|
private $yinstance;
|
|
private $shopping_data = [];*/
|
|
|
|
|
|
public static $points = 0;
|
|
public static $price = 0;
|
|
public static $price_net = 0;
|
|
public static $ek_price = 0;
|
|
public static $income_price = 0;
|
|
|
|
private static $homeparty;
|
|
private static $userCarts = [];
|
|
|
|
public static $user_host_id;
|
|
|
|
public static $is_bonus = false;
|
|
public static $is_bonus_coupon = false;
|
|
|
|
private static $bonus_coupon = 0;
|
|
private static $bonus_value = 30;
|
|
|
|
private static $bonus_price = 0;
|
|
private static $bonus_diff = 0;
|
|
private static $bonus_points_diff = 0;
|
|
private static $bonus_coupon_fault = 0;
|
|
private static $bonus_coupon_next_step = 0;
|
|
private static $bonus_coupon_next_value = 0;
|
|
private static $bonus_start = 200;
|
|
private static $bonusTable = [
|
|
250 => 15,
|
|
300 => 20,
|
|
400 => 30,
|
|
500 => 35,
|
|
600 => 40,
|
|
700 => 50,
|
|
|
|
];
|
|
public static function calculateHomeparty(Homeparty $homeparty){
|
|
|
|
self::$homeparty = $homeparty;
|
|
foreach ($homeparty->homeparty_users as $homeparty_user){
|
|
if($homeparty_user->is_host){
|
|
self::$user_host_id = $homeparty_user->id;
|
|
}
|
|
self::$userCarts[$homeparty_user->id] = new HomepartyUserCart($homeparty_user);
|
|
self::addCart(self::$userCarts[$homeparty_user->id]);
|
|
}
|
|
self::caluclateBonus();
|
|
self::calculateBonusHost();
|
|
}
|
|
|
|
public static function addCart(HomepartyUserCart $homepartyUserCart){
|
|
self::$points += $homepartyUserCart->points;
|
|
self::$price += $homepartyUserCart->price;
|
|
self::$price_net += $homepartyUserCart->price_net;
|
|
self::$ek_price += $homepartyUserCart->ek_price;
|
|
self::$income_price += $homepartyUserCart->income_price;
|
|
}
|
|
|
|
public static function getUserCart($id){
|
|
return isset(self::$userCarts[$id]) ? self::$userCarts[$id] : null;
|
|
}
|
|
|
|
|
|
public static function caluclateBonus(){
|
|
|
|
if(self::$price >= 200){
|
|
self::$is_bonus = true;
|
|
|
|
//TODO get from PRODUCT
|
|
self::$bonus_price = 11.90;
|
|
self::$price += self::$bonus_price;
|
|
self::$price_net += 10;
|
|
|
|
$bonus_tmp = self::$price - self::$bonus_value;
|
|
|
|
//look up for coupon in table
|
|
foreach (self::$bonusTable as $val=>$coupon){
|
|
if($bonus_tmp >= $val){
|
|
self::$is_bonus_coupon = true;
|
|
self::$bonus_coupon = $coupon;
|
|
}else{
|
|
if(self::$bonus_coupon_fault === 0){
|
|
self::$bonus_coupon_fault = $val - $bonus_tmp;
|
|
self::$bonus_coupon_next_step = $val;
|
|
self::$bonus_coupon_next_value = $coupon;
|
|
}
|
|
}
|
|
}
|
|
$keys = array_keys(self::$bonusTable);
|
|
$step = $keys[count($keys)-1];
|
|
if($bonus_tmp > $step){
|
|
self::$bonus_coupon_next_step = $step;
|
|
self::$bonus_coupon_next_value =self::$bonusTable[$step];
|
|
}
|
|
|
|
}else{
|
|
self::$bonus_diff = 200 - self::$price;
|
|
}
|
|
|
|
}
|
|
|
|
public static function calculateBonusHost(){
|
|
if(self::$is_bonus){
|
|
$bonus_total = self::$bonus_value + self::$bonus_coupon;
|
|
$user_cart = self::getUserCart(self::$user_host_id);
|
|
//cart lower the bonus
|
|
if($user_cart->price <= $bonus_total){
|
|
self::$bonus_points_diff = $user_cart->points;
|
|
$user_cart->points = 0;
|
|
$user_cart->price = 0;
|
|
return;
|
|
}
|
|
|
|
$bonus_percent = (100/$user_cart->price*$bonus_total);
|
|
self::$bonus_points_diff = round($user_cart->points/100*$bonus_percent);
|
|
$user_cart->points -= self::$bonus_points_diff;
|
|
$user_cart->price -= $bonus_total;
|
|
|
|
}
|
|
}
|
|
|
|
public static function getUserCartHost(){
|
|
return self::getUserCart(self::$user_host_id);
|
|
}
|
|
|
|
public static function getFormattedPoints()
|
|
{
|
|
return formatNumber(self::$points, 0);
|
|
}
|
|
|
|
public static function getFormattedPrice()
|
|
{
|
|
return formatNumber(self::$price);
|
|
}
|
|
|
|
public static function getFormattedPriceNet()
|
|
{
|
|
return formatNumber(self::$price_net);
|
|
}
|
|
|
|
public static function getFormattedEkPrice()
|
|
{
|
|
return formatNumber(self::$ek_price);
|
|
}
|
|
|
|
public static function getFormattedIncomePrice()
|
|
{
|
|
return formatNumber(self::$income_price);
|
|
}
|
|
|
|
public static function getFormattedPriceTax(){
|
|
return formatNumber(self::$price - self::$price_net);
|
|
}
|
|
public static function getFormattedBonusPrice()
|
|
{
|
|
return formatNumber(self::$bonus_price);
|
|
}
|
|
public static function getFormattedBonusStart(){
|
|
return formatNumber(self::$bonus_start);
|
|
}
|
|
public static function getFormattedBonusValue(){
|
|
return formatNumber(self::$bonus_value);
|
|
}
|
|
|
|
public static function getFormattedBonusDiff(){
|
|
return formatNumber(self::$bonus_diff);
|
|
}
|
|
|
|
public static function getFormattedBonusCoupon(){
|
|
return formatNumber(self::$bonus_coupon);
|
|
}
|
|
|
|
public static function getFormattedBonusCouponFault(){
|
|
return formatNumber(self::$bonus_coupon_fault);
|
|
}
|
|
|
|
public static function getFormattedBonusCouponNextStep(){
|
|
return formatNumber(self::$bonus_coupon_next_step);
|
|
}
|
|
public static function getFormattedBonusCouponNextValue(){
|
|
return formatNumber(self::$bonus_coupon_next_value);
|
|
}
|
|
|
|
public static function getFormattedBonusTotal(){
|
|
if(self::$is_bonus){
|
|
return formatNumber(self::$bonus_value + self::$bonus_coupon);
|
|
}
|
|
return formatNumber(0);
|
|
}
|
|
|
|
public static function getFormattedBonusPointsDiff(){
|
|
return formatNumber( self::$bonus_points_diff, 0 );
|
|
|
|
}
|
|
/* public static function getTaxRate()
|
|
{
|
|
return config('cart.tax');
|
|
}
|
|
|
|
public function putYardExtra($key, $value){
|
|
|
|
$content = $this->getYContent();
|
|
$content->put($key, $value);
|
|
$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 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, $shipping_is_for = 'ot')
|
|
{
|
|
$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();
|
|
|
|
}
|
|
|
|
private function calculateShippingPrice(){
|
|
|
|
$shippingCountry = ShippingCountry::find($this->shipping_country_id);
|
|
if(!$shippingCountry){
|
|
return;
|
|
}
|
|
$shipping = $shippingCountry->shipping;
|
|
|
|
if($this->weight() == 0){
|
|
$shipping_price = $shipping->shipping_prices->first();
|
|
$shipping_price->price = 0;
|
|
$shipping_price->price_comp = 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){
|
|
$price = $shipping_price->price;
|
|
$this->num_comp = 0;
|
|
if($this->shipping_is_for === 'me'){
|
|
$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;
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
//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)
|
|
{
|
|
$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)
|
|
{
|
|
$total = (float) ($this->total(2, '.', '')) + $this->shipping_price;
|
|
return $this->numberFormat($total, $decimals, $decimalPoint, $thousandSeperator);
|
|
}
|
|
|
|
|
|
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 points()
|
|
{
|
|
$content = $this->getContent();
|
|
$total = $content->reduce(function ($total, CartItem $cartItem) {
|
|
return $total + ($cartItem->options->points ? ($cartItem->options->points * $cartItem->qty) : 0);
|
|
}, 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;
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
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);
|
|
}
|
|
|
|
|
|
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'){
|
|
$price = $product->getPriceWith(false, true);
|
|
}
|
|
$cartItem = $this->getCartItem($product->id, $product->getLang('name'), 1, $price, ['image' => $image, 'slug' => $product->slug, 'weight' => $product->weight, 'points' => $product->points]);
|
|
$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 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;
|
|
}
|
|
|
|
*/
|
|
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);
|
|
}
|
|
} |