mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-11-10 05:02:36 +01:00
Working on the bot
This commit is contained in:
parent
d374843e50
commit
815c3991a6
@ -2,8 +2,9 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Libraries\CurlUtils;
|
||||
use Exception;
|
||||
use App\Libraries\Skype\SkypeResponse;
|
||||
use App\Libraries\CurlUtils;
|
||||
use App\Ninja\Intents\BaseIntent;
|
||||
|
||||
class BotController extends Controller
|
||||
@ -11,13 +12,15 @@ class BotController extends Controller
|
||||
public function handleMessage($platform)
|
||||
{
|
||||
$to = '29:1C-OsU7OWBEDOYJhQUsDkYHmycOwOq9QOg5FVTwRX9ts';
|
||||
//$message = 'create a new invoice for Mr. Gino ';
|
||||
$message = 'add 1 item';
|
||||
//$message = 'set the cost to 20';
|
||||
//$message = 'new invoice for john for 2 items due tomorrow';
|
||||
//$message = 'create a new invoice for john smith for 2 tickets, set the invoice date to today, the due date to tomorrow, the deposit to 5 and the discount set to 10 percent';
|
||||
//$message = 'create a new invoice for john smith with a due date of September 7th';
|
||||
//$message = 'create a new invoice for john';
|
||||
$message = 'add 2 tickets and set the due date to yesterday';
|
||||
//$message = 'set the po number to 0004';
|
||||
//$message = 'set the quantity to 20';
|
||||
//$message = 'send the invoice';
|
||||
|
||||
//$message = view('bots.skype.message', ['message' => $message])->render();
|
||||
//return $this->sendResponse($to, $message);
|
||||
//$message = 'show me my products';
|
||||
|
||||
echo "Message: $message <p>";
|
||||
$token = $this->authenticate();
|
||||
@ -33,9 +36,7 @@ class BotController extends Controller
|
||||
$this->saveState($token, $state);
|
||||
/*
|
||||
} catch (Exception $exception) {
|
||||
$message = view('bots.skype.message', [
|
||||
'message' => $exception->getMessage()
|
||||
])->render();
|
||||
SkypeResponse::message($exception->getMessage());
|
||||
}
|
||||
*/
|
||||
|
||||
@ -86,7 +87,6 @@ class BotController extends Controller
|
||||
private function saveState($token, $data)
|
||||
{
|
||||
$url = sprintf('%s/botstate/skype/conversations/%s', MSBOT_STATE_URL, '29:1C-OsU7OWBEDOYJhQUsDkYHmycOwOq9QOg5FVTwRX9ts');
|
||||
var_dump($url);
|
||||
|
||||
$headers = [
|
||||
'Authorization: Bearer ' . $token,
|
||||
@ -94,11 +94,8 @@ class BotController extends Controller
|
||||
];
|
||||
|
||||
$data = '{ eTag: "*", data: "' . addslashes(json_encode($data)) . '" }';
|
||||
//$data = '{ eTag: "*", data: "" }';
|
||||
var_dump($data);
|
||||
$response = CurlUtils::post($url, $data, $headers);
|
||||
|
||||
var_dump($response);
|
||||
CurlUtils::post($url, $data, $headers);
|
||||
}
|
||||
|
||||
private function sendResponse($token, $to, $message)
|
||||
@ -111,7 +108,7 @@ class BotController extends Controller
|
||||
|
||||
$response = CurlUtils::post($url, $message, $headers);
|
||||
|
||||
var_dump($message);
|
||||
echo "<pre>" . htmlentities(json_encode(json_decode($message), JSON_PRETTY_PRINT)) . "</pre>";
|
||||
var_dump($response);
|
||||
}
|
||||
|
||||
|
11
app/Libraries/Skype/ButtonCard.php
Normal file
11
app/Libraries/Skype/ButtonCard.php
Normal file
@ -0,0 +1,11 @@
|
||||
<?php namespace App\Libraries\Skype;
|
||||
|
||||
class ButtonCard
|
||||
{
|
||||
public function __construct($type, $title, $value)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->title = $title;
|
||||
$this->value = $value;
|
||||
}
|
||||
}
|
26
app/Libraries/Skype/HeroCard.php
Normal file
26
app/Libraries/Skype/HeroCard.php
Normal file
@ -0,0 +1,26 @@
|
||||
<?php namespace App\Libraries\Skype;
|
||||
|
||||
class HeroCard
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
$this->contentType = 'application/vnd.microsoft.card.hero';
|
||||
$this->content = new stdClass;
|
||||
$this->content->buttons = [];
|
||||
}
|
||||
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->content->title = $title;
|
||||
}
|
||||
|
||||
public function setSubitle($subtitle)
|
||||
{
|
||||
$this->content->subtitle = $subtitle;
|
||||
}
|
||||
|
||||
public function addButton($button)
|
||||
{
|
||||
$this->content->buttons[] = $button;
|
||||
}
|
||||
}
|
75
app/Libraries/Skype/InvoiceCard.php
Normal file
75
app/Libraries/Skype/InvoiceCard.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php namespace App\Libraries\Skype;
|
||||
|
||||
use HTML;
|
||||
use stdClass;
|
||||
|
||||
class InvoiceCard
|
||||
{
|
||||
public function __construct($invoice)
|
||||
{
|
||||
$this->contentType = 'application/vnd.microsoft.card.receipt';
|
||||
$this->content = new stdClass;
|
||||
$this->content->facts = [];
|
||||
$this->content->items = [];
|
||||
$this->content->buttons = [];
|
||||
|
||||
$this->setTitle('test');
|
||||
|
||||
$this->setTitle(trans('texts.invoice_for_client', [
|
||||
'invoice' => link_to($invoice->getRoute(), $invoice->invoice_number),
|
||||
'client' => link_to($invoice->client->getRoute(), $invoice->client->getDisplayName())
|
||||
]));
|
||||
|
||||
$this->addFact(trans('texts.email'), HTML::mailto($invoice->client->contacts[0]->email)->toHtml());
|
||||
|
||||
if ($invoice->due_date) {
|
||||
$this->addFact($invoice->present()->dueDateLabel, $invoice->present()->due_date);
|
||||
}
|
||||
|
||||
if ($invoice->po_number) {
|
||||
$this->addFact(trans('texts.po_number'), $invoice->po_number);
|
||||
}
|
||||
|
||||
if ($invoice->discount) {
|
||||
$this->addFact(trans('texts.discount'), $invoice->present()->discount);
|
||||
}
|
||||
|
||||
foreach ($invoice->invoice_items as $item) {
|
||||
$this->addItem($item, $invoice->account);
|
||||
}
|
||||
|
||||
$this->setTotal($invoice->present()->requestedAmount);
|
||||
|
||||
$this->addButton('imBack', trans('texts.send_email'), 'send_email');
|
||||
$this->addButton('imBack', trans('texts.download_pdf'), 'download_pdf');
|
||||
}
|
||||
|
||||
public function setTitle($title)
|
||||
{
|
||||
$this->content->title = $title;
|
||||
}
|
||||
|
||||
public function setTotal($value)
|
||||
{
|
||||
$this->content->total = $value;
|
||||
}
|
||||
|
||||
public function addFact($key, $value)
|
||||
{
|
||||
$fact = new stdClass;
|
||||
$fact->key = $key;
|
||||
$fact->value = $value;
|
||||
|
||||
$this->content->facts[] = $fact;
|
||||
}
|
||||
|
||||
public function addItem($item, $account)
|
||||
{
|
||||
$this->content->items[] = new InvoiceItemCard($item, $account);
|
||||
}
|
||||
|
||||
public function addButton($type, $title, $value)
|
||||
{
|
||||
$this->content->buttons[] = new ButtonCard($type, $title, $value);
|
||||
}
|
||||
}
|
12
app/Libraries/Skype/InvoiceItemCard.php
Normal file
12
app/Libraries/Skype/InvoiceItemCard.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php namespace App\Libraries\Skype;
|
||||
|
||||
class InvoiceItemCard
|
||||
{
|
||||
public function __construct($invoiceItem, $account)
|
||||
{
|
||||
$this->title = $invoiceItem->product_key;
|
||||
$this->subtitle = $invoiceItem->notes;
|
||||
$this->quantity = $invoiceItem->qty;
|
||||
$this->price = $account->formatMoney($invoiceItem->cost);
|
||||
}
|
||||
}
|
28
app/Libraries/Skype/SkypeResponse.php
Normal file
28
app/Libraries/Skype/SkypeResponse.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php namespace App\Libraries\Skype;
|
||||
|
||||
class SkypeResponse
|
||||
{
|
||||
public function __construct($type)
|
||||
{
|
||||
$this->type = $type;
|
||||
$this->attachments = [];
|
||||
}
|
||||
|
||||
public static function message($message)
|
||||
{
|
||||
$instance = new self('message/text');
|
||||
$instance->setText($message);
|
||||
|
||||
return json_encode($instance);
|
||||
}
|
||||
|
||||
public function setText($text)
|
||||
{
|
||||
$this->text = $text;
|
||||
}
|
||||
|
||||
public function addAttachment($attachment)
|
||||
{
|
||||
$this->attachments[] = $attachment;
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
use stdClass;
|
||||
use Exception;
|
||||
use App\Libraries\CurlUtils;
|
||||
use App\Libraries\Skype\SkypeResponse;
|
||||
|
||||
class BaseIntent
|
||||
{
|
||||
@ -26,7 +27,7 @@ class BaseIntent
|
||||
$this->state = $state;
|
||||
$this->data = $data;
|
||||
|
||||
var_dump($state);
|
||||
//var_dump($state);
|
||||
}
|
||||
|
||||
public static function createIntent($state, $data)
|
||||
@ -38,9 +39,23 @@ class BaseIntent
|
||||
$intent = $data->intents[0]->intent;
|
||||
$entityType = false;
|
||||
|
||||
echo "Intent: $intent<p>";
|
||||
foreach ($data->entities as $entity) {
|
||||
if ($entity->type === 'EntityType') {
|
||||
$entityType = $entity->entity;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $entityType) {
|
||||
$entityType = $state->current->entityType;
|
||||
}
|
||||
|
||||
$entityType = ucwords(strtolower($entityType));
|
||||
$intent = str_replace('Entity', $entityType, $intent);
|
||||
$className = "App\\Ninja\\Intents\\{$intent}Intent";
|
||||
|
||||
echo "Intent: $intent<p>";
|
||||
|
||||
if ( ! class_exists($className)) {
|
||||
throw new Exception(trans('texts.intent_not_supported'));
|
||||
}
|
||||
@ -109,11 +124,10 @@ class BaseIntent
|
||||
protected function parseClient()
|
||||
{
|
||||
$clientRepo = app('App\Ninja\Repositories\ClientRepository');
|
||||
|
||||
$client = false;
|
||||
|
||||
foreach ($this->data->entities as $param) {
|
||||
if ($param->type == 'Client') {
|
||||
if ($param->type == 'Name') {
|
||||
$client = $clientRepo->findPhonetically($param->entity);
|
||||
}
|
||||
}
|
||||
@ -125,6 +139,10 @@ class BaseIntent
|
||||
{
|
||||
$data = [];
|
||||
|
||||
if ( ! isset($this->data->compositeEntities)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($this->data->compositeEntities as $compositeEntity) {
|
||||
if ($compositeEntity->parentType != 'FieldValuePair') {
|
||||
continue;
|
||||
@ -178,4 +196,22 @@ class BaseIntent
|
||||
return $value;
|
||||
}
|
||||
|
||||
protected function createResponse($type, $content)
|
||||
{
|
||||
$response = new SkypeResponse($type);
|
||||
|
||||
if (is_string($content)) {
|
||||
$response->setText($content);
|
||||
} else {
|
||||
if ( ! is_array($content)) {
|
||||
$content = [$content];
|
||||
}
|
||||
|
||||
foreach ($content as $item) {
|
||||
$response->addAttachment($item);
|
||||
}
|
||||
}
|
||||
|
||||
return json_encode($response);
|
||||
}
|
||||
}
|
||||
|
@ -11,17 +11,16 @@ class CreateInvoiceIntent extends InvoiceIntent
|
||||
$invoiceItems = $this->parseInvoiceItems();
|
||||
|
||||
if ( ! $client) {
|
||||
return view('bots.skype.message', [
|
||||
'message' => trans('texts.client_not_found')
|
||||
])->render();
|
||||
throw new Exception(trans('texts.client_not_found'));
|
||||
}
|
||||
|
||||
$data = [
|
||||
$data = array_merge($this->parseFields(), [
|
||||
'client_id' => $client->id,
|
||||
'invoice_items' => $invoiceItems,
|
||||
];
|
||||
]);
|
||||
|
||||
var_dump($data);
|
||||
|
||||
$valid = EntityModel::validate($data, ENTITY_INVOICE);
|
||||
|
||||
if ($valid !== true) {
|
||||
@ -29,6 +28,7 @@ class CreateInvoiceIntent extends InvoiceIntent
|
||||
}
|
||||
|
||||
$invoice = $this->invoiceRepo->save($data);
|
||||
|
||||
$invoiceItemIds = array_map(function($item) {
|
||||
return $item['public_id'];
|
||||
}, $invoice->invoice_items->toArray());
|
||||
@ -38,8 +38,6 @@ class CreateInvoiceIntent extends InvoiceIntent
|
||||
$this->setEntities(ENTITY_INVOICE, $invoice->public_id);
|
||||
$this->setEntities(ENTITY_INVOICE_ITEM, $invoiceItemIds);
|
||||
|
||||
return view('bots.skype.invoice', [
|
||||
'invoice' => $invoice
|
||||
])->render();
|
||||
return $this->createResponse('message/card.receipt', $invoice->present()->skypeBot);
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
<?php namespace App\Ninja\Intents;
|
||||
|
||||
use Exception;
|
||||
use App\Models\EntityModel;
|
||||
use App\Models\Invoice;
|
||||
|
||||
class CreateInvoiceItemsIntent extends InvoiceIntent
|
||||
{
|
||||
public function process()
|
||||
{
|
||||
$invoice = $this->invoice();
|
||||
$invoiceItems = $this->parseInvoiceItems();
|
||||
|
||||
$data = [
|
||||
'public_id' => $invoice->public_id,
|
||||
'invoice_items' => array_merge($invoice->invoice_items->toArray(), $invoiceItems),
|
||||
];
|
||||
|
||||
var_dump($data);
|
||||
$valid = EntityModel::validate($data, ENTITY_INVOICE, $invoice);
|
||||
|
||||
if ($valid !== true) {
|
||||
throw new Exception($valid);
|
||||
}
|
||||
|
||||
$invoice = $this->invoiceRepo->save($data, $invoice);
|
||||
|
||||
$invoiceItems = array_slice($invoice->invoice_items->toArray(), count($invoiceItems) * -1);
|
||||
$invoiceItemIds = array_map(function($item) {
|
||||
return $item['public_id'];
|
||||
}, $invoiceItems);
|
||||
|
||||
$this->setEntities(ENTITY_INVOICE_ITEM, $invoiceItemIds);
|
||||
|
||||
return view('bots.skype.invoice', [
|
||||
'invoice' => $invoice->load('invoice_items')
|
||||
])->render();
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
<?php namespace App\Ninja\Intents;
|
||||
|
||||
use Auth;
|
||||
use App\Models\EntityModel;
|
||||
use App\Models\Invoice;
|
||||
use Auth;
|
||||
use App\Libraries\Skype\SkypeResponse;
|
||||
|
||||
class DownloadInvoiceIntent extends InvoiceIntent
|
||||
{
|
||||
@ -13,8 +14,6 @@ class DownloadInvoiceIntent extends InvoiceIntent
|
||||
$message = trans('texts.' . $invoice->getEntityType()) . ' ' . $invoice->invoice_number;
|
||||
$message = link_to('/download/' . $invoice->invitations[0]->invitation_key, $message);
|
||||
|
||||
return view('bots.skype.message', [
|
||||
'message' => $message
|
||||
])->render();
|
||||
return SkypeResponse::message($message);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ use Auth;
|
||||
use Exception;
|
||||
use App\Models\EntityModel;
|
||||
use App\Models\Invoice;
|
||||
use App\Libraries\Skype\SkypeResponse;
|
||||
|
||||
class EmailInvoiceIntent extends InvoiceIntent
|
||||
{
|
||||
@ -20,8 +21,6 @@ class EmailInvoiceIntent extends InvoiceIntent
|
||||
|
||||
$message = trans('texts.bot_emailed_' . $invoice->getEntityType());
|
||||
|
||||
return view('bots.skype.message', [
|
||||
'message' => $message
|
||||
])->render();
|
||||
return SkypeResponse::message($message);
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,9 @@ use App\Models\Invoice;
|
||||
|
||||
class InvoiceIntent extends BaseIntent
|
||||
{
|
||||
private $_invoice;
|
||||
private $_invoiceItem;
|
||||
|
||||
public function __construct($state, $data)
|
||||
{
|
||||
$this->invoiceRepo = app('App\Ninja\Repositories\InvoiceRepository');
|
||||
@ -15,6 +18,10 @@ class InvoiceIntent extends BaseIntent
|
||||
|
||||
protected function invoice()
|
||||
{
|
||||
if ($this->_invoice) {
|
||||
return $this->_invoice;
|
||||
}
|
||||
|
||||
$invoiceId = $this->entity(ENTITY_INVOICE);
|
||||
|
||||
if ( ! $invoiceId) {
|
||||
@ -34,6 +41,19 @@ class InvoiceIntent extends BaseIntent
|
||||
return $invoice;
|
||||
}
|
||||
|
||||
protected function invoiceItem()
|
||||
{
|
||||
if ($this->_invoiceItem) {
|
||||
return $this->_invoiceItem;
|
||||
}
|
||||
|
||||
$invoiceItemId = $this->entity(ENTITY_INVOICE_ITEM);
|
||||
|
||||
if ( ! $invoiceItemId) {
|
||||
$invoice = $this->invoice();
|
||||
}
|
||||
}
|
||||
|
||||
protected function parseInvoiceItems()
|
||||
{
|
||||
$productRepo = app('App\Ninja\Repositories\ProductRepository');
|
||||
@ -58,6 +78,7 @@ class InvoiceIntent extends BaseIntent
|
||||
|
||||
$item = $product->toArray();
|
||||
$item['qty'] = $qty;
|
||||
|
||||
$invoiceItems[] = $item;
|
||||
}
|
||||
}
|
||||
@ -65,4 +86,10 @@ class InvoiceIntent extends BaseIntent
|
||||
return $invoiceItems;
|
||||
}
|
||||
|
||||
protected function parseFields()
|
||||
{
|
||||
$data = parent::parseFields();
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
19
app/Ninja/Intents/ListProductsIntent.php
Normal file
19
app/Ninja/Intents/ListProductsIntent.php
Normal file
@ -0,0 +1,19 @@
|
||||
<?php namespace App\Ninja\Intents;
|
||||
|
||||
use Auth;
|
||||
use Exception;
|
||||
use App\Models\Product;
|
||||
|
||||
|
||||
class ListProductsIntent extends ProductIntent
|
||||
{
|
||||
public function process()
|
||||
{
|
||||
$products = Product::scope()->get();
|
||||
|
||||
return view('bots.skype.list', [
|
||||
'items' => $products
|
||||
])->render();
|
||||
|
||||
}
|
||||
}
|
15
app/Ninja/Intents/ProductIntent.php
Normal file
15
app/Ninja/Intents/ProductIntent.php
Normal file
@ -0,0 +1,15 @@
|
||||
<?php namespace App\Ninja\Intents;
|
||||
|
||||
use Auth;
|
||||
use Exception;
|
||||
|
||||
|
||||
class ProductIntent extends BaseIntent
|
||||
{
|
||||
public function __construct($state, $data)
|
||||
{
|
||||
$this->productRepo = app('App\Ninja\Repositories\ProductRepository');
|
||||
|
||||
parent::__construct($state, $data);
|
||||
}
|
||||
}
|
@ -9,13 +9,46 @@ class UpdateInvoiceIntent extends InvoiceIntent
|
||||
public function process()
|
||||
{
|
||||
$invoice = $this->invoice();
|
||||
$invoiceItems = $this->parseInvoiceItems();
|
||||
|
||||
$data = $this->parseFields();
|
||||
$data = array_merge($this->parseFields(), [
|
||||
'public_id' => $invoice->public_id,
|
||||
'invoice_items' => array_merge($invoice->invoice_items->toArray(), $invoiceItems),
|
||||
]);
|
||||
|
||||
dd($data);
|
||||
// map the cost and qty fields to the invoice items
|
||||
if (isset($data['cost']) || isset($data['quantity'])) {
|
||||
foreach ($data['invoice_items'] as $key => $item) {
|
||||
// if it's new or we recently created it
|
||||
if (empty($item['public_id']) || in_array($item['public_id'], $this->entities(ENTITY_INVOICE_ITEM))) {
|
||||
$data['invoice_items'][$key]['cost'] = isset($data['cost']) ? $data['cost'] : $item['cost'];
|
||||
$data['invoice_items'][$key]['qty'] = isset($data['quantity']) ? $data['quantity'] : $item['qty'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return view('bots.skype.invoice', [
|
||||
'invoice' => $invoice
|
||||
])->render();
|
||||
var_dump($data);
|
||||
|
||||
$valid = EntityModel::validate($data, ENTITY_INVOICE, $invoice);
|
||||
|
||||
if ($valid !== true) {
|
||||
throw new Exception($valid);
|
||||
}
|
||||
|
||||
$invoice = $this->invoiceRepo->save($data, $invoice);
|
||||
|
||||
$invoiceItems = array_slice($invoice->invoice_items->toArray(), count($invoiceItems) * -1);
|
||||
$invoiceItemIds = array_map(function($item) {
|
||||
return $item['public_id'];
|
||||
}, $invoiceItems);
|
||||
|
||||
$this->setEntities(ENTITY_INVOICE_ITEM, $invoiceItemIds);
|
||||
|
||||
$response = $invoice
|
||||
->load('invoice_items')
|
||||
->present()
|
||||
->skypeBot;
|
||||
|
||||
return $this->createResponse('message/card.receipt', $response);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<?php namespace App\Ninja\Presenters;
|
||||
|
||||
use Utils;
|
||||
use App\Libraries\Skype\InvoiceCard;
|
||||
|
||||
class InvoicePresenter extends EntityPresenter {
|
||||
|
||||
@ -22,6 +23,14 @@ class InvoicePresenter extends EntityPresenter {
|
||||
return $account->formatMoney($invoice->amount, $invoice->client);
|
||||
}
|
||||
|
||||
public function requestedAmount()
|
||||
{
|
||||
$invoice = $this->entity;
|
||||
$account = $invoice->account;
|
||||
|
||||
return $account->formatMoney($invoice->getRequestedAmount(), $invoice->client);
|
||||
}
|
||||
|
||||
public function balanceDueLabel()
|
||||
{
|
||||
if ($this->entity->partial > 0) {
|
||||
@ -33,6 +42,26 @@ class InvoicePresenter extends EntityPresenter {
|
||||
}
|
||||
}
|
||||
|
||||
public function dueDateLabel()
|
||||
{
|
||||
if ($this->entity->isType(INVOICE_TYPE_STANDARD)) {
|
||||
return trans('texts.due_date');
|
||||
} else {
|
||||
return trans('texts.valid_until');
|
||||
}
|
||||
}
|
||||
|
||||
public function discount()
|
||||
{
|
||||
$invoice = $this->entity;
|
||||
|
||||
if ($invoice->is_amount_discount) {
|
||||
return $invoice->account->formatMoney($invoice->discount);
|
||||
} else {
|
||||
return $invoice->discount . '%';
|
||||
}
|
||||
}
|
||||
|
||||
// https://schema.org/PaymentStatusType
|
||||
public function paymentStatus()
|
||||
{
|
||||
@ -107,4 +136,9 @@ class InvoicePresenter extends EntityPresenter {
|
||||
|
||||
return trans('texts.auto_bill_notification', $data);
|
||||
}
|
||||
|
||||
public function skypeBot()
|
||||
{
|
||||
return new InvoiceCard($this->entity);
|
||||
}
|
||||
}
|
||||
|
@ -12,15 +12,25 @@
|
||||
{
|
||||
"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 }}"
|
||||
}
|
||||
@if ($invoice->due_date)
|
||||
, {
|
||||
"key": "{{ $invoice->present()->dueDateLabel }}:",
|
||||
"value": "{{ $invoice->present()->due_date }}"
|
||||
}
|
||||
@endif
|
||||
@if ($invoice->po_number)
|
||||
, {
|
||||
"key": "{{ trans('texts.po_number') }}:",
|
||||
"value": "{{ $invoice->po_number }}"
|
||||
}
|
||||
@endif
|
||||
@if ($invoice->discount)
|
||||
, {
|
||||
"key": "{{ trans('texts.discount') }}:",
|
||||
"value": "{{ $invoice->present()->discount }}"
|
||||
}
|
||||
@endif
|
||||
],
|
||||
"items":[
|
||||
@foreach ($invoice->invoice_items as $item)
|
||||
@ -38,7 +48,7 @@
|
||||
@if (false)
|
||||
"tax":"0.00",
|
||||
@endif
|
||||
"total":"{{ $invoice->present()->amount }}",
|
||||
"total":"{{ $invoice->present()->requestedAmount }}",
|
||||
"buttons":[
|
||||
{
|
||||
"type":"imBack",
|
||||
|
29
resources/views/bots/skype/list.blade.php
Normal file
29
resources/views/bots/skype/list.blade.php
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"type":"message/card.carousel",
|
||||
"attachments":[
|
||||
@foreach ($items as $item)
|
||||
@if ($items[0] != $item)
|
||||
,
|
||||
@endif
|
||||
{
|
||||
"contentType": "application/vnd.microsoft.card.hero",
|
||||
"content": {
|
||||
"title": "{{ $item['title'] }}",
|
||||
"subtitle": "{{ $item['subtitle'] }}",
|
||||
"buttons": [
|
||||
@foreach($item['buttons'] as $button)
|
||||
@if ($items['buttons'][0] != $button)
|
||||
,
|
||||
@endif
|
||||
{
|
||||
"type": "{{ $button['type'] }}",
|
||||
"title": "{{ $button['title'] }}",
|
||||
"value": "https://en.wikipedia.org/wiki/{cardContent.Key}"
|
||||
}
|
||||
@endforeach
|
||||
]
|
||||
}
|
||||
}
|
||||
@endforeach
|
||||
]
|
||||
}
|
Loading…
Reference in New Issue
Block a user