kg-bot / rackbeat-integration-dashboard
Dashboard for all Rackbeat integrations
Requires
- php: >=7.1
- ext-json: *
- guzzlehttp/guzzle: *
- laravel/framework: ^6|^7
- maxbanton/cwh: ^2.0
- dev-master
- v1.0.37
- v1.0.36
- v1.0.35
- v1.0.34
- v1.0.33
- v1.0.32
- v1.0.31
- v1.0.30
- v1.0.29
- v1.0.28
- v1.0.27
- v1.0.26
- v1.0.25
- v1.0.24
- v1.0.23
- v1.0.22
- v1.0.21
- v1.0.20
- v1.0.19
- v1.0.18
- v1.0.17
- v1.0.16
- v1.0.15
- v1.0.14
- v1.0.13
- v1.0.12
- v1.0.11
- v1.0.10
- v1.0.9
- v1.0.8
- v1.0.7
- v1.0.6
- v1.0.5
- v1.0.4
- v1.0.3
- v1.0.2
- v1.0.1
- v1.0
This package is auto-updated.
Last update: 2024-10-24 21:10:13 UTC
README
1. composer require kg-bot/rackbeat-integration-dashboard
inside your integration project
2. Export configurations php artisan vendor:publish
for this package and change your Connection class inside
3. Run migrations
$ php artisan migrate
4. Run php artisan make:dashboard-token
5. Add rackbeat-integration-dashboard/*
to your VerifyCsrfToken
middleware $except
property
This package requires you to use Laravel Jobs for all of your transfers and tasks between Rackbeat and 3rd party integrations.
Each of your Job classes must extend KgBot\RackbeatDashboard\Classes\DashboardJob
and it must have special __construct
code.
Jobs are not dispatched directly, instead you need to create a new KgBot\RackbeatDashboard\Models\Job
model and it will automatically dispatch job using observer.
If you need any special constructor data you must send them in Job
model's create()
method, they will be serialized and saved in database so you will have to use them as so from you Job's constructor.
Example of this would look like this:
// App\Jobs\Webhooks\TransferInvoice.php
<?php
namespace App\Jobs\Webhooks;
use App\Connection;
use App\Transformers\CustomerTransformer;
use App\Transformers\InvoiceTransformer;
use App\Transformers\SupplierTransformer;
use App\Transformers\TransformerInterface;
use Illuminate\Support\Facades\Log;
use KgBot\Billy\Billy;
use KgBot\Billy\Models\Customer;
use KgBot\Billy\Models\Supplier;
use KgBot\RackbeatDashboard\Classes\DashboardJob;
use KgBot\RackbeatDashboard\Models\Job;
use Rackbeat\Utils\Model;
class TransferInvoice extends DashboardJob
{
/**
* @var $conn Connection
*/
protected $conn;
/**
* @var $type string
*/
protected $type;
/**
* @var $request array
*/
protected $request;
protected $tries = 1;
protected $timeout = 0;
/**
* Create a new job instance.
*
* @return void
*/
public function __construct( Job $job, $connection, $request, string $type = 'customer' ) {
parent::__construct( $job );
$connection = Connection::find( $connection->id );
$this->conn = $connection;
$this->type = $type;
$this->request = (array) $request;
}
/**
* Execute the job.
*
* @return void
*/
public function execute() {
$this->conn->focus();
// todo Determine is this supplier or customer invoice so we know what integration to check if enabled
try {
if ( $this->type === 'customer' ) {
$invoice = $this->conn->createRackbeatClient()->rb->customer_invoices()->find( $this->request['key'] );
if ( ! $this->conn->hasDebtorIntegration() ) {
return;
}
} else {
$invoice = $this->conn->createRackbeatClient()->rb->supplier_invoices()->find( $this->request['key'] );
if ( ! $this->conn->hasCreditorIntegration() ) {
return;
}
}
$this->jobModel->updateProgress( 10 );
} catch ( \Exception $exception ) {
$this->jobModel->updateProgress( 5 );
Log::error( 'Can\'t get invoice from webhook: ' . $exception->getMessage() );
throw $exception;
}
$this->createInvoice( $this->conn, $invoice );
$this->jobModel->updateProgress( 100 );
}
/**
* @param Connection $connection
* @param Model $invoice
*
* @return bool
*/
protected function createInvoice( Connection $connection, Model $invoice ) {
$billy = $connection->createBillyClient();
$rackbeat = $connection->createRackbeatClient();
$type = ( $invoice->getEntity() === 'supplier-invoices' ) ? 'supplier' : 'customer';
$rb_entity = $type . 's';
$contact = $this->findOrCreateContact( $rackbeat->rb->{$rb_entity}()->find( $invoice->{$type . '_id'} ), $billy, $type );
$this->jobModel->updateProgress( 50 );
$invoice = InvoiceTransformer::rackbeat( $connection, $invoice );
$invoice['contactId'] = $contact->id;
if ( $type === 'customer' ) {
$this->jobModel->updateProgress( 80 );
$this->createBillyInvoice( $invoice, $billy );
} else {
$this->jobModel->updateProgress( 80 );
$this->createBillyBill( $invoice, $billy );
}
return true;
}
/**
* @param $contact Model
* @param $billy Billy
* @param string $type string
*
* @return Supplier|Customer
*/
protected function findOrCreateContact( $contact, $billy, $type = 'supplier' ) {
switch ( $type ) {
case 'customer':
$billy = $billy->customers();
/**
* @var $transformer TransformerInterface
*/
$transformer = new CustomerTransformer( $this->conn );
break;
default:
$billy = $billy->suppliers();
$transformer = new SupplierTransformer( $this->conn );
}
$billy_contact = $billy->get( [
[ 'contactNo', '=', $contact->number ]
] )->first();
if ( ! $billy_contact ) {
$billy_contact = $billy->create( $transformer->fromRackbeat( $contact ) );
}
return $billy_contact;
}
/**
* @param $invoice
* @param $billy Billy
*/
protected function createBillyInvoice( $invoice, $billy ) {
$billy->invoices()->create( $invoice );
}
/**
* @param $invoice
* @param $billy Billy
*/
protected function createBillyBill( $invoice, $billy ) {
$billy->bills()->create( $invoice );
}
}
And this is how you would start this job from your controller
// App\Http\Controllers\Webhooks\InvoiceController.php
<?php
namespace App\Http\Controllers\Webhooks;
use App\Connection;
use App\Jobs\Webhooks\TransferInvoice;
use KgBot\RackbeatDashboard\Models\Job;
class InvoiceController extends Controller
{
public function test() {
Job::create( [
'command' => TransferInvoice::class,
'queue' => 'rackbeat-dashboard',
'args' => [ Connection::find( 1 ), [ 'key' => 3001 ], 'customer' ],
'title' => 'Transfer Invoice',
'created_by' => 1,
] );
return redirect()->to( '/' );
}
}
created_by
parameter is Connection ID for which you create this model/job.
If you need any more info feel free to contact maintainers, read this code or read Billy integration code because this is all used inside that integration.