469 lines
18 KiB
PHP
469 lines
18 KiB
PHP
<?php
|
|
|
|
namespace common\components;
|
|
|
|
use common\jobs\EmailJob;
|
|
use common\models\Account;
|
|
use common\models\InvoiceItem;
|
|
use common\models\SalesAgent;
|
|
use common\models\Service;
|
|
use Yii;
|
|
use yii\helpers\Url;
|
|
use yii\httpclient\Client;
|
|
use yii\httpclient\Request;
|
|
use yii\httpclient\RequestEvent;
|
|
|
|
class SonarApiComponent extends \yii\base\Component
|
|
{
|
|
public Client $client;
|
|
public string $baseUrl;
|
|
public string $bearerToken;
|
|
|
|
public function init()
|
|
{
|
|
parent::init();
|
|
$this->client = new Client([
|
|
'baseUrl' => $this->baseUrl,
|
|
'requestConfig' => [
|
|
'format' => Client::FORMAT_JSON
|
|
],
|
|
'responseConfig' => [
|
|
'format' => Client::FORMAT_JSON
|
|
],
|
|
]);
|
|
|
|
// Setup event for auth before each send
|
|
$this->client->on(Request::EVENT_BEFORE_SEND, function (RequestEvent $event) {
|
|
$event->request->addHeaders(['Authorization' => 'Bearer ' . $this->bearerToken]);
|
|
});
|
|
}
|
|
|
|
public function getAccounts(int $page = 1, int $limit = 100)
|
|
{
|
|
$data = [
|
|
'form_params' => [
|
|
'query' => 'query accountsWithSalesAgents(
|
|
$paginator: Paginator,
|
|
$search: [Search],
|
|
$sorter: [Sorter]
|
|
) {
|
|
accounts(
|
|
paginator: $paginator
|
|
search: $search
|
|
sorter: $sorter
|
|
reverse_relation_filters: {
|
|
relation: "custom_field_data",
|
|
search: {
|
|
integer_fields: {
|
|
attribute: "custom_field_id",
|
|
search_value: 12,
|
|
operator: EQ
|
|
}
|
|
}
|
|
}
|
|
general_search_mode: ROOT_PLUS_RELATIONS
|
|
account_status_id: 1
|
|
) {
|
|
entities {
|
|
id
|
|
name
|
|
account_status {
|
|
id
|
|
name
|
|
}
|
|
account_services {
|
|
entities {
|
|
id
|
|
quantity
|
|
name_override
|
|
price_override
|
|
price_override_reason
|
|
service {
|
|
id
|
|
name
|
|
amount
|
|
enabled
|
|
application
|
|
type
|
|
}
|
|
}
|
|
page_info {
|
|
page
|
|
records_per_page
|
|
total_count
|
|
total_pages
|
|
}
|
|
}
|
|
custom_field_data(custom_field_id:12) {
|
|
entities {
|
|
id
|
|
custom_field_id
|
|
value
|
|
}
|
|
}
|
|
}
|
|
page_info {
|
|
page
|
|
records_per_page
|
|
total_count
|
|
total_pages
|
|
}
|
|
}
|
|
}',
|
|
'variables' => [
|
|
'paginator' => [
|
|
'page' => $page,
|
|
'records_per_page' => $limit
|
|
],
|
|
'search' => [],
|
|
'sorter' => [
|
|
[
|
|
'attribute' => 'updated_at',
|
|
'direction' => 'ASC',
|
|
]
|
|
],
|
|
]
|
|
]
|
|
];
|
|
|
|
$response = $this->client->createRequest()
|
|
->setMethod('POST')
|
|
->setData($data)
|
|
->send();
|
|
|
|
$account = json_decode($response->getContent(), true);
|
|
|
|
return $account['form_params']['data'];
|
|
}
|
|
|
|
public function getInvoices(string $startDate, string $endDate)
|
|
{
|
|
$page = 1;
|
|
$limit = 100;
|
|
$invoices = [];
|
|
do {
|
|
$data = [
|
|
'form_params' => [
|
|
'query' => 'query accountInvoice($paginator: Paginator, $search: [Search], $sorter: [Sorter]) {
|
|
invoices(
|
|
paginator: $paginator
|
|
search: $search
|
|
sorter: $sorter
|
|
general_search_mode: ROOT_PLUS_RELATIONS
|
|
) {
|
|
entities {
|
|
id
|
|
account_id
|
|
total_debits
|
|
void
|
|
remaining_due
|
|
date
|
|
due_date
|
|
end_date
|
|
delinquent
|
|
debits {
|
|
entities {
|
|
id
|
|
quantity
|
|
service_id
|
|
service_name
|
|
amount
|
|
}
|
|
}
|
|
credits {
|
|
entities {
|
|
amount
|
|
}
|
|
}
|
|
}
|
|
page_info {
|
|
page
|
|
records_per_page
|
|
total_count
|
|
total_pages
|
|
}
|
|
}
|
|
}',
|
|
'variables' => [
|
|
'paginator' => [
|
|
'page' => $page,
|
|
'records_per_page' => $limit
|
|
],
|
|
'search' => [
|
|
[
|
|
'date_fields' => [
|
|
['attribute' => 'date', 'search_value' => $startDate, 'operator' => 'GTE'],
|
|
['attribute' => 'date', 'search_value' => $endDate, 'operator' => 'LTE'],
|
|
]
|
|
]
|
|
]
|
|
|
|
],
|
|
'sorter' => [
|
|
[
|
|
'attribute' => 'updated_at',
|
|
'direction' => 'ASC',
|
|
]
|
|
],
|
|
]
|
|
];
|
|
|
|
$response = $this->client->createRequest()
|
|
->setMethod('POST')
|
|
->setData($data)
|
|
->send();
|
|
|
|
|
|
$responseData = json_decode($response->getContent(), true);
|
|
$invoices = array_merge($invoices, $responseData['form_params']['data']['invoices']['entities']);
|
|
$page++;
|
|
} while ($page < ($responseData['form_params']['data']['invoices']['page_info']['total_pages'] + 1));
|
|
|
|
return $invoices;
|
|
}
|
|
|
|
public function getInvoice(int $invoiceId = 1)
|
|
{
|
|
$page = 1;
|
|
$limit = 100;
|
|
$data = [
|
|
'form_params' => [
|
|
'query' => 'query accountInvoice($paginator: Paginator, $search: [Search], $sorter: [Sorter]) {
|
|
invoices(
|
|
id: ' . $invoiceId . '
|
|
paginator: $paginator
|
|
search: $search
|
|
sorter: $sorter
|
|
general_search_mode: ROOT_PLUS_RELATIONS
|
|
) {
|
|
entities {
|
|
id
|
|
account_id
|
|
total_debits
|
|
void
|
|
remaining_due
|
|
date
|
|
due_date
|
|
end_date
|
|
delinquent
|
|
debits {
|
|
entities {
|
|
id
|
|
quantity
|
|
service_id
|
|
service_name
|
|
amount
|
|
}
|
|
}
|
|
credits {
|
|
entities {
|
|
amount
|
|
}
|
|
}
|
|
}
|
|
page_info {
|
|
page
|
|
records_per_page
|
|
total_count
|
|
total_pages
|
|
}
|
|
}
|
|
}',
|
|
'variables' => [
|
|
'paginator' => [
|
|
'page' => $page,
|
|
'records_per_page' => $limit
|
|
],
|
|
'search' => [],
|
|
'sorter' => [
|
|
[
|
|
'attribute' => 'updated_at',
|
|
'direction' => 'ASC',
|
|
]
|
|
],
|
|
]
|
|
]
|
|
];
|
|
|
|
$response = $this->client->createRequest()
|
|
->setMethod('POST')
|
|
->setData($data)
|
|
->send();
|
|
|
|
$invoice = json_decode($response->getContent(), true);
|
|
|
|
return $invoice['form_params']['data']['invoices']['entities'][0];
|
|
}
|
|
|
|
public function storeInvoices($invoices)
|
|
{
|
|
foreach ($invoices as $invoice) {
|
|
$this->storeInvoice($invoice);
|
|
}
|
|
}
|
|
|
|
public function storeInvoice($invoice)
|
|
{
|
|
\Yii::debug($invoice);
|
|
// $remainingDue is the Entire Invoice remaining to be paid amount, 0 = everything paid
|
|
$remainingDue = $invoice['remaining_due'];
|
|
// debits = charges on the account
|
|
// credits = payments on the account
|
|
|
|
foreach ($invoice['debits']['entities'] as $i => $rawItem) {
|
|
$invoiceItem = InvoiceItem::find()->where(['sonar_id' => (int)$rawItem['id']])->one();
|
|
if (null === $invoiceItem) { // create new invoice item
|
|
|
|
$account = Account::findOne(['sonar_id' => (int)$invoice['account_id']]);
|
|
$service = Service::findOne(['sonar_id' => (int)$rawItem['service_id']]);
|
|
\Yii::debug($rawItem);
|
|
if ($service && $account) {
|
|
\Yii::debug($invoice);
|
|
$payment = (isset($invoice['credits']['entities'][$i]['amount'])) ? $invoice['credits']['entities'][$i]['amount'] : 0;
|
|
// @todo check payment - i think it is wrong to assume we have the same credits and debits ^ CGS
|
|
$invoiceItem = new InvoiceItem([
|
|
'sonar_id' => (int)$rawItem['id'],
|
|
'account_id' => $account->id,
|
|
'service_id' => $service->id,
|
|
'name' => $rawItem['service_name'],
|
|
'status' => InvoiceItem::STATUS_OPEN,
|
|
'charge' => $rawItem['amount'],
|
|
'payment' => $payment,
|
|
'is_commissionable' => $service->hasCommission(),
|
|
]);
|
|
$invoiceItem->save();
|
|
}
|
|
}
|
|
|
|
// is the invoice item paid?
|
|
if ($invoiceItem && $remainingDue == 0) {
|
|
$invoiceItem->status = InvoiceItem::STATUS_PAYMENT_RECEIVED;
|
|
$invoiceItem->save();
|
|
}
|
|
}
|
|
}
|
|
|
|
private function mapAccounts($accounts)
|
|
{
|
|
$mapped = [];
|
|
$i = 0;
|
|
$db = \Yii::$app->db;
|
|
foreach ($accounts as $account) {
|
|
$mapped[$i]['sonar_id'] = (int)$account['id'];
|
|
$mapped[$i]['name'] = $account['name'];
|
|
|
|
/**
|
|
* [
|
|
* 'id' => '132'
|
|
* 'quantity' => 1
|
|
* 'name_override' => 'Bradley'
|
|
* 'price_override' => 0
|
|
* 'price_override_reason' => 'testing'
|
|
* 'service' => [
|
|
* 'id' => '10'
|
|
* 'name' => 'Business Giga Speed Internet'
|
|
* 'amount' => 18000
|
|
* 'enabled' => true
|
|
* 'application' => 'DEBIT'
|
|
* 'type' => 'DATA'
|
|
* ]
|
|
* ]
|
|
*/
|
|
$mapped[$i]['services'] = []; // init empty array
|
|
|
|
foreach ($account['account_services']['entities'] as $key => $account_service) {
|
|
$mapped[$i]['services'][$key]['sonar_id'] = (int)$account_service['service']['id'];
|
|
$mapped[$i]['services'][$key]['name'] = (!empty($account_service['name_override'])) ? $account_service['name_override'] : $account_service['service']['name'];
|
|
$mapped[$i]['services'][$key]['price'] = (!empty($account_service['price_override'])) ? $account_service['price_override'] : $account_service['service']['amount'];
|
|
if ($account_service['service']['application'] === 'CREDIT') {
|
|
$mapped[$i]['services'][$key]['price'] = -1 * $mapped[$i]['services'][$key]['price'];// store as a negative
|
|
}
|
|
|
|
// set to 0 if null after credit
|
|
if (null === $mapped[$i]['services'][$key]['price']) {
|
|
$mapped[$i]['services'][$key]['price'] = 0;
|
|
}
|
|
}
|
|
|
|
$name = $account['custom_field_data']['entities'][0]['value'];
|
|
$salesAgent = SalesAgent::findOne(['name' => $name]);
|
|
if (null === $salesAgent) {
|
|
$salesAgent = new SalesAgent(['name' => $name]);
|
|
$salesAgent->save();
|
|
}
|
|
|
|
$mapped[$i]['sales_agent_id'] = $salesAgent->id;
|
|
|
|
$i++;
|
|
}
|
|
return $mapped;
|
|
}
|
|
|
|
public function storeAccounts()
|
|
{
|
|
$page = 1;
|
|
do {
|
|
$batch = $this->getAccounts($page, 100);
|
|
$accounts = $this->mapAccounts($batch['accounts']['entities']);
|
|
|
|
foreach ($accounts as $account) {
|
|
$accountModel = Account::findOne(['sonar_id' => $account['sonar_id']]);
|
|
if (null === $accountModel) {
|
|
$accountModel = new Account([
|
|
'sonar_id' => $account['sonar_id'],
|
|
'name' => $account['name'],
|
|
'sales_agent_id' => $account['sales_agent_id'],
|
|
]);
|
|
$accountModel->save();
|
|
} else {
|
|
//$accountModel->sonar_id = $account['sonar_id'];
|
|
$accountModel->name = $account['name'];
|
|
$accountModel->sales_agent_id = $account['sales_agent_id'];
|
|
$accountModel->save();
|
|
}
|
|
|
|
foreach ($account['services'] as $rawServiceData) {
|
|
$serviceModel = Service::findOne(['sonar_id' => (int)$rawServiceData['sonar_id']]);
|
|
if (null === $serviceModel) {
|
|
$serviceModel = new Service([
|
|
'sonar_id' => $rawServiceData['sonar_id'],
|
|
'name' => $rawServiceData['name'],
|
|
'price' => $rawServiceData['price'],
|
|
'account_id' => $accountModel->id,
|
|
'active' => 1, // @todo pull active state in from sonar api
|
|
]);
|
|
$serviceModel->save();
|
|
} else {
|
|
$serviceModel->commission = $serviceModel->getFormattedDollar($serviceModel->commission, false);
|
|
$serviceModel->sonar_id = $rawServiceData['sonar_id'];
|
|
$serviceModel->name = $rawServiceData['name'];
|
|
$serviceModel->price = $rawServiceData['price'];
|
|
$serviceModel->account_id = $accountModel->id;
|
|
if (!empty($serviceModel->dirtyAttributes)) {
|
|
if (isset($serviceModel->dirtyAttributes['price'])) {
|
|
//Yii::$app->queue->push(new EmailJob([
|
|
// 'templateAlias' => EmailJob::PRICE_CHANGE,
|
|
// "email" => Yii::$app->params['adminEmail'],
|
|
// 'templateModel' => [
|
|
// "action_edit_url" => Yii::$app->urlManager->createAbsoluteUrl(
|
|
// ['service/update', 'id' => $serviceModel->id]
|
|
// ),
|
|
// ]
|
|
//]));
|
|
}
|
|
}
|
|
$serviceModel->save();
|
|
}
|
|
}
|
|
}
|
|
|
|
$page++;
|
|
} while ($page < ($batch['accounts']['page_info']['total_pages'] + 1));
|
|
}
|
|
|
|
public function processInvoices(int $invoiceId)
|
|
{
|
|
dump($this->getInvoice($invoiceId));
|
|
}
|
|
|
|
} |