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'));
}
}