mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
Working on speech rec
This commit is contained in:
parent
dcee9285d9
commit
fcbc9bd885
@ -100,6 +100,7 @@ class BotController extends Controller
|
||||
public function handleCommand()
|
||||
{
|
||||
$data = $this->parseMessage(request()->command);
|
||||
//dd($data);
|
||||
$intent = BaseIntent::createIntent(BOT_PLATFORM_WEB_APP, false, $data);
|
||||
|
||||
return $intent->process();
|
||||
|
@ -194,6 +194,7 @@ class InvoiceController extends BaseController
|
||||
|
||||
$invoice = $account->createInvoice($entityType, $clientId);
|
||||
$invoice->public_id = 0;
|
||||
$invoice->loadFromRequest();
|
||||
|
||||
$clients = Client::scope()->with('contacts', 'country')->orderBy('name');
|
||||
if (! Auth::user()->hasPermission('view_all')) {
|
||||
|
@ -319,6 +319,15 @@ class EntityModel extends Eloquent
|
||||
return array_get($icons, $entityType);
|
||||
}
|
||||
|
||||
public function loadFromRequest()
|
||||
{
|
||||
foreach (static::$requestFields as $field) {
|
||||
if ($value = request()->$field) {
|
||||
$this->$field = strpos($field, 'date') ? Utils::fromSqlDate($value) : $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// isDirty return true if the field's new value is the same as the old one
|
||||
public function isChanged()
|
||||
{
|
||||
|
@ -73,6 +73,18 @@ class Invoice extends EntityModel implements BalanceAffecting
|
||||
'date:',
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public static $requestFields = [
|
||||
'invoice_number',
|
||||
'invoice_date',
|
||||
'due_date',
|
||||
'po_number',
|
||||
'discount',
|
||||
'partial',
|
||||
];
|
||||
|
||||
public static $statusClasses = [
|
||||
INVOICE_STATUS_SENT => 'info',
|
||||
INVOICE_STATUS_VIEWED => 'warning',
|
||||
|
@ -187,9 +187,11 @@ class BaseIntent
|
||||
{
|
||||
$field = str_replace(' ', '_', $field);
|
||||
|
||||
/* Shouldn't be need any more
|
||||
if (strpos($field, 'date') !== false) {
|
||||
$field .= '_sql';
|
||||
}
|
||||
*/
|
||||
|
||||
return $field;
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Ninja\Intents\WebApp;
|
||||
|
||||
use App\Models\Invoice;
|
||||
use App\Models\EntityModel;
|
||||
use App\Ninja\Intents\InvoiceIntent;
|
||||
use Exception;
|
||||
@ -11,18 +12,21 @@ class CreateInvoiceIntent extends InvoiceIntent
|
||||
public function process()
|
||||
{
|
||||
$client = $this->requestClient();
|
||||
$invoiceItems = $this->requestInvoiceItems();
|
||||
$clientPublicId = $client ? $client->public_id : null;
|
||||
|
||||
if (! $client) {
|
||||
throw new Exception(trans('texts.client_not_found'));
|
||||
//$invoiceItems = $this->requestInvoiceItems();
|
||||
|
||||
$url = '/invoices/create/' . $clientPublicId . '?';
|
||||
|
||||
foreach ($this->requestFields() as $field => $value) {
|
||||
if (in_array($field, Invoice::$requestFields)) {
|
||||
$url .= $field . '=' . urlencode($value) . '&';
|
||||
}
|
||||
}
|
||||
|
||||
$data = array_merge($this->requestFields(), [
|
||||
'client_id' => $client->public_id,
|
||||
'invoice_items' => $invoiceItems,
|
||||
]);
|
||||
$url = rtrim($url, '?');
|
||||
$url = rtrim($url, '&');
|
||||
|
||||
//var_dump($data);
|
||||
dd($data);
|
||||
return redirect($url);
|
||||
}
|
||||
}
|
||||
|
@ -2464,6 +2464,7 @@ $LANG = array(
|
||||
'confirm_account_to_import' => 'Please confirm your account to import data.',
|
||||
'import_started' => 'Your import has started, we\'ll send you an email once it completes.',
|
||||
'listening' => 'Listening...',
|
||||
'microphone_help' => 'Say \'Create new invoice for...\'',
|
||||
|
||||
);
|
||||
|
||||
|
@ -132,6 +132,12 @@
|
||||
$('#left-menu-toggle').trigger('click');
|
||||
});
|
||||
|
||||
@if (Utils::isNinja())
|
||||
Mousetrap.bind('r', function(e) {
|
||||
onMicrophoneClick();
|
||||
});
|
||||
@endif
|
||||
|
||||
@foreach([
|
||||
'i' => ENTITY_INVOICE,
|
||||
'p' => ENTITY_PAYMENT,
|
||||
|
@ -1,20 +1,25 @@
|
||||
<i id="microphone" class="fa fa-microphone form-control-feedback"
|
||||
style=""
|
||||
onclick="startButton(event)" aria-hidden="true"></i>
|
||||
title="{{ trans('texts.microphone_help') }}"
|
||||
onclick="onMicrophoneClick()" aria-hidden="true"></i>
|
||||
|
||||
<style type="text/css">
|
||||
#microphone {
|
||||
font-size:16px;
|
||||
padding-top:8px;
|
||||
cursor:pointer;
|
||||
pointer-events:auto;
|
||||
color:#888;
|
||||
font-size: 16px;
|
||||
padding-top: 8px;
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
#microphone:hover {
|
||||
color: black;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
// https://developers.google.com/web/updates/2013/01/Voice-Driven-Web-Apps-Introduction-to-the-Web-Speech-API
|
||||
/*
|
||||
$(function() {
|
||||
$('#search').keypress(function(event) {
|
||||
if (event.keyCode === 13) {
|
||||
@ -22,6 +27,7 @@
|
||||
}
|
||||
})
|
||||
})
|
||||
*/
|
||||
|
||||
var langs =
|
||||
[['Afrikaans', ['af-ZA']],
|
||||
@ -99,10 +105,9 @@
|
||||
var final_transcript = '';
|
||||
var recognizing = false;
|
||||
var ignore_onend;
|
||||
var start_timestamp;
|
||||
|
||||
if (!('webkitSpeechRecognition' in window)) {
|
||||
upgrade();
|
||||
$('.fa-microphone').hide();
|
||||
} else {
|
||||
var recognition = new webkitSpeechRecognition();
|
||||
recognition.continuous = false;
|
||||
@ -136,6 +141,7 @@
|
||||
if (!final_transcript) {
|
||||
return;
|
||||
}
|
||||
$('#search-form').submit();
|
||||
};
|
||||
|
||||
recognition.onresult = function(event) {
|
||||
@ -143,7 +149,7 @@
|
||||
if (typeof(event.results) == 'undefined') {
|
||||
recognition.onend = null;
|
||||
recognition.stop();
|
||||
upgrade();
|
||||
$('.fa-microphone').hide();
|
||||
return;
|
||||
}
|
||||
for (var i = event.resultIndex; i < event.results.length; ++i) {
|
||||
@ -154,7 +160,6 @@
|
||||
}
|
||||
}
|
||||
final_transcript = capitalize(final_transcript);
|
||||
|
||||
var value = final_transcript || interim_transcript;
|
||||
var $search = document.getElementById('search');
|
||||
$search.value = value;
|
||||
@ -162,22 +167,16 @@
|
||||
};
|
||||
}
|
||||
|
||||
function upgrade() {
|
||||
$('.fa-microphone').hide();
|
||||
}
|
||||
|
||||
var two_line = /\n\n/g;
|
||||
var one_line = /\n/g;
|
||||
function linebreak(s) {
|
||||
return s.replace(two_line, '<p></p>').replace(one_line, '<br>');
|
||||
}
|
||||
|
||||
var first_char = /\S/;
|
||||
function capitalize(s) {
|
||||
return s.replace(first_char, function(m) { return m.toUpperCase(); });
|
||||
}
|
||||
|
||||
function startButton(event) {
|
||||
function onMicrophoneClick() {
|
||||
$('#search').val('create new invoice for edgar a po number of 1234');
|
||||
$('#search-form').submit();
|
||||
return;
|
||||
|
||||
$('.fa-microphone').hide();
|
||||
$('#search').val("{{ trans('texts.listening') }}");
|
||||
if (recognizing) {
|
||||
@ -188,7 +187,6 @@
|
||||
recognition.lang = 'en-US';
|
||||
recognition.start();
|
||||
ignore_onend = false;
|
||||
start_timestamp = event.timeStamp;
|
||||
}
|
||||
|
||||
</script>
|
||||
|
Loading…
x
Reference in New Issue
Block a user