HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/deensekroon.komma-mediadesign.nl/wwwroot/php/sweebr/SweebrService.php
<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/admin/php/connect.php';
include_once $_SERVER['DOCUMENT_ROOT'] . '/admin/php/functions2.php';

include_once $_SERVER['DOCUMENT_ROOT'] . '/php/sweebr/SweebrRepository.php';
include_once $_SERVER['DOCUMENT_ROOT'] . '/lib/Carbon/Carbon.php';
include_once $_SERVER['DOCUMENT_ROOT'] . '/admin/lib/mail/php_mailer.class.php';

use Carbon\Carbon;

class SweebrService
{
    protected $repository;

    protected $mysqli;

    protected $mailer;

    protected $errors = [];
    protected $success = [];

    protected $stockInDatabase;

    public function __construct()
    {
        $this->repository = new SweebrRepository();

        global $mysqli;
        $this->mysqli = $mysqli;

        $this->mailer = new PHPMailer();
    }

    public function index()
    {
        // In debug mode
        //echo 'Sweebr Koppeling niet geactiveerd.';
        //exit;

        // Set scope
        $scope = (object) [
            'start' => Carbon::yesterday('Europe/Amsterdam')->addHours(2),
            'end' => Carbon::today('Europe/Amsterdam')->addHours(2)
        ];

        // Get report
        list($httpCode, $response, $error) = $this->repository->getReportFromScope($scope);

        // Handle error
        if ( $httpCode != 200 )
        {
            echo 'Return code is ' . $httpCode . ' \n' . $error;
            exit;
        }

        // Check if we already processed this scope
        if($this->alreadyProcessedScope($scope))
        {
            $this->errors[] = 'Double attempt to scope update.';
            $this->saveScopeInDatabase($scope);
            var_dump('Scope already processed');
            return false;
        }

        // Set $this->productsInDatabase
        $this->stockInDatabase = $this->getAllStockFromDatabase();

        // Handle response
        $products = json_decode($response)->products;
        $this->handleProducts($products);

        // Save processed scope in database
        $this->saveScopeInDatabase($scope);

        // Mail errors to Deense Kroon
        $this->mailErrorsToShop();
        return true;
    }

    /**
     * @param $scope
     * @return int
     */
    protected function alreadyProcessedScope($scope)
    {
        // Hash the scope
        $hash = $this->hashScope($scope);

        // Build Query
        $query = 'SELECT hash
                  FROM sweebr_scopes
                  WHERE hash = "' . $hash . '"
                  LIMIT 1';
        $result = $this->mysqli->query($query);

        return $result->num_rows;
    }

    /**
     * @param $scope
     * @return string
     */
    protected function hashScope($scope)
    {
        return hash('sha1', $scope->start . $scope->end);
    }

    protected function getAllStockFromDatabase()
    {
        $data = [];

        $query = 'SELECT id, ean, inStock
                  FROM shop_stock
                  WHERE ean IS NOT NULL';
        $result = $this->mysqli->query($query);
        while($record = $result->fetch_assoc())
        {
            $id = $record['id'];
            $ean = fromDatabase($record['ean']);
            $inStock = fromDatabase($record['inStock']);

            if( ! empty($ean))
            {
                $data[$ean] = (object) [ 'id' => $id, 'ean' => $ean, 'inStock' => $inStock ];
            }
        }

        return $data;
    }

    /**
     * @param $products
     * @return bool
     */
    protected function handleProducts($products)
    {
        $products = (array) $products;
        if( ! count($products)) return false;

        // Save quantity and amount
        //$numProducts = $products['quantity'];

        // Remove quantity and amount from array
        unset($products['quantity']);
        unset($products['amount']); 

        // Check foreach product if we can update from stock
        foreach($products as $product)
        {
            $this->updateStock($product);
        }
        return true;
    }

    /**
     * @param $product
     * @return bool
     */
    protected function updateStock($product)
    {
        $title = $product->product;

        // Check if title contains EAN
        if( ! $ean = $this->getEanFromTitle($title))
        {
            $this->errors[] = (object) ['product' => $product,'error' => 'De titel bevat geen juiste EAN-code'];
            return false;
        }

        // Check if EAN is found in database
        if( ! isset( $this->stockInDatabase[$ean]))
        {
            $this->errors[] = (object) ['product' => $product,'error' => 'EAN-code niet gevonden in webshop'];
            return false;
        }

        // Calculate new stock
        $stockQuantity = $product->quantity;
        $oldStock = $this->stockInDatabase[$ean]->inStock;
        $newStock = $oldStock - $stockQuantity;

        // Check if any stock left in shop
        if($newStock < 0)
        {
            $unit = 'stuks';
            if($this->stockInDatabase[$ean]->inStock == 1) $unit = 'stuk';
            $this->errors[] = (object) ['product' => $product,'error' => 'Niet voldoende voorraad aanwezig in webshop (slechts ' . $this->stockInDatabase[$ean]->inStock. ' ' . $unit . ')'];
            return false;
        }

        // Update in table
        $this->stockInDatabase[$ean]->inStock = $newStock;

        // Update in database
        $query = 'UPDATE shop_stock
                  SET inStock = ' . $newStock . '
                  WHERE id = ' . $this->stockInDatabase[$ean]->id;
        if( ! $this->mysqli->query($query))
        {
            $this->errors[] = (object) ['product' => $product,'error' => 'Om technische database redenen niet gelukt'];
            return false;
        } 

        $this->success[] = (object) ['product' => $product,'oldStock' => $oldStock, 'newStock' => $newStock];
        return true;
    }

    /**
     * @param $title
     * @return bool|string
     */
    protected function getEanFromTitle($title)
    {
        $title = trim($title);
        $ean = substr($title,0,13);
        if( preg_match('/^[0-9]{13}$/',$ean))
            return $ean;
        return false;
    }

    protected function saveScopeInDatabase($scope)
    {
        $query = 'INSERT INTO sweebr_scopes(hash,start,end,errors,success,created_at)
                  VALUES(?,?,?,?,?,?)';
        if( ! $stmt = $this->mysqli->prepare($query))
        {
            var_dump($this->mysqli->error);
            return false;
        }

        $hash = $this->hashScope($scope);
        $jsonErrors = json_encode($this->errors);
        $jsonSuccess = json_encode($this->success);
        $createdAt = Carbon::now();

        $stmt->bind_param('ssssss', $hash, $scope->start, $scope->end, $jsonErrors, $jsonSuccess, $createdAt);
        $stmt->execute();
        return true; 
    }

    /**
     * @return bool
     */
    protected function mailErrorsToShop()
    {
        if(count($this->errors) > 0)
        {
            $msg = 'Bericht van deensekroon.nl:<br /><br />
                    Een aantal producten betaald via <strong>Sweebr</strong> zijn niet afgeboekt van de webshop.
                    De voorraad van deze producten dient handmatige gecontroleerd / afgeboekt te worden.<br /><br />
                    <strong>Errors:</strong><br /><br />';

            foreach($this->errors as $error)
            {
                $msg .= '<strong>' . $error->product->product . '</strong><br />';
                $msg .= 'Aantal verkocht: ' . $error->product->quantity . '<br />';
                $msg .= 'Foutmelding: ' . $error->error . '<br /><br />';
            }

            try
            {
                $this->mailer->AddAddress('info@deensekroon.nl', 'Deense Kroon');
                $this->mailer->AddCC('mike@komma.pro', 'Mike');
                $this->mailer->SetFrom('mike@komma.pro', 'Deense Kroon Webshop');
                $this->mailer->Subject = 'Sweebr producten niet afgeboekt';
                $this->mailer->MsgHTML($msg);
                $this->mailer->Send();
            }
            catch (phpmailerException $e)
            {
                return FALSE;
            }
        } 

        return true;

    }


}