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/topswtwmobile.komma.pro/app/KommaApp/Shop/Orders/OrderService.php
<?php


namespace KommaApp\Shop\Orders;

use Carbon\Carbon;
use Illuminate\Support\Facades\Config;
use KommaApp\Shop\Checkout\CheckoutSession\CheckoutSession;
use KommaApp\Shop\Customers\CustomerService;
use KommaApp\Shop\FormValidation\CheckoutForm;
use KommaApp\Shop\Mailers\CustomerMailer;

class OrderService
{
    /**
     * @var Order
     */
    protected $order;
    /**
     * @var CheckoutForm
     */
    protected $checkoutForm;
    /**
     * @var Cart
     */
    protected $checkoutSession;

    /**
     * @var CustomerService
     */
    protected $customerService;

    /**
     * @var OrderProduct
     */
    private $orderProduct;
    /**
     * @var CustomerMailer
     */
    private $customerMailer;
    /**
     * @var OrderToken
     */
    private $orderToken;
    /**
     * @var OrderRepository
     */
    private $orderRepository;

    /**
     * @param CheckoutSession $checkoutSession
     * @param CheckoutForm $checkoutForm
     * @param Order $order
     * @param OrderProduct $orderProduct
     * @param CustomerMailer $customerMailer
     * @param OrderToken $orderToken
     * @param OrderRepository $orderRepository
     */
    public function __construct(
        CheckoutSession $checkoutSession,
        CheckoutForm $checkoutForm,
        CustomerService $customerService,
        CustomerMailer $customerMailer,
        Order $order,
        OrderProduct $orderProduct,
        OrderToken $orderToken,
        OrderRepository $orderRepository
    )
    {
        $this->checkoutSession = $checkoutSession;
        $this->checkoutForm = $checkoutForm;
        $this->customerService = $customerService;
        $this->order = $order;
        $this->orderProduct = $orderProduct;
        $this->customerMailer = $customerMailer;
        $this->orderToken = $orderToken;
        $this->orderRepository = $orderRepository;
    }

    /**
     * Store order in database
     *
     * @param $input
     * @return string
     */
    public function store($input)
    {
        if (isset($input['invoice-company-vat'])) {
            $input['invoice-company-vat'] = strtoupper($input['invoice-company-vat']);
            $input['invoice-company-vat'] = preg_replace("/[^A-Z0-9]/", "", $input['invoice-company-vat']);
        }
        // Save customer in a session
        $this->checkoutSession->customer()->save();

        $this->checkoutSession->payment()->save();

        //Set the remark in the session
        $this->checkoutSession->setRemarks($input['remarks']);

        // Check shipping address
        $input = $this->updateShippingAddress($input);


        // Is the order valid
        if (!$this->checkoutForm->isValid($input)) {
            return \Redirect::back()
                ->withErrors($this->checkoutForm->errorMessages());
        }


        // Prepare data
        $data = $this->prepareData($input);
        // Fill data and save order
        if (!$this->order
            ->fill($data)
            ->save()
        ) {
            // Todo message
            return \Redirect::back();
        };
        $products = [];

        // Add products to database
        foreach ($this->checkoutSession->cart()->products() as $product) {
            // Create title

            $title_parts = [];
            if (strtolower($product['data']->brand_name) != 'toebehoren') $title_parts[] = $product['data']->brand_name;
            $title_parts[] = $product['data']->name;

            $title_parts[] = (\Lang::has('pages/products.' . $product['data']->product_group) ? \Lang::get('pages/products.' . $product['data']->product_group) : $product['data']->product_group);

            $title_parts[] = $product['data']->filter_class;
            $title_parts[] = implode(' ', [$product['data']->special_1, $product['data']->special_2]);

            $title = implode(' ', $title_parts);

            // Create description
            $description = $product['data']->composition_formatted;
            $product = $products[] = [
                'order_id' => $this->order->id,
                'internal_article_number' => $product['data']->internal_article_number,
                'pick_number' => $product['data']->pick_number,
                'title' => $title,
                'description' => $description,
                'composition' => json_encode($product['data']->composition),
                'quantity' => $product['quantity'],
                'original_price' => $product['data']->price * $product['quantity'],
                'original_price_ex' => $product['data']->getPriceExVat(),
                'price' => $product['data']->getDiscountPrice(
                    $product['quantity'],
                    $this->checkoutSession->cart()->getCouponCode(),
                    $this->checkoutSession->cart()->getBatchId()
                ),
                'price_ex' => $product['data']->getDiscountPriceExVat(
                    $product['quantity'],
                    $this->checkoutSession->cart()->getCouponCode(),
                    $this->checkoutSession->cart()->getBatchId()
                ),
                'discount_description' => $product['data']->getDiscountSummary(
                    $product['quantity'],
                    $this->checkoutSession->cart()->getCouponCode(),
                    $this->checkoutSession->cart()->getBatchId()
                ),
                'discount_number_of_items_for_free' => $product['data']->getNumberOfFreeProducts(
                    $product['quantity'],
                    $this->checkoutSession->cart()->getCouponCode(),
                    $this->checkoutSession->cart()->getBatchId()
                ),
                'tax_name' => $product['data']->tax_name,
                'tax_rate' => $product['data']->tax_rate
            ];
            // Fill & save product
            if (!$this->orderProduct->create($product)) {
                // Todo message
                return \Redirect::back();
            }

        }

        // Set orderId in the session
        $data['orderId'] = $this->order->id;
        $this->checkoutSession->payment()->set($data);

        // Generate token and update database
        $token = $this->orderToken->generate(array_merge($data, ['created_at' => $this->order->created_at]));
        $this->order->order_token = $token;

        $this->order->save();

        //Set the order_id in the checkoutSession
        $this->checkoutSession->setOrderId($this->order->id);

        // Send confirmation e-mail
        // Can't insert Order object to mail template :-S have to use arrays. (Laravel limitation)
        $data['invoice_full_name'] = $this->order->getFullInvoiceName();
        $data['invoice_full_last_name'] = $this->order->getFullInvoiceLastName();
        $data['invoice_full_address'] = $this->order->getFullInvoiceAddress();
        $data['shipping_full_address'] = $this->order->getFullShippingAddress();
        $data['dpd_full_information'] = $this->order->getFullDpdAddress();
        //todo: uit gezet om dat er geen use van vond (Tim)
        // $data['vat_reverse_charge'] = $this->vatIsNotDutch($this->order-invoice_company>_vat);
        $data['sub_total'] = $this->order->getSubTotal();
        $data['sub_total_ex_vat'] = $this->order->getSubTotalExVat();
        $data['discount_price'] = $this->order->discount_price;
        $data['discount_price_ex_vat'] = $this->order->getDiscountPriceExVat();
        $data['discount_percentage'] = $this->order->discount_percentage;
        $data['shipping_costs'] = $this->order->shipping_costs;
        $data['shipping_costs_ex_vat'] = $this->order->getShippingCostsExVat();
        $data['products'] = $products;
        $data['taxes'] = $this->order->getTaxTotals();
        $data['total_ex_vat'] = $this->order->getPriceTotalExVat();
        $data['order'] = $this->order;

        //$data['invoice'] = $this->generateInvoicePdf($this->order->id);

        // Hard to refactor because of: Serialization of 'Closure' is not allowed error...
        /*\Mail::queue('emails.order.received', $data, function($message) use ($data)
        {
            $pdf = \PDF::loadView('pdfs.invoice', ['order' => $data['order']]);
            $message->to($data['invoice_email'])->subject( \Lang::get('emails/order/received.subject'));
            if($pdf) $message->attachData($pdf->output(), \Lang::get('pdfs/invoice.fileName',[ 'orderNumber' => $data['order_number'] ]) . '.pdf');
        });*/

        $this->customerMailer->sendOrderReceived($data);

        //Send email to shop owner
        $this->customerMailer->sendOrderReceivedToShop($data);
    }

    /**
     * This function will redirect to the payment
     *
     * @return Redirect to chosen payment
     */
    public function redirectToPayment()
    {
        $paymentForm = \Shop::getPageService()->page('paymentForm')->route;
        return \Redirect::to($paymentForm);
    }

    /**
     * @param $orderId
     * @return mixed
     */
    public function generateInvoicePdf($orderId)
    {
        $order = $this->order->findOrFail($orderId);
        return \PDF::loadView('pdfs.invoice', ['order' => $order]);
    }

    /**
     * @param $orderId
     * @return mixed
     */
    public function streamInvoicePdf($orderId)
    {
        $order = $this->order->findOrFail($orderId);
        $pdf = \PDF::loadView('pdfs.invoice', ['order' => $order]);
        return $pdf->stream(\Lang::get('pdfs/invoice.fileName', ['orderNumber' => $order->order_number]) . '.pdf');
    }

    /**
     * @param $orderId
     * @return mixed
     */
    public function downloadInvoicePdf($orderId)
    {
        $order = $this->order->findOrFail($orderId);


        //Set the locale to the language of the order
        \App::setLocale($order->language->iso_2);

        $pdf = \PDF::loadView('pdfs.invoice', ['order' => $order]);

        return $pdf->download(\Lang::get('pdfs/invoice.fileName', ['orderNumber' => $order->order_number]) . '.pdf');
    }

    /*
     * Returns an order by token
     *
     * @return KommaApp/Shop/Orders/Order
     */
    public function getOrderByToken($token)
    {
        return $this->orderRepository->getOrderFromToken($token);
    }

    /**
     * Check what to do with the shipping address
     *
     * @param $input
     * @return array
     */
    protected function updateShippingAddress($input)
    {
        if (!isset($input['shipping-type'])) $input['shipping-type'] = 'invoice';
        switch ($input['shipping-type']) {
            case 'add-shipping-address':
                $this->checkoutSession->shipping()->save();
                return $input;
                break;
            case 'dpd-parcel-shop':
                \Session::put('checkout.shipping.dpd_carrier_shop_id', $input['dpd_carrier_shop_id']);
                \Session::put('checkout.shipping.dpd_carrier_shop_details', $input['dpd_carrier_shop_details']);

            default:
                $input = array_merge($input, $this->checkoutSession->shipping()->useInvoiceAddress());
                return $input;
                break;
        }

    }

    /**
     * @param $input
     * @return array
     */
    protected function prepareData($input)
    {
        // Prepare keys
        $data = [];
        foreach ($input as $key => $value) {
            $newKey = str_replace('-', '_', $key);
            $data[$newKey] = $value;
        }

        // Set the shipping country in the cart for the calculation of the shipping costs
        $this->checkoutSession->cart()->setShippingCountryIdByIso2($data['shipping_country']);


        // Check if there is an customer
        if (!$customer = \Auth::customer()->get()) {
            $customer = $this->createCustomer();
        }

        $customerId = $customer->id;

        // Get Shop id
        $shopId = \Shop::getId();

        $orderNumber = Order::getNewOrderNumber();

        $data['shop_id'] = $shopId;
        $data['customer_id'] = $customerId;
        $data['order_number'] = $orderNumber;
        $data['language_id'] = \Shop::getLanguageService()->getLanguageIdFromUri();
        $data['domain_country'] = \Shop::getDomainCountry();

        $data['coupon_code'] = $this->checkoutSession->cart()->getCouponCode();

        // Get genders from title
        $data['invoice_gender'] = $this->order->getInvoiceGender($input);
        $data['shipping_gender'] = $this->order->getShippingGender($input);

        //Get the shop Country from the tops comfig
        $shop_country = \Config::get('komma/tops.shop_country');
        if (!isset($data['dpd_carrier_shop_id']) || empty($data['dpd_carrier_shop_id'])) $data['dpd_carrier_shop_id'] = null;
        //Lets fill the price and VAT price based on the EU rules

        if (!empty($input['invoice-company'])) {
            //This will check the vat number and if correct will return the Vat Country (iso2)
            $vat_country = $this->checkVatNumber($input['invoice-company-vat']);
        } else {
            $data['invoice_company_vat'] = '';
        }

        //If there is an vat_country and the vat_country is not the same as the shop AND the shipping_country is not the same as the shop_country
        if (!empty($vat_country) && $vat_country != $shop_country && $shop_country != $data['shipping_country']) {
            //EU cross-border shopping. no VAT
            //This rule can only be aplied to an EU company When it is schipped to an other EU country that is NOT the country of the shop
            $data['shipping_costs'] = $this->checkoutSession->cart()->shippingWithoutVat();
            $data['original_price'] = $this->checkoutSession->cart()->subTotalOriginalProductPriceWithoutVat();
            $data['price_total'] = $this->checkoutSession->cart()->totalPriceExVat();
            $data['discount_price'] = $this->checkoutSession->cart()->getDiscountExVat();
            $data['discount_price'] = $this->checkoutSession->cart()->getDiscountExVat();
            $data['discount_percentage'] = $this->checkoutSession->cart()->getDiscountPercentage();
            $data['discount'] = $this->checkoutSession->cart()->getDiscountExVat();
            $data['discount_description'] = '(-' . $this->checkoutSession->cart()->getDiscountPercentage() . '%)&nbsp;-&euro;&nbsp;' . price($this->checkoutSession->cart()->getDiscountExVat());
        } //The vat_country doesn't exist (private buyer) Or the buying company is based in the same nation as the shop
        else {
            $data['shipping_costs'] = $this->checkoutSession->cart()->shipping();
            $data['original_price'] = $this->checkoutSession->cart()->subTotalOriginalProductPrice();
            $data['price_total'] = $this->checkoutSession->cart()->totalPrice();
            $data['discount_price'] = $this->checkoutSession->cart()->getDiscount();
            $data['discount_percentage'] = $this->checkoutSession->cart()->getDiscountPercentage();
            $data['discount'] = $this->checkoutSession->cart()->getDiscount();
            $data['discount_description'] = '(-' . $this->checkoutSession->cart()->getDiscountPercentage() . '%)&nbsp;-&euro;&nbsp;' . price($this->checkoutSession->cart()->getDiscount());
        }

        $data['product_total_ex'] = $this->checkoutSession->cart()->totalProductPriceExVat();

        //remarks, convert \n to <br/>
        $data['remarks'] = nl2br($data['remarks']);

        $data['status'] = Order::OPEN;
        $data['ordered_at'] = Carbon::now();
        return $data;
    }


    /**
     * This function will check the country of the vat number
     * And will check the VAT-regex for the given country.
     *
     * @param $vatNumber
     * @return mixed
     */
    public function checkVatNumber($vatNumber)
    {


        //Check if the vatNumber is not empty
        if (empty($vatNumber)) {
            //No VAT -> return false
            return false;
        }

        //The big EU vat checker
        if (!$matched_vat = preg_match("((AT)?U[0-9]{8}|(BE)?0[0-9]{9}|(BG)?[0-9]{9,10}|(CY)?[0-9]{8}L|(CZ)?[0-9]{8,10}|(DE)?[0-9]{9}|(DK)?[0-9]{8}|(EE)?[0-9]{9}|(EL|GR)?[0-9]{9}|(ES)?[0-9A-Z][0-9]{7}[0-9A-Z]|(FI)?[0-9]{8}|(FR)?[0-9A-Z]{2}[0-9]{9}|(GB)?([0-9]{9}([0-9]{3})?|[A-Z]{2}[0-9]{3})|(HU)?[0-9]{8}|(IE)?[0-9]S[0-9]{5}L|(IT)?[0-9]{11}|(LT)?([0-9]{9}|[0-9]{12})|(LU)?[0-9]{8}|(LV)?[0-9]{11}|(MT)?[0-9]{8}|(NL)?[0-9]{9}B[0-9]{2}|(PL)?[0-9]{10}|(PT)?[0-9]{9}|(RO)?[0-9]{2,10}|(SE)?[0-9]{12}|(SI)?[0-9]{8}|(SK)?[0-9]{10})", $vatNumber)) {
            //Regex is not correct so return false
            return false;
        }

        //The vat is correct and an VAT of the EU

        //extract the country code from the vatNumber
        $countryCode = substr($vatNumber, 0, 2);
        $vatNumber = substr($vatNumber, 2);

        //Check the VAT with the ec.europe load the soap client
        $client = new \SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl");

        if ($client) {
            $params = [
                'countryCode' => $countryCode,
                'vatNumber' => $vatNumber
            ];
            try {
                try {
                    $response = $client->checkVat($params);

                } catch (\SoapFault $e) {
                    //Respons can not be checked, but we will accept the VAT
                    return $countryCode;
                }
                if ($response->valid) {
                    //If all is well return countryCode
                    return $countryCode;
                } else {
                    return false;
                }
            } catch (SoapFault $e) {
                //Respons can not be checked, but we will accept the VAT
                return $countryCode;
            }
        }
        return false;


    }

    public function createCustomer()
    {
        //No customer, create a customer
        $input = [];
        foreach ($this->checkoutSession->customer()->get() as $key => $data) {
            $input[str_replace('invoice-', '', $key)] = $data;
        }

        $input['first_name'] = $input['first-name'];
        if (isset($input['name_insertion'])) {
            $input['name_insertion'] = $input['name-insertion'];
        }
        $input['last_name'] = $input['last-name'];
        $input['house_number'] = $input['house-number'];
        $input['house_number_suffix'] = $input['house-number-suffix'];
        //Only save the VAT when the comany is not empty
        $input['company_vat'] = (!empty(trim($input['company'])) ? $input['company-vat'] : "");
        $input['password'] = md5(time());
        $input['customer_email'] = $input['email'];
        return $this->customerService->streamLinedStoreNewCustomer($input);

    }


}