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/netwerkbrabant/netwerkbrabant.nl/app/KommaApp/WeFact/WeFactService.php
<?php


namespace App\KommaApp\WeFact;

use App\Mail\WeFactErrorMail;

/**
 * Service for calling the right api hooks.
 * For a full documentation about we you can expect;
 * https://www.wefact.nl/api/
 *
 * Class WeFactService
 * @package App\KommaApp\WeFact
 */
class WeFactService
{

    /** @var WeFactAPI $api */
    private $api;

    const PRODUCT_GROUP_EVENTS = 1;
    const PRODUCT_GROUP_INTERNET = 4;
    const PRODUCT_GROUP_MEMBERSHIP = 2;
    const PRODUCT_GROUP_MAGAZINE = 3;
    const PRODUCT_GROUP_WEB_PRODUCT = 5;


    public function __construct()
    {
        $this->api = app()->make(WeFactAPI::class);
    }

    /**
     * Validate the response
     * So make sure that the status is successful.
     * If not then mail admin and show user friendly error message
     *
     * @param $response
     */
    private function validateResponse($response)
    {
        if(isset($response['status']) && $response['status'] == 'success') return;

        //Send payment error email
        $mail = (new WeFactErrorMail($response))->useMailConfigFrom('exception_mail');
        \Mail::send($mail);

        if(app()->environment() != 'production') dd($response);
        throw new \InvalidArgumentException('WeFact response was not successful.');
    }

    public function getDebtors()
    {
        $response = $this->api->sendRequest(WeFactAPI::DEBTOR_CONTROLLER, 'list', []);
        $this->validateResponse($response);
        return $response;
    }

    /**
     * Search for debtors by the given email.
     * Limit the results to 5, because we actually only need to find one.
     * If we find more then our search is invalid.
     *
     *
     * @param  string  $email
     * @return object
     */
    public function searchDebtorsByEmail(string $email)
    {
        $parameters = [
            'searchat'  => 'EmailAddress',
            'searchfor' => $email,
            'limit' => 5
        ];

        $response = $this->api->sendRequest(WeFactAPI::DEBTOR_CONTROLLER, 'list', $parameters);
        $this->validateResponse($response);

        $responseObject = (object)[
          'results' => $response['totalresults'],
        ];

        if(isset($response['debtors'])) $responseObject->debtors = $response['debtors'];
        else $responseObject->debtors = [];

        return $responseObject;
    }

    public function searchDebtorsByName(string $name)
    {
        $parameters = [
            'searchat'  => 'CompanyName',
            'searchfor' => $name,
        ];

        $response = $this->api->sendRequest(WeFactAPI::DEBTOR_CONTROLLER, 'list', $parameters);
        $this->validateResponse($response);
        return $response;
    }

    public function getDebtor(string $debtorCode)
    {
        $parameters = [
            'DebtorCode' => $debtorCode,
        ];

        $response = $this->api->sendRequest(WeFactAPI::DEBTOR_CONTROLLER, 'show', $parameters);
        $this->validateResponse($response);
        return $response;
    }

    /**
     * Add a debtor.
     *
     * @param $debtorInput
     * @return mixed
     */
    public function addDebtor($debtorInput)
    {
        $parameters = [];
        $parameters = array_merge($parameters, $debtorInput);

        $response = $this->api->sendRequest(WeFactAPI::DEBTOR_CONTROLLER, 'add', $parameters);
        $this->validateResponse($response);
        return (object)$response['debtor'];
    }

    public function getProductGroups()
    {
        $parameters = [
            'type' => 'product',
        ];

        $response = $this->api->sendRequest(WeFactAPI::GROUP_CONTROLLER, 'list', $parameters);
        $this->validateResponse($response);
        return $response;
    }

    public function getDebtorGroups()
    {
        $parameters = [
            'type' => 'debtor',
        ];

        $response = $this->api->sendRequest(WeFactAPI::GROUP_CONTROLLER, 'list', $parameters);
        $this->validateResponse($response);
        return $response;
    }

    public function getProducts()
    {
        $response = $this->api->sendRequest(WeFactAPI::PRODUCT_CONTROLLER, 'list', []);
        $this->validateResponse($response);
        return $response;
    }

    /**
     * Get products that are marked as events (product group: 1).
     *
     * @return array
     */
    public function getEventProducts()
    {
        $parameters = [
            'group' => self::PRODUCT_GROUP_EVENTS,
        ];

        $response = $this->api->sendRequest(WeFactAPI::PRODUCT_CONTROLLER, 'list', $parameters);
        $this->validateResponse($response);
        return $response['products'];
    }

    /**
     * Get a product out of we fact by the given product code.
     *
     * @param  string  $productCode
     * @return object
     */
    public function getProduct(string $productCode)
    {
        $parameters = [
            'ProductCode' => $productCode,
        ];

        $response = $this->api->sendRequest(WeFactAPI::PRODUCT_CONTROLLER, 'show', $parameters);
        $this->validateResponse($response);
        return (object)$response['product'];
    }

    /**
     * Create a product by the given product input values.
     * And define the event product group.
     *
     * @param $productInput
     * @param int $groupId
     * @return object
     */
    public function addProduct($productInput, int $groupId = self::PRODUCT_GROUP_EVENTS)
    {
        $parameters = [
            'Groups' => [
                $groupId
            ]
        ];
        $parameters = array_merge($parameters, $productInput);

        $response = $this->api->sendRequest(WeFactAPI::PRODUCT_CONTROLLER, 'add', $parameters);
        $this->validateResponse($response);
        return (object)$response['product'];
    }

    /**
     * Edit the given product with the injected input values.
     *
     * @param  string  $productCode
     * @param $productInput
     * @return object
     */
    public function editProduct(string $productCode, $productInput)
    {
        $parameters = [
            'ProductCode' => $productCode,
        ];
        $parameters = array_merge($parameters, $productInput);
        $response = $this->api->sendRequest(WeFactAPI::PRODUCT_CONTROLLER, 'edit', $parameters);
        $this->validateResponse($response);
        return (object)$response['product'];
    }

    public function searchProductByName(string $name)
    {
        $parameters = [
            'searchat'  => 'ProductName',
            'searchfor' => $name,
        ];

        $response = $this->api->sendRequest(WeFactAPI::PRODUCT_CONTROLLER, 'list', $parameters);

        $responseObject = (object)[
            'results' => $response['totalresults'],
        ];

        if(isset($response['products'])) $responseObject->debtors = $response['products'];
        else $responseObject->debtors = [];

        return $responseObject;
    }

    /**
     * Add membership subscription to debtor.
     * This will be done by creating a invoice with a product that has a periodicType.
     *
     * @param  string  $debtorCode
     * @return object
     */
    public function addSubscription(string $debtorCode)
    {
        $parameters = [
            'DebtorCode'   => $debtorCode,
            'InvoiceLines' => [
                [
                    'Number'      => 1,
                    'ProductCode' => config('site.membershipProductCode'),
                ],
            ],
        ];

        $response = $this->api->sendRequest(WeFactAPI::INVOICE_CONTROLLER, 'add', $parameters);
        $this->validateResponse($response);
        return (object)$response['invoice'];

//        return (object)$response['invoice'];

//        $parameters = [
//            'DebtorCode'   => $debtorCode,
//            'Subscription' => [
//                'ProductCode' => config('site.membershipProductCode'),
//            ],
//        ];
//
//        $response = $this->api->sendRequest(WeFactAPI::SUBSCRIPTION_CONTROLLER, 'add', $parameters);
//        $this->validateResponse($response);
//        return (object)$response['subscription'];
    }

    /**
     * Add a invoice to WeFact, generated by the provided parameters.
     *
     * @param  string  $debtorCode
     * @param  string  $productCode
     * @param  string|null  $reference
     * @param  bool  $hasPaid
     * @return object
     */
    public function addInvoice(string $debtorCode, string $productCode, string $reference = null, bool $hasPaid = false)
    {
        $parameters = [
            'DebtorCode'   => $debtorCode,
            'InvoiceLines' => [
                [
                    'Number'      => 1,
                    'ProductCode' => $productCode,
                ],
            ],
        ];

        // Add reference if has been provided
        if(!empty($reference)) {
            $parameters['ReferenceNumber'] = $reference;
        }


        // Set invoice to paid
        if($hasPaid){
            $parameters['Status'] = 4;
        }

        $response = $this->api->sendRequest(WeFactAPI::INVOICE_CONTROLLER, 'add', $parameters);
        $this->validateResponse($response);
        return (object)$response['invoice'];
    }

    public function getInvoice(int $identifier)
    {
        $parameters = [
            'Identifier'   => $identifier,
        ];

        $response = $this->api->sendRequest(WeFactAPI::INVOICE_CONTROLLER, 'show', $parameters);
        $this->validateResponse($response);
        return $response;
    }

    public function sendInvoiceByMail(string $identifier)
    {
        $parameters = [
            'Identifier' => $identifier
        ];

        $response = $this->api->sendRequest(WeFactAPI::INVOICE_CONTROLLER, 'sendbyemail', $parameters);
        $this->validateResponse($response);
        return $response;
    }

    // ======================================= Test functions ======================================== //

    public function testSearchDebtorsByEmail()
    {
        return $this->searchDebtorsByEmail('komma.pro');
    }

    public function testSearchDebtorsByName()
    {
        return $this->searchDebtorsByName('Komma');
    }

    public function testGetDebtor()
    {
        return $this->getDebtor(921);
    }

    public function testAddDebtor()
    {
        $debtorInput = [
            'CompanyName'       => 'Komma TEST',
            'Initials'    => 'Pascal',
            'SurName'     => 'Lemmen',
            'Address'       => 'Randweg-Zuid 1',
            'ZipCode'        => '6021PW',
            'City'          => 'Budel',
            'EmailAddress' => 'pascal@komma.pro',
        ];

        return $this->addDebtor($debtorInput);
    }

    public function testGetProduct()
    {
        return $this->getProduct(config('site.membershipProductCode'));
    }

    public function testAddSubscription()
    {
        dd( $this->addSubscription(1361) );
    }

    public function testAddInvoice()
    {
        return $this->addInvoice(1361, 'P0011');
    }

    public function testAddAndSendInvoice()
    {
        $invoice = $this->addInvoice(1361, 'P0011', true);
        return $this->sendInvoiceByMail($invoice->Identifier);
    }

    public function testAddProduct()
    {
        $productInput = [
            'ProductName' => 'Test product',
            'ProductKeyPhrase' => 'Omschrijving van product',
            'PriceExcl' => 39.50,
            'TaxCode' => 'V9',
        ];

        return $this->addProduct($productInput);
    }

    public function testSearchProductByName()
    {
        dd($this->searchProductByName('Brabants Netwerkdiner - 21 september 2020'));
    }
}