mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-08 20:22:42 +01:00
Working on the bot
This commit is contained in:
parent
325aaa3272
commit
f8fda5f241
File diff suppressed because one or more lines are too long
@ -627,9 +627,11 @@ if (!defined('CONTACT_EMAIL')) {
|
||||
define('EMAIL_MARKUP_URL', env('EMAIL_MARKUP_URL', 'https://developers.google.com/gmail/markup'));
|
||||
define('OFX_HOME_URL', env('OFX_HOME_URL', 'http://www.ofxhome.com/index.php/home/directory/all'));
|
||||
define('GOOGLE_ANALYITCS_URL', env('GOOGLE_ANALYITCS_URL', 'https://www.google-analytics.com/collect'));
|
||||
|
||||
define('MSBOT_LOGIN_URL', 'https://login.microsoftonline.com/common/oauth2/v2.0/token');
|
||||
define('MSBOT_LUIS_URL', 'https://api.projectoxford.ai/luis/v1/application');
|
||||
define('SKYPE_API_URL', 'https://apis.skype.com/v3');
|
||||
define('MSBOT_STATE_URL', 'https://state.botframework.com/v3');
|
||||
|
||||
define('BLANK_IMAGE', 'data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=');
|
||||
|
||||
|
36
app/Libraries/CurlUtils.php
Normal file
36
app/Libraries/CurlUtils.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php namespace App\Libraries;
|
||||
|
||||
class CurlUtils
|
||||
{
|
||||
public static function post($url, $data, $headers = false)
|
||||
{
|
||||
return self::exec('POST', $url, $data, $headers);
|
||||
}
|
||||
|
||||
public static function get($url, $headers = false)
|
||||
{
|
||||
return self::exec('GET', $url, null, $headers);
|
||||
}
|
||||
|
||||
public static function exec($method, $url, $data, $headers = false)
|
||||
{
|
||||
$curl = curl_init();
|
||||
|
||||
$opts = [
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_RETURNTRANSFER => true,
|
||||
CURLOPT_POST => $method,
|
||||
CURLOPT_HTTPHEADER => $headers ?: [],
|
||||
];
|
||||
|
||||
if ($data) {
|
||||
$opts[CURLOPT_POSTFIELDS] = $data;
|
||||
}
|
||||
|
||||
curl_setopt_array($curl, $opts);
|
||||
$response = curl_exec($curl);
|
||||
curl_close($curl);
|
||||
|
||||
return $response;
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
use Auth;
|
||||
use Eloquent;
|
||||
use Utils;
|
||||
use Validator;
|
||||
|
||||
/**
|
||||
* Class EntityModel
|
||||
@ -86,6 +87,11 @@ class EntityModel extends Eloquent
|
||||
return '[' . $this->getEntityType().':'.$this->public_id.':'.$this->getDisplayName() . ']';
|
||||
}
|
||||
|
||||
public function entityKey()
|
||||
{
|
||||
return $this->public_id . ':' . $this->getEntityType();
|
||||
}
|
||||
|
||||
/*
|
||||
public function getEntityType()
|
||||
{
|
||||
@ -190,4 +196,35 @@ class EntityModel extends Eloquent
|
||||
$name = $parts[count($parts)-1];
|
||||
return strtolower($name) . '_id';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param $entityType
|
||||
* @return bool|string
|
||||
*/
|
||||
public static function validate($data, $entityType, $action = 'create')
|
||||
{
|
||||
// Use the API request if it exists
|
||||
$requestClass = sprintf('App\\Http\\Requests\\%s%sAPIRequest', ucwords($action), ucwords($entityType));
|
||||
if ( ! class_exists($requestClass)) {
|
||||
$requestClass = sprintf('App\\Http\\Requests\\%s%sRequest', ucwords($action), ucwords($entityType));
|
||||
}
|
||||
|
||||
$request = new $requestClass();
|
||||
$request->setUserResolver(function() { return Auth::user(); });
|
||||
$request->replace($data);
|
||||
|
||||
if ( ! $request->authorize()) {
|
||||
return trans('texts.not_allowed');
|
||||
}
|
||||
|
||||
$validator = Validator::make($data, $request->rules());
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $validator->messages()->first();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,17 +1,21 @@
|
||||
<?php namespace App\Ninja\Intents;
|
||||
|
||||
use stdClass;
|
||||
use Exception;
|
||||
use App\Libraries\CurlUtils;
|
||||
|
||||
class BaseIntent
|
||||
{
|
||||
protected $state;
|
||||
protected $parameters;
|
||||
|
||||
public function __construct($data)
|
||||
public function __construct($state, $data)
|
||||
{
|
||||
$this->state = $state ?: new stdClass;
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
public static function createIntent($data)
|
||||
public static function createIntent($state, $data)
|
||||
{
|
||||
if ( ! count($data->intents)) {
|
||||
throw new Exception(trans('texts.intent_not_found'));
|
||||
@ -19,14 +23,14 @@ class BaseIntent
|
||||
|
||||
$intent = $data->intents[0];
|
||||
$intentType = $intent->intent;
|
||||
|
||||
|
||||
$className = "App\\Ninja\\Intents\\{$intentType}Intent";
|
||||
|
||||
if ( ! class_exists($className)) {
|
||||
throw new Exception(trans('texts.intent_not_supported'));
|
||||
}
|
||||
|
||||
return (new $className($data));
|
||||
return (new $className($state, $data));
|
||||
}
|
||||
|
||||
public function process()
|
||||
@ -34,4 +38,62 @@ class BaseIntent
|
||||
// do nothing by default
|
||||
}
|
||||
|
||||
public function addState($entities)
|
||||
{
|
||||
var_dump($this->state);
|
||||
if (isset($this->state->current)) {
|
||||
$this->state->previous = $this->state->current;
|
||||
}
|
||||
|
||||
|
||||
$this->state->current = $entities;
|
||||
}
|
||||
|
||||
public function getState()
|
||||
{
|
||||
return $this->state;
|
||||
}
|
||||
|
||||
protected function parseClient()
|
||||
{
|
||||
$clientRepo = app('App\Ninja\Repositories\ClientRepository');
|
||||
|
||||
$client = false;
|
||||
|
||||
foreach ($this->data->entities as $param) {
|
||||
if ($param->type == 'Client') {
|
||||
$client = $clientRepo->findPhonetically($param->entity);
|
||||
}
|
||||
}
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
protected function parseInvoiceItems()
|
||||
{
|
||||
$productRepo = app('App\Ninja\Repositories\ProductRepository');
|
||||
|
||||
$invoiceItems = [];
|
||||
|
||||
foreach ($this->data->compositeEntities as $entity) {
|
||||
if ($entity->parentType == 'InvoiceItem') {
|
||||
$product = false;
|
||||
$qty = 1;
|
||||
foreach ($entity->children as $child) {
|
||||
if ($child->type == 'Product') {
|
||||
$product = $productRepo->findPhonetically($child->value);
|
||||
} else {
|
||||
$qty = $child->value;
|
||||
}
|
||||
}
|
||||
|
||||
$item = $product->toArray();
|
||||
$item['qty'] = $qty;
|
||||
$invoiceItems[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $invoiceItems;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php namespace App\Ninja\Intents;
|
||||
|
||||
use App\Models\EntityModel;
|
||||
|
||||
class CreateInvoiceIntent extends BaseIntent
|
||||
{
|
||||
public function process()
|
||||
@ -9,64 +11,31 @@ class CreateInvoiceIntent extends BaseIntent
|
||||
$client = $this->parseClient();
|
||||
$invoiceItems = $this->parseInvoiceItems();
|
||||
|
||||
if ($client) {
|
||||
$data = [
|
||||
'client_id' => $client->id,
|
||||
'invoice_items' => $invoiceItems,
|
||||
];
|
||||
|
||||
$invoice = $invoiceRepo->save($data);
|
||||
|
||||
return view('bots.skype.invoice', [
|
||||
'invoice' => $invoice
|
||||
])->render();
|
||||
} else {
|
||||
if ( ! $client) {
|
||||
return view('bots.skype.message', [
|
||||
'message' => trans('texts.client_not_found')
|
||||
])->render();
|
||||
}
|
||||
}
|
||||
|
||||
private function parseClient()
|
||||
{
|
||||
$clientRepo = app('App\Ninja\Repositories\ClientRepository');
|
||||
$data = [
|
||||
'client_id' => $client->id,
|
||||
'invoice_items' => $invoiceItems,
|
||||
];
|
||||
|
||||
$client = false;
|
||||
$valid = EntityModel::validate($data, ENTITY_INVOICE);
|
||||
|
||||
foreach ($this->data->entities as $param) {
|
||||
if ($param->type == 'Client') {
|
||||
$client = $clientRepo->findPhonetically($param->entity);
|
||||
}
|
||||
if ($valid !== true) {
|
||||
return view('bots.skype.message', [
|
||||
'message' => $valid
|
||||
])->render();
|
||||
}
|
||||
|
||||
return $client;
|
||||
$invoice = $invoiceRepo->save($data);
|
||||
|
||||
$this->addState([$invoice->entityKey()]);
|
||||
|
||||
return view('bots.skype.invoice', [
|
||||
'invoice' => $invoice
|
||||
])->render();
|
||||
}
|
||||
|
||||
private function parseInvoiceItems()
|
||||
{
|
||||
$productRepo = app('App\Ninja\Repositories\ProductRepository');
|
||||
|
||||
$invoiceItems = [];
|
||||
|
||||
foreach ($this->data->compositeEntities as $entity) {
|
||||
if ($entity->parentType == 'InvoiceItem') {
|
||||
$product = false;
|
||||
$qty = 1;
|
||||
foreach ($entity->children as $child) {
|
||||
if ($child->type == 'Product') {
|
||||
$product = $productRepo->findPhonetically($child->value);
|
||||
} else {
|
||||
$qty = $child->value;
|
||||
}
|
||||
}
|
||||
|
||||
$item = $product->toArray();
|
||||
$item['qty'] = $qty;
|
||||
$invoiceItems[] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
return $invoiceItems;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,22 @@ class ClientPresenter extends EntityPresenter {
|
||||
return $this->entity->country ? $this->entity->country->name : '';
|
||||
}
|
||||
|
||||
public function balance()
|
||||
{
|
||||
$client = $this->entity;
|
||||
$account = $client->account;
|
||||
|
||||
return $account->formatMoney($client->balance, $client);
|
||||
}
|
||||
|
||||
public function paid_to_date()
|
||||
{
|
||||
$client = $this->entity;
|
||||
$account = $client->account;
|
||||
|
||||
return $account->formatMoney($client->paid_to_date, $client);
|
||||
}
|
||||
|
||||
public function status()
|
||||
{
|
||||
$class = $text = '';
|
||||
|
@ -9,7 +9,6 @@ use Auth;
|
||||
use Utils;
|
||||
use parsecsv;
|
||||
use Session;
|
||||
use Validator;
|
||||
use League\Fractal\Manager;
|
||||
use App\Ninja\Repositories\ContactRepository;
|
||||
use App\Ninja\Repositories\ClientRepository;
|
||||
@ -141,7 +140,7 @@ class ImportService
|
||||
|
||||
foreach ($json['clients'] as $jsonClient) {
|
||||
|
||||
if ($this->validate($jsonClient, ENTITY_CLIENT) === true) {
|
||||
if (EntityModel::validate($jsonClient, ENTITY_CLIENT) === true) {
|
||||
$client = $this->clientRepo->save($jsonClient);
|
||||
$this->addSuccess($client);
|
||||
} else {
|
||||
@ -151,7 +150,7 @@ class ImportService
|
||||
|
||||
foreach ($jsonClient['invoices'] as $jsonInvoice) {
|
||||
$jsonInvoice['client_id'] = $client->id;
|
||||
if ($this->validate($jsonInvoice, ENTITY_INVOICE) === true) {
|
||||
if (EntityModel::validate($jsonInvoice, ENTITY_INVOICE) === true) {
|
||||
$invoice = $this->invoiceRepo->save($jsonInvoice);
|
||||
$this->addSuccess($invoice);
|
||||
} else {
|
||||
@ -162,7 +161,7 @@ class ImportService
|
||||
foreach ($jsonInvoice['payments'] as $jsonPayment) {
|
||||
$jsonPayment['client_id'] = $jsonPayment['client'] = $client->id; // TODO: change to client_id once views are updated
|
||||
$jsonPayment['invoice_id'] = $jsonPayment['invoice'] = $invoice->id; // TODO: change to invoice_id once views are updated
|
||||
if ($this->validate($jsonPayment, ENTITY_PAYMENT) === true) {
|
||||
if (EntityModel::validate($jsonPayment, ENTITY_PAYMENT) === true) {
|
||||
$payment = $this->paymentRepo->save($jsonPayment);
|
||||
$this->addSuccess($payment);
|
||||
} else {
|
||||
@ -280,7 +279,7 @@ class ImportService
|
||||
$data['invoice_number'] = $account->getNextInvoiceNumber($invoice);
|
||||
}
|
||||
|
||||
if ($this->validate($data, $entityType) !== true) {
|
||||
if (EntityModel::validate($data, $entityType) !== true) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -396,26 +395,6 @@ class ImportService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $data
|
||||
* @param $entityType
|
||||
* @return bool|string
|
||||
*/
|
||||
private function validate($data, $entityType)
|
||||
{
|
||||
$requestClass = 'App\\Http\\Requests\\Create' . ucwords($entityType) . 'Request';
|
||||
$request = new $requestClass();
|
||||
$request->setUserResolver(function() { return Auth::user(); });
|
||||
$request->replace($data);
|
||||
|
||||
$validator = Validator::make($data, $request->rules());
|
||||
|
||||
if ($validator->fails()) {
|
||||
return $validator->messages()->first();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $files
|
||||
|
@ -2055,6 +2055,7 @@ $LANG = array(
|
||||
'intent_not_found' => 'Sorry, I\'m not sure what you\'re asking.',
|
||||
'intent_not_supported' => 'Sorry, I\'m not able to do that.',
|
||||
'client_not_found' => 'We weren\'t able to find the client',
|
||||
'not_allowed' => 'Sorry, you don\'t have the needed permissions',
|
||||
|
||||
);
|
||||
|
||||
|
@ -8,6 +8,20 @@
|
||||
'invoice' => link_to($invoice->getRoute(), $invoice->invoice_number),
|
||||
'client' => link_to($invoice->client->getRoute(), $invoice->client->getDisplayName())
|
||||
]) !!}',
|
||||
"facts": [
|
||||
{
|
||||
"key": "{{ trans('texts.email') }}:",
|
||||
"value": "{!! addslashes(HTML::mailto($invoice->client->contacts[0]->email)->toHtml()) !!}"
|
||||
},
|
||||
{
|
||||
"key": "{{ trans('texts.paid_to_date') }}:",
|
||||
"value": "{{ $invoice->client->present()->paid_to_date }}"
|
||||
},
|
||||
{
|
||||
"key": "{{ trans('texts.balance') }}:",
|
||||
"value": "{{ $invoice->client->present()->balance }}"
|
||||
}
|
||||
],
|
||||
"items":[
|
||||
@foreach ($invoice->invoice_items as $item)
|
||||
@if ($invoice->invoice_items[0] != $item)
|
||||
|
Loading…
Reference in New Issue
Block a user