Your IP : 216.73.216.86


Current Path : /var/www/homesaver/www/bitrix/modules/sberbank.ecom/payment/
Upload File :
Current File : /var/www/homesaver/www/bitrix/modules/sberbank.ecom/payment/rbs-discount.php

<?php

class rbsDiscount {

    private $cashBasket = [];
    private $equalPosition = -1;
    private $faultPrice;
    private $arrOrder = [
	    'order_id' =>  null,
	    'amount' =>  null,
	    'discount' =>  null,
	    'basket' => []
    ];
    private $arrRecountSumm = [
       'priceAmount' => 0,
       'priceDiscount' => 0,
       'discount' => 0
    ];

	function __construct($order) {
		$this->arrOrder = $order;
	}

	private function priceTransform() {
        $basket = $this->arrOrder['basket'];
        $this->arrOrder['discount'] = $this->arrOrder['discount'] * 100;
        foreach ($this->arrOrder['basket'] as $key => $item) {
            $item['discount'] = $item['discount'] * 100;
            $item['priceAmount'] = $item['priceAmount'] * 100;
            $item['priceBase'] = $item['priceBase'] * 100;
            $item['priceDiscount'] = $item['priceDiscount'] * 100;
            $this->arrOrder['basket'][$key] = $item;
        }
	}

	private function transformNumber($value, $count = 2) {
		$count = $count ? $count : 2; 
        return round($value,$count);
	}

	private function transformBasePrice($item) {
        $result = ($this->arrOrder['discount'] * $item['percentDiscount'] / 100) / $item['count'];
        $result = $this->transformNumber( $item['priceBase'] - $result);
        if($result < 0) {  $result = 0; }
        return $result;
	}


	private function onPositionDiscountPercent($item) {
        $price = $item['priceAmount'];
        return $this->transformNumber((100 / $this->arrOrder['amount'] * $price), 4);
	}

	private function onPositionDiscount($item) {
        $result = $this->transformNumber( ($item['priceBase'] - $item['priceBaseDiscount']) * $item['count']);
        return $result;
	}

	private function onPositionDiscountPrice($item) {
        $result = $this->transformNumber($item['priceBaseDiscount'] * $item['count']);
        if( $result < 0 ) { $result = 0; }
        return $result;
	}


	private function findMaxCount() {
        $maxValue = max(array_column( $this->arrOrder['basket'], 'count' ));
        $result = array_search( $maxValue, array_column( $this->arrOrder['basket'] ,'count') );
        return $result;
	}

	private function splitPosition($mode, $indexSeparate) {
        $newIndex = count($this->arrOrder['basket']);
        $separatePosition = $this->arrOrder['basket'][$indexSeparate];

        if( $mode === 'onePosition' ) {
            $this->arrOrder['basket'][$indexSeparate]['count'] = $this->transformNumber( $separatePosition['count'] - 1,3 );
            array_push( $this->arrOrder['basket'], $separatePosition );
            $this->equalPosition = $newIndex;
            $this->arrOrder['basket'][$newIndex] = $separatePosition;
            $this->arrOrder['basket'][$newIndex]['count'] = 1;
        } else if( $mode === 'fractionPosition' ) {
            $needPositionPrice = $this->transformNumber( $separatePosition['priceDiscount'] + $this->faultPrice );
            $originalCount = $separatePosition['count'];
            $success = false;
            $vishPrice = $this->transformNumber( $needPositionPrice / $originalCount );

            $separObject = [];
            $separObject['needSumm'] = $needPositionPrice;
            $separObject['oldPositionCount'] =  $this->transformNumber($originalCount / 2, 3 );
            $separObject['newPositionCount'] = $this->transformNumber($originalCount - $separObject['oldPositionCount'],3);

               
            for ($toIndex = 0; $toIndex < 5; $toIndex++) {
                $separObject['oldPositionCount'] = $this->transformNumber( $separObject['oldPositionCount'] - 0.001, 3) ;
                $separObject['newPositionCount'] = $this->transformNumber( $separObject['newPositionCount'] + 0.001, 3 );
                $separObject['oldPositionPrice'] = $this->transformNumber( $separObject['oldPositionCount'] * $vishPrice );
                $separObject['newPositionPrice'] = $this->transformNumber( $separObject['newPositionCount'] * $vishPrice );
                $separObject['oldPositionVishPrice'] = $this->transformNumber( $separObject['oldPositionPrice'] / $separObject['oldPositionCount'] );
                $separObject['newPositionVishPrice'] = $this->transformNumber( $separObject['newPositionPrice'] / $separObject['newPositionCount'] );
                $separObject['recountSumm'] = $this->transformNumber( $separObject['oldPositionPrice'] + $separObject['newPositionPrice']);
                if($separObject['recountSumm'] == $separObject['needSumm']) {
                    $success = true;
                    break;
                }
            }
            if( !$success ) {
                $res = $this->transformNumber(($separObject['newPositionPrice'] - ($separObject['recountSumm']-$separObject['needSumm'])) / $separObject['newPositionCount']);
                $separObject['newPositionPrice'] = $this->transformNumber( $res * $separObject['newPositionCount'] );
                $separObject['recountSumm'] = $this->transformNumber( $separObject['oldPositionPrice']+$separObject['newPositionPrice'] );
                if( $separObject['recountSumm'] === $separObject['needSumm'] ) { $success = true;}
            }
            if( $success ) {
                $separatePosition['count'] = $separObject['oldPositionCount'];        
                $separatePosition['priceBaseDiscount'] = $separObject['oldPositionVishPrice'];
                $separatePosition['priceAmount'] = $this->transformNumber( $separatePosition['count'] * $separatePosition['priceBase'] );  
                $separatePosition['priceDiscount'] = $separObject['oldPositionPrice'];
                $separatePosition['discount'] = $this->transformNumber( $separatePosition['priceAmount'] - $separatePosition['priceDiscount'] );
                $this->arrOrder['basket'][$indexSeparate] = $separatePosition;

                array_push($this->arrOrder['basket'], $separatePosition);
                $newPosition = $this->arrOrder['basket'][$newIndex];
                $newPosition['count'] = $separObject['newPositionCount'];
                $newPosition['priceAmount'] = $this->transformNumber( $newPosition['count'] * $newPosition['priceBase'] );
                $newPosition['priceBaseDiscount'] = $separObject['newPositionVishPrice'];
                $newPosition['priceDiscount'] = $separObject['newPositionPrice'];  
                $newPosition['discount'] = $this->transformNumber( $newPosition['priceAmount'] - $newPosition['priceDiscount'] );
                $this->arrOrder['basket'][$newIndex] = $newPosition;
            } else {

            }

        }
	}

	private function transformBasket() {
        $onePositionFind = false;
        $positionSeparateIndex = -1;
        $basket = $this->arrOrder['basket'];
        $transformMode = 'none';
        $this->equalPosition = -1;

        if( count($basket) === 0 ) { return false; }
        
        foreach ($basket as $key => $position) {
            if($position['count'] > 1) {
                $positionSeparateIndex = $key; 
            }
            if ($position['count'] == 1) {
                $this->equalPosition = $key;
                $onePositionFind = true;
            }
        }
        
        if(!$onePositionFind && $positionSeparateIndex >= 0) {
            $transformMode = 'onePosition';
        } else if(!$onePositionFind) {
            $positionSeparateIndex = $this->findMaxCount();
            $transformMode = 'fractionPosition';
        }
        $this->splitPosition( $transformMode,$positionSeparateIndex );
        return $transformMode;
	}



	private function generateRecieptAmount() {
        $summ = 0;
        foreach ($this->arrOrder['basket'] as $key => $item) {
        	$summ += $this->transformNumber($item['priceBase'] * $item['count']);
        }
        $this->arrOrder['amount'] = $this->transformNumber($summ);   
        if($this->arrOrder['amount'] < $this->arrOrder['discount']) {
            $this->arrOrder['discount'] = $this->arrOrder['amount'];
        }
        
	}

	private function generatePositionsDiscount() {
        $difference = $this->arrOrder['amount'] - $this->arrOrder['discount'];
        if( $difference > 1 ) {
        	foreach ($this->arrOrder['basket'] as $key => $item) {
                $item['priceAmount'] = $this->transformNumber( $item['priceBase'] * $item['count'] );
                $item['percentDiscount'] = $this->onPositionDiscountPercent( $item );
                $item['priceBaseDiscount'] = $this->transformBasePrice( $item );
                $item['discount'] = $this->onPositionDiscount( $item );
                $item['priceDiscount'] = $this->onPositionDiscountPrice( $item );

                $this->arrOrder['basket'][$key] = $item;
            }
        } else {
            foreach ($this->arrOrder['basket'] as $key => $item) {
                $item['priceAmount'] = $this->transformNumber( $item['priceBase'] * $item['count'] );
                $item['percentDiscount'] = 0;
                $item['priceBaseDiscount'] = 0;
                $item['discount'] = $item['priceAmount'];
                $item['priceDiscount'] = $item['priceAmount'] - $item['discount'];

                $this->arrOrder['basket'][$key] = $item;
            }
        }
	}

    private function equalizePositionDiscount() {
    	
        if( $this->equalPosition < 0 ) { return false; }
        $equalPosition = $this->arrOrder['basket'][$this->equalPosition];
        $baseSumm = $this->arrOrder['amount'] - $this->arrOrder['discount'];
        $recountSumm = $this->arrRecountSumm['priceDiscount'];
        $remain = 0;

        if( $baseSumm != $recountSumm ) {
            $remain = $this->transformNumber($baseSumm - $recountSumm);
            $this->arrOrder['basket'][$this->equalPosition]['priceBaseDiscount'] = $this->transformNumber($equalPosition['priceBaseDiscount'] + $remain);
            $this->arrOrder['basket'][$this->equalPosition]['priceDiscount'] = $equalPosition['priceBaseDiscount'];
            $this->arrOrder['basket'][$this->equalPosition]['discount'] = $this->transformNumber($equalPosition['discount'] - $remain);
            $this->arrOrder['basket'][$this->equalPosition]['priceDiscount'] = $this->arrOrder['basket'][$this->equalPosition]['priceBaseDiscount'];
        }
    }



	private function provideProductsToOrder() {
		$this->arrOrder['basket'] = $this->cashBasket;
	}

    private function finalCheck() {
        $baseAmount = $this->transformNumber( $this->arrOrder['amount'] - $this->arrOrder['discount'] );
        $finalAmount = $this->arrRecountSumm['priceDiscount'];
        
        $this->faultPrice =  $this->transformNumber($baseAmount - $finalAmount);
        if($this->faultPrice != 0) {
            $transformMode = $this->transformBasket();
            if( $transformMode !== 'fractionPosition' ) {
                $this->generatePositionsDiscount();
                $this->recountRecieptAmount();
                $this->equalizePositionDiscount();
            }
            $this->recountRecieptAmount();
        }       
    }

	public function addProduct($product) {
        $product['priceAmount'] = $product['count'] * $product['priceBase'];
        $this->cashBasket[] = $product; 
	}



	public function recountRecieptAmount() {
        $summ = [
           'priceAmount' =>  0,
           'priceDiscount' =>  0,
           'discount:' => 0  
        ];
        foreach ($this->arrOrder['basket'] as $key => $item) {
            $summ['priceAmount'] += $item['priceAmount'];
            $summ['priceDiscount'] += $item['priceBaseDiscount'] * $item['count'];
            $summ['discount'] += $item['discount'];
        }
        $this->arrRecountSumm['priceAmount'] = $this->transformNumber( $summ['priceAmount'] );
        $this->arrRecountSumm['priceDiscount'] = $this->transformNumber( $summ['priceDiscount'] );
        $this->arrRecountSumm['discount'] = $this->transformNumber( $summ['discount'] );

	}

	public function getOrder() {
		return $this->arrOrder;
	}


	public function getProducts() {
		return $this->cashBasket;
	}
	public function getBasketResult() {
		$order;
		foreach ($this->arrOrder['basket'] as $key => $item) {
			$order[$key] = [
	            'positionId' => $key+1,
                'name' => $item['name'],
                'quantity' => array(
                    'value' => $item['count'],
                    'measure' => $item['arrGate']['quantity']['measure'],
                ),
                'itemAmount' => $this->transformNumber($item['priceDiscount'] * 100,0),
                'itemCode' => $item['id'],
                'itemPrice' => $this->transformNumber($item['priceBaseDiscount'] * 100,0),
	            'tax' => array(
	                'taxType' => $item['arrGate']['tax']['taxType'],
	            ),
	        ];

            if(isset($item['itemAttributes'])) {
                $order[$key]['itemAttributes'] = $item['itemAttributes'];
            }
		}
		return $order;

	}
	public function getRecountSumm() {
		return $this->arrRecountSumm;
	}

	public function setOrderDiscount($value) {
		$this->arrOrder['discount'] = $value;
	}



	public function updateOrder() {
		$this->provideProductsToOrder();
		$this->generateRecieptAmount();
		$this->generatePositionsDiscount();
        $this->recountRecieptAmount();
        $this->finalCheck();
	}

	public function test($message = '') {
		echo "<pre>";
		print_r($this->arrOrder);
		print_r($this->arrRecountSumm);
		echo "</pre>";
	}

}

?>