1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-09 12:42:36 +01:00

Merge branch 'release-3.2.1'

This commit is contained in:
Hillel Coren 2017-04-06 17:11:03 +03:00
commit a2df6bdc51
71 changed files with 1292 additions and 185 deletions

View File

@ -45,6 +45,7 @@ FCM_API_TOKEN=
#CACHE_DRIVER=
#CACHE_HOST=
#REDIS_HOST=
#CACHE_PORT1=
#CACHE_PORT2=

View File

@ -70,7 +70,7 @@ All contributors are welcome!
For information on how contribute to Invoice Ninja, please see our [contributing guide](CONTRIBUTING.md).
## Credits
* [Hillel Coren](https://github.com/hillelcoren)
* [Hillel Coren](https://hillelcoren.com/)
* [All contributors](https://github.com/invoiceninja/invoiceninja/graphs/contributors)
**Special thanks to:**

View File

@ -296,7 +296,7 @@ if (! defined('APP_NAME')) {
define('NINJA_APP_URL', env('NINJA_APP_URL', 'https://app.invoiceninja.com'));
define('NINJA_DOCS_URL', env('NINJA_DOCS_URL', 'http://docs.invoiceninja.com/en/latest'));
define('NINJA_DATE', '2000-01-01');
define('NINJA_VERSION', '3.2.0' . env('NINJA_VERSION_SUFFIX'));
define('NINJA_VERSION', '3.2.1' . env('NINJA_VERSION_SUFFIX'));
define('SOCIAL_LINK_FACEBOOK', env('SOCIAL_LINK_FACEBOOK', 'https://www.facebook.com/invoiceninja'));
define('SOCIAL_LINK_TWITTER', env('SOCIAL_LINK_TWITTER', 'https://twitter.com/invoiceninja'));
@ -321,10 +321,13 @@ if (! defined('APP_NAME')) {
define('FIREFOX_PDF_HELP_URL', 'https://support.mozilla.org/en-US/kb/view-pdf-files-firefox');
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('MSBOT_LUIS_URL', 'https://westus.api.cognitive.microsoft.com/luis/v2.0/apps');
define('SKYPE_API_URL', 'https://apis.skype.com/v3');
define('MSBOT_STATE_URL', 'https://state.botframework.com/v3');
define('BOT_PLATFORM_WEB_APP', 'WebApp');
define('BOT_PLATFORM_SKYPE', 'Skype');
define('BLANK_IMAGE', 'data:image/png;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=');
define('COUNT_FREE_DESIGNS', 4);

View File

@ -80,7 +80,7 @@ class BotController extends Controller
$user->account->loadLocalizationSettings();
$data = $this->parseMessage($text);
$intent = BaseIntent::createIntent($state, $data);
$intent = BaseIntent::createIntent($platform, $state, $data);
$response = $intent->process();
$state = $intent->getState();
}
@ -97,6 +97,20 @@ class BotController extends Controller
return RESULT_SUCCESS;
}
public function handleCommand()
{
$command = request()->command;
$data = $this->parseMessage($command);
try {
$intent = BaseIntent::createIntent(BOT_PLATFORM_WEB_APP, false, $data);
return $intent->process();
} catch (Exception $exception) {
$message = sprintf('"%s"<br/>%s', $command, $exception->getMessage());
return redirect()->back()->withWarning($message);
}
}
private function authenticate($input)
{
$token = isset($_SERVER['HTTP_AUTHORIZATION']) ? $_SERVER['HTTP_AUTHORIZATION'] : false;
@ -146,7 +160,8 @@ class BotController extends Controller
$subKey = env('MSBOT_LUIS_SUBSCRIPTION_KEY');
$message = rawurlencode($message);
$url = sprintf('%s?id=%s&subscription-key=%s&q=%s', MSBOT_LUIS_URL, $appId, $subKey, $message);
$url = sprintf('%s/%s?subscription-key=%s&verbose=true&q=%s', MSBOT_LUIS_URL, $appId, $subKey, $message);
//$url = sprintf('%s?id=%s&subscription-key=%s&q=%s', MSBOT_LUIS_URL, $appId, $subKey, $message);
$data = file_get_contents($url);
$data = json_decode($data);

View File

@ -326,14 +326,20 @@ class ClientPortalController extends BaseController
}
$color = $account->primary_color ? $account->primary_color : '#0b4d78';
$columns = ['frequency', 'start_date', 'end_date', 'invoice_total'];
$client = $contact->client;
if ($client->hasAutoBillConfigurableInvoices()) {
$columns[] = 'auto_bill';
}
$data = [
'color' => $color,
'account' => $account,
'client' => $contact->client,
'client' => $client,
'title' => trans('texts.recurring_invoices'),
'entityType' => ENTITY_RECURRING_INVOICE,
'columns' => Utils::trans(['frequency', 'start_date', 'end_date', 'invoice_total', 'auto_bill']),
'columns' => Utils::trans($columns),
];
return response()->view('public_list', $data);

View File

@ -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')) {

View File

@ -127,6 +127,7 @@ Route::group(['middleware' => 'auth:user'], function () {
Route::get('check_invoice_number/{invoice_id?}', 'InvoiceController@checkInvoiceNumber');
Route::post('save_sidebar_state', 'UserController@saveSidebarState');
Route::post('contact_us', 'HomeController@contactUs');
Route::post('handle_command', 'BotController@handleCommand');
Route::get('settings/user_details', 'AccountController@showUserDetails');
Route::post('settings/user_details', 'AccountController@saveUserDetails');

View File

@ -543,7 +543,15 @@ class Client extends EntityModel
*/
public function hasAutoBillConfigurableInvoices()
{
return $this->invoices()->whereIn('auto_bill', [AUTO_BILL_OPT_IN, AUTO_BILL_OPT_OUT])->count() > 0;
return $this->invoices()->whereIsPublic(true)->whereIn('auto_bill', [AUTO_BILL_OPT_IN, AUTO_BILL_OPT_OUT])->count() > 0;
}
/**
* @return bool
*/
public function hasRecurringInvoices()
{
return $this->invoices()->whereIsPublic(true)->whereIsRecurring(true)->count() > 0;
}
public function defaultDaysDue()

View File

@ -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()
{

View File

@ -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',

View File

@ -13,4 +13,26 @@ class InvoiceStatus extends Eloquent
* @var bool
*/
public $timestamps = false;
public static function getIdFromAlias($status)
{
switch ($status) {
case 'draft':
return INVOICE_STATUS_DRAFT;
case 'sent':
return INVOICE_STATUS_SENT;
case 'viewed':
return INVOICE_STATUS_VIEWED;
case 'approved':
return INVOICE_STATUS_APPROVED;
case 'partial':
return INVOICE_STATUS_PARTIAL;
case 'overdue':
return INVOICE_STATUS_OVERDUE;
case 'unpaid':
return INVOICE_STATUS_UNPAID;
default:
return false;
}
}
}

View File

@ -3,6 +3,7 @@
namespace App\Ninja\Intents;
use App\Libraries\Skype\SkypeResponse;
use App\Models\Client;
use Exception;
use stdClass;
@ -28,11 +29,22 @@ class BaseIntent
$this->state = $state;
$this->data = $data;
// If they're viewing a client set it as the current state
if (! $this->hasField('Filter', 'all')) {
$url = url()->previous();
preg_match('/clients\/(\d*)/', $url, $matches);
if (count($matches) >= 2) {
if ($client = Client::scope($matches[1])->first()) {
$this->state->current->client = $client;
}
}
}
//var_dump($state);
}
public static function createIntent($state, $data)
public static function createIntent($platform, $state, $data)
{
if (! count($data->intents)) {
throw new Exception(trans('texts.intent_not_found'));
@ -43,20 +55,26 @@ class BaseIntent
foreach ($data->entities as $entity) {
if ($entity->type === 'EntityType') {
$entityType = $entity->entity;
$entityType = rtrim($entity->entity, 's');
break;
}
}
if (! $entityType) {
if ($state && ! $entityType) {
$entityType = $state->current->entityType;
}
$entityType = $entityType ?: 'client';
$entityType = ucwords(strtolower($entityType));
if ($entityType == 'Recurring') {
$entityType = 'RecurringInvoice';
}
$intent = str_replace('Entity', $entityType, $intent);
$className = "App\\Ninja\\Intents\\{$intent}Intent";
//echo "Intent: $intent<p>";
if ($platform == BOT_PLATFORM_WEB_APP) {
$className = "App\\Ninja\\Intents\\WebApp\\{$intent}Intent";
} else {
$className = "App\\Ninja\\Intents\\{$intent}Intent";
}
if (! class_exists($className)) {
throw new Exception(trans('texts.intent_not_supported'));
@ -65,6 +83,52 @@ class BaseIntent
return new $className($state, $data);
}
protected function getField($field)
{
foreach ($this->data->entities as $entity) {
if ($entity->type === $field) {
return $entity->entity;
}
}
return false;
}
protected function getFields($field)
{
$data = [];
foreach ($this->data->entities as $entity) {
if ($entity->type === $field) {
$data[] = $entity->entity;
}
}
return $data;
}
protected function loadStates($entityType)
{
$states = array_filter($this->getFields('Filter'), function($state) {
return in_array($state, [STATUS_ACTIVE, STATUS_ARCHIVED, STATUS_DELETED]);
});
if (count($states) || $this->hasField('Filter', 'all')) {
session(['entity_state_filter:' . $entityType => join(',', $states)]);
}
}
protected function hasField($field, $value = false)
{
$fieldValue = $this->getField($field);
if ($value) {
return $fieldValue && $fieldValue == $value;
} else {
return $fieldValue ? true : false;
}
}
public function process()
{
throw new Exception(trans('texts.intent_not_supported'));
@ -128,13 +192,32 @@ class BaseIntent
foreach ($this->data->entities as $param) {
if ($param->type == 'Name') {
$param->type = rtrim($param->type, ' \' s');
$client = $clientRepo->findPhonetically($param->entity);
}
}
if (! $client) {
$client = $this->state->current->client;
}
return $client;
}
protected function requestInvoice()
{
$invoiceRepo = app('App\Ninja\Repositories\InvoiceRepository');
$invoice = false;
foreach ($this->data->entities as $param) {
if ($param->type == 'builtin.number') {
return $invoiceRepo->findPhonetically($param->entity);
}
}
return false;
}
protected function requestFields()
{
$data = [];
@ -178,13 +261,31 @@ class BaseIntent
return $data;
}
protected function requestFieldsAsString($fields)
{
$str = '';
foreach ($this->requestFields() as $field => $value) {
if (in_array($field, $fields)) {
$str .= $field . '=' . urlencode($value) . '&';
}
}
$str = rtrim($str, '?');
$str = rtrim($str, '&');
return $str;
}
protected function processField($field)
{
$field = str_replace(' ', '_', $field);
/* Shouldn't be need any more
if (strpos($field, 'date') !== false) {
$field .= '_sql';
}
*/
return $field;
}

View File

@ -3,6 +3,7 @@
namespace App\Ninja\Intents;
use App\Models\Invoice;
use App\Models\InvoiceStatus;
use Auth;
use Exception;
@ -104,4 +105,20 @@ class InvoiceIntent extends BaseIntent
return $invoiceItems;
}
protected function loadStatuses($entityType)
{
$statusIds = [];
$statuses = $this->getFields('Filter');
foreach ($statuses as $status) {
if ($statusId = InvoiceStatus::getIdFromAlias($status)) {
$statusIds[] = $statusId;
}
}
if (count($statusIds) || $this->hasField('Filter', 'all')) {
session(['entity_status_filter:' . $entityType => join(',', $statusIds)]);
}
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class CreateClientIntent extends BaseIntent
{
public function process()
{
$url = '/clients/create';
//$url = '/invoices/create/' . $clientPublicId . '?';
//$url .= $this->requestFieldsAsString(Invoice::$requestFields);
return redirect($url);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class CreateCreditIntent extends BaseIntent
{
public function process()
{
$client = $this->requestClient();
$clientPublicId = $client ? $client->public_id : null;
//$invoiceItems = $this->requestInvoiceItems();
$url = '/credits/create/' . $clientPublicId;
//$url .= $this->requestFieldsAsString(Invoice::$requestFields);
return redirect($url);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class CreateExpenseIntent extends BaseIntent
{
public function process()
{
$url = '/expenses/create';
//$url = '/invoices/create/' . $clientPublicId . '?';
//$url .= $this->requestFieldsAsString(Invoice::$requestFields);
return redirect($url);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Models\Invoice;
use App\Models\EntityModel;
use App\Ninja\Intents\InvoiceIntent;
use Exception;
class CreateInvoiceIntent extends InvoiceIntent
{
public function process()
{
$client = $this->requestClient();
$clientPublicId = $client ? $client->public_id : null;
//$invoiceItems = $this->requestInvoiceItems();
$url = '/invoices/create/' . $clientPublicId . '?';
$url .= $this->requestFieldsAsString(Invoice::$requestFields);
$url = rtrim($url, '?');
$url = rtrim($url, '&');
return redirect($url);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class CreatePaymentIntent extends BaseIntent
{
public function process()
{
$clientPublicId = 0;
$invoicePublicId = 0;
if ($invoice = $this->requestInvoice()) {
$invoicePublicId = $invoice->public_id;
} elseif ($client = $this->requestClient()) {
$clientPublicId = $client->public_id;
}
//$invoiceItems = $this->requestInvoiceItems();
$url = sprintf('/payments/create/%s/%s', $clientPublicId, $invoicePublicId);
//$url .= $this->requestFieldsAsString(Invoice::$requestFields);
return redirect($url);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Models\Product;
use App\Models\EntityModel;
use App\Ninja\Intents\ProductIntent;
use Exception;
class CreateProductIntent extends ProductIntent
{
public function process()
{
$url = '/products/create';
//$url = '/invoices/create/' . $clientPublicId . '?';
//$url .= $this->requestFieldsAsString(Invoice::$requestFields);
return redirect($url);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Models\Invoice;
use App\Ninja\Intents\BaseIntent;
class CreateQuoteIntent extends BaseIntent
{
public function process()
{
$client = $this->requestClient();
$clientPublicId = $client ? $client->public_id : null;
//$invoiceItems = $this->requestInvoiceItems();
$url = '/quotes/create/' . $clientPublicId . '?';
$url .= $this->requestFieldsAsString(Invoice::$requestFields);
$url = rtrim($url, '?');
$url = rtrim($url, '&');
return redirect($url);
}
}

View File

@ -0,0 +1,25 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Models\Invoice;
use App\Ninja\Intents\BaseIntent;
class CreateRecurringInvoiceIntent extends BaseIntent
{
public function process()
{
$client = $this->requestClient();
$clientPublicId = $client ? $client->public_id : null;
//$invoiceItems = $this->requestInvoiceItems();
$url = '/recurring_invoices/create/' . $clientPublicId . '?';
$url .= $this->requestFieldsAsString(Invoice::$requestFields);
$url = rtrim($url, '?');
$url = rtrim($url, '&');
return redirect($url);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class CreateTaskIntent extends BaseIntent
{
public function process()
{
$client = $this->requestClient();
$clientPublicId = $client ? $client->public_id : null;
//$invoiceItems = $this->requestInvoiceItems();
$url = '/tasks/create/' . $clientPublicId . '?';
//$url .= $this->requestFieldsAsString(Invoice::$requestFields);
return redirect($url);
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class CreateVendorIntent extends BaseIntent
{
public function process()
{
$url = '/vendors/create';
//$url = '/invoices/create/' . $clientPublicId . '?';
//$url .= $this->requestFieldsAsString(Invoice::$requestFields);
return redirect($url);
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class FindClientIntent extends BaseIntent
{
public function process()
{
$client = $this->requestClient();
$url = $client ? $client->present()->url : '/clients';
return redirect($url);
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\InvoiceIntent;
class FindInvoiceIntent extends InvoiceIntent
{
public function process()
{
$invoice = $this->requestInvoice();
$url = $invoice ? $invoice->present()->url : '/invoices';
return redirect($url);
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\InvoiceIntent;
class FindQuoteIntent extends InvoiceIntent
{
public function process()
{
$invoice = $this->requestInvoice();
$url = $invoice ? $invoice->present()->url : '/quotes';
return redirect($url);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class ListClientIntent extends BaseIntent
{
public function process()
{
$this->loadStates(ENTITY_CLIENT);
return redirect('/clients');
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class ListCreditIntent extends BaseIntent
{
public function process()
{
$this->loadStates(ENTITY_CREDIT);
if ($client = $this->requestClient()) {
$url = $client->present()->url . '#credits';
} else {
$url = '/credits';
}
return redirect($url);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class ListExpenseIntent extends BaseIntent
{
public function process()
{
$this->loadStates(ENTITY_EXPENSE);
return redirect('/expenses');
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\InvoiceIntent;
class ListInvoiceIntent extends InvoiceIntent
{
public function process()
{
$this->loadStates(ENTITY_INVOICE);
$this->loadStatuses(ENTITY_INVOICE);
if ($client = $this->requestClient()) {
$url = $client->present()->url . '#invoices';
} else {
$url = '/invoices';
}
return redirect($url);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class ListPaymentIntent extends BaseIntent
{
public function process()
{
$this->loadStates(ENTITY_PAYMENT);
if ($client = $this->requestClient()) {
$url = $client->present()->url . '#payments';
} else {
$url = '/payments';
}
return redirect($url);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class ListProductIntent extends BaseIntent
{
public function process()
{
$this->loadStates(ENTITY_PRODUCT);
return redirect('/products');
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\InvoiceIntent;
class ListQuoteIntent extends InvoiceIntent
{
public function process()
{
$this->loadStates(ENTITY_QUOTE);
$this->loadStatuses(ENTITY_QUOTE);
if ($client = $this->requestClient()) {
$url = $client->present()->url . '#quotes';
} else {
$url = '/quotes';
}
return redirect($url);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class ListRecurringInvoiceIntent extends BaseIntent
{
public function process()
{
$this->loadStates(ENTITY_RECURRING_INVOICE);
if ($client = $this->requestClient()) {
$url = $client->present()->url . '#recurring_invoices';
} else {
$url = '/recurring_invoices';
}
return redirect($url);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class ListTaskIntent extends BaseIntent
{
public function process()
{
$this->loadStates(ENTITY_TASK);
if ($client = $this->requestClient()) {
$url = $client->present()->url . '#tasks';
} else {
$url = '/tasks';
}
return redirect($url);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Ninja\Intents\BaseIntent;
class ListVendorIntent extends BaseIntent
{
public function process()
{
$this->loadStates(ENTITY_VENDOR);
return redirect('/vendors');
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Ninja\Intents\WebApp;
use App\Models\Account;
use App\Ninja\Intents\BaseIntent;
class NavigateToIntent extends BaseIntent
{
public function process()
{
$location = $this->getField('Location');
$location = str_replace(' ', '_', $location);
if (in_array($location, array_merge(Account::$basicSettings, Account::$advancedSettings))) {
$location = '/settings/' . $location;
} elseif (in_array($location, ['report', 'reports'])) {
$location = '/reports';
} elseif ($location == 'settings') {
$location = '/settings';
} else {
$location = '/dashboard';
}
return redirect($location);
}
}

View File

@ -211,7 +211,6 @@ class InvoiceRepository extends BaseRepository
->where('clients.deleted_at', '=', null)
->where('invoices.is_recurring', '=', true)
->where('invoices.is_public', '=', true)
->whereIn('invoices.auto_bill', [AUTO_BILL_OPT_IN, AUTO_BILL_OPT_OUT])
//->where('invoices.start_date', '>=', date('Y-m-d H:i:s'))
->select(
DB::raw('COALESCE(clients.currency_id, accounts.currency_id) currency_id'),
@ -225,6 +224,7 @@ class InvoiceRepository extends BaseRepository
'invoices.amount',
'invoices.start_date',
'invoices.end_date',
'invoices.auto_bill',
'invoices.client_enable_auto_bill',
'frequencies.name as frequency'
);
@ -243,7 +243,11 @@ class InvoiceRepository extends BaseRepository
return Utils::formatMoney($model->amount, $model->currency_id, $model->country_id);
})
->addColumn('client_enable_auto_bill', function ($model) {
if ($model->client_enable_auto_bill) {
if ($model->auto_bill == AUTO_BILL_OFF) {
return trans('texts.disabled');
} elseif ($model->auto_bill == AUTO_BILL_ALWAYS) {
return trans('texts.enabled');
} elseif ($model->client_enable_auto_bill) {
return trans('texts.enabled') . ' - <a href="javascript:setAutoBill('.$model->public_id.',false)">'.trans('texts.disable').'</a>';
} else {
return trans('texts.disabled') . ' - <a href="javascript:setAutoBill('.$model->public_id.',true)">'.trans('texts.enable').'</a>';
@ -1122,4 +1126,26 @@ class InvoiceRepository extends BaseRepository
$this->save($data, $invoice);
$invoice->load('invoice_items');
}
public function findPhonetically($invoiceNumber)
{
$map = [];
$max = SIMILAR_MIN_THRESHOLD;
$invoiceId = 0;
$invoices = Invoice::scope()->get(['id', 'invoice_number', 'public_id']);
foreach ($invoices as $invoice) {
$map[$invoice->id] = $invoice;
$similar = similar_text($invoiceNumber, $invoice->invoice_number, $percent);
var_dump($similar);
if ($percent > $max) {
$invoiceId = $invoice->id;
$max = $percent;
}
}
return ($invoiceId && isset($map[$invoiceId])) ? $map[$invoiceId] : null;
}
}

View File

@ -68,6 +68,7 @@ class CurrenciesSeeder extends Seeder
['name' => 'Mozambican Metical', 'code' => 'MZN', 'symbol' => 'MT', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ',', 'swap_currency_symbol' => true],
['name' => 'Omani Rial', 'code' => 'OMR', 'symbol' => '', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
['name' => 'Ukrainian Hryvnia', 'code' => 'UAH', 'symbol' => '', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
['name' => 'Macanese Pataca', 'code' => 'MOP', 'symbol' => 'MOP$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'],
];
foreach ($currencies as $currency) {

View File

@ -34,6 +34,7 @@ class PaymentTypesSeeder extends Seeder
['name' => 'Switch', 'gateway_type_id' => GATEWAY_TYPE_CREDIT_CARD],
['name' => 'iZettle', 'gateway_type_id' => GATEWAY_TYPE_CREDIT_CARD],
['name' => 'Swish', 'gateway_type_id' => GATEWAY_TYPE_BANK_TRANSFER],
['name' => 'Venmo'],
];
foreach ($paymentTypes as $paymentType) {

File diff suppressed because one or more lines are too long

View File

@ -59,7 +59,7 @@ author = u'Invoice Ninja'
# The short X.Y version.
version = u'3.2'
# The full version, including alpha/beta/rc tags.
release = u'3.2.0'
release = u'3.2.1'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.

View File

@ -29,7 +29,7 @@ Step 1: Download the code
You can either download the zip file below or checkout the code from our GitHub repository. The zip includes all third party libraries whereas using GitHub requires you to use Composer to install the dependencies.
https://download.invoiceninja.com/ninja-v3.1.3.zip
https://download.invoiceninja.com/ninja-v3.2.0.zip
.. Note:: All Pro and Enterprise features from our hosted app are included in both the zip file and the GitHub repository. We offer a $20 per year white-label license to remove our branding.

View File

@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'Dark',
'industry_help' => 'Used to provide comparisons against the averages of companies of similar size and industry.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a field when creating a client and display the label and value on the PDF.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2463,6 +2464,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -852,6 +852,7 @@ $LANG = array(
'dark' => 'Tmavý',
'industry_help' => 'Používá se pro porovnání proti průměru u firem podobné velikosti a podobného odvětví.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Určete prefix nebo použijte upravitelný vzorec pro nastavení číslování faktur.',
'quote_number_help' => 'Určete prefix nebo použijte upravitelný vzorec pro nastavení číslování nabídek.',
'custom_client_fields_helps' => 'Když vytváříte klienta - přidejte nové pole a jeho popis a hodnotu pro zobrazení v PDF.',
@ -1043,7 +1044,7 @@ $LANG = array(
'invoiced_amount' => 'Fakturovaná částka',
'invoice_item_fields' => 'Pole položky faktury',
'custom_invoice_item_fields_help' => 'Během vytváření faktury si přidejte pole a zobrazte si jeho popis a hodnotu v PDF.',
'recurring_invoice_number' => 'Číslo pravidelné faktury',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Určete prefix, který se přidá k číslu pravidelných faktur. Výchozí hodnota je \'R\'.',
// Client Passwords
@ -2465,6 +2466,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'Dark',
'industry_help' => 'Used to provide comparisons against the averages of companies of similar size and industry.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a text input to the client create/edit page and display the label and value on the PDF.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2463,6 +2464,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -2,7 +2,7 @@
$LANG = array(
'organization' => 'Organisation',
'organization' => 'Unternehmen',
'name' => 'Name',
'website' => 'Webseite',
'work_phone' => 'Telefon',
@ -151,7 +151,7 @@ $LANG = array(
'last_logged_in' => 'Zuletzt eingeloggt',
'details' => 'Details',
'standing' => 'Aktueller Stand',
'credit' => 'Guthaben',
'credit' => 'Gutschrift',
'activity' => 'Aktivität',
'date' => 'Datum',
'message' => 'Nachricht',
@ -266,7 +266,7 @@ $LANG = array(
'working' => 'Wird bearbeitet',
'success' => 'Erfolg',
'success_message' => 'Du hast dich erfolgreich registriert. Bitte besuche den Link in deiner Bestätigungsmail um deine E-Mail-Adresse zu verifizieren.',
'erase_data' => 'Your account is not registered, this will permanently erase your data.',
'erase_data' => 'Ihr Konto ist nicht registriert, diese Aktion wird Ihre Daten unwiederbringlich löschen.',
'password' => 'Passwort',
'pro_plan_product' => 'Pro Plan',
'pro_plan_success' => 'Danke, dass Sie Invoice Ninja\'s Pro gewählt haben!<p/>&nbsp;<br/>
@ -369,7 +369,7 @@ $LANG = array(
'confirm_email_quote' => 'Bist du sicher, dass du dieses Angebot per E-Mail versenden möchtest',
'confirm_recurring_email_invoice' => 'Wiederkehrende Rechnung ist aktiv. Bis du sicher, dass du diese Rechnung weiterhin als E-Mail verschicken möchtest?',
'cancel_account' => 'Konto Kündigen',
'cancel_account_message' => 'Warning: This will permanently delete your account, there is no undo.',
'cancel_account_message' => 'Warnung: Diese Aktion wird Ihr Konto unwiederbringlich löschen.',
'go_back' => 'Zurück',
'data_visualizations' => 'Datenvisualisierungen',
'sample_data' => 'Beispieldaten werden angezeigt',
@ -663,8 +663,8 @@ $LANG = array(
'valid_until' => 'Gültig bis',
'reset_terms' => 'Zahlungsbedingungen zurücksetzen',
'reset_footer' => 'Fußzeile zurücksetzen',
'invoice_sent' => ':count invoice sent',
'invoices_sent' => ':count invoices sent',
'invoice_sent' => ':count Rechnung versendet',
'invoices_sent' => ':count Rechnungen versendet',
'status_draft' => 'Entwurf',
'status_sent' => 'Versendet',
'status_viewed' => 'Angesehen',
@ -701,7 +701,7 @@ $LANG = array(
'oneclick_login' => 'Ein Klick Login',
'disable' => 'Deaktivieren',
'invoice_quote_number' => 'Rechnungs- und Angebotsnummern',
'invoice_charges' => 'Invoice Surcharges',
'invoice_charges' => 'Rechnungsgebühren',
'notification_invoice_bounced' => 'Die Rechnung :invoice an :contact konnte nicht zugestellt werden.',
'notification_invoice_bounced_subject' => 'Rechnung :invoice nicht zugestellt.',
'notification_quote_bounced' => 'Das Angebot :invoice an :contact konnte nicht zugestellt werden.',
@ -792,7 +792,7 @@ $LANG = array(
'default_invoice_footer' => 'Standard-Fußzeile festlegen',
'quote_footer' => 'Angebots-Fußzeile',
'free' => 'Kostenlos',
'quote_is_approved' => 'The quote has been approved',
'quote_is_approved' => 'Dem Angebot wurde zugestimmt',
'apply_credit' => 'Guthaben anwenden',
'system_settings' => 'Systemeinstellungen',
'archive_token' => 'Token archivieren',
@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'Dunkel',
'industry_help' => 'Wird genutzt um Vergleiche zwischen den Durchschnittswerten von Firmen ähnlicher Größe und Branche ermitteln zu können.',
'subdomain_help' => 'Passen Sie die Rechnungslink-Subdomäne an oder stellen Sie die Rechnung auf Ihrer eigenen Webseite zur Verfügung.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Geben Sie einen Präfix oder ein benutzerdefiniertes Schema an, um die Rechnungsnummer dynamisch zu erzeugen.',
'quote_number_help' => 'Geben Sie einen Präfix oder ein benutzerdefiniertes Schema an, um die Angebotsnummer dynamisch zu erzeugen.',
'custom_client_fields_helps' => 'Füge ein Feld hinzu, wenn ein neuer Kunde erstellt wird und zeige die Bezeichnung und den Wert auf der PDF-Datei an.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Rechnungsbetrag',
'invoice_item_fields' => 'Rechnungspositionsfeld',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Wiederkehrende Rechnungsnummer',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Geben Sie einen Präfix für wiederkehrende Rechnungen an. Standard ist \'R\'.',
// Client Passwords
@ -2324,7 +2325,7 @@ Sobald Sie die Beträge erhalten haben, kommen Sie bitte wieder zurück zu diese
'sort_by' => 'Sortiere nach',
'draft' => 'Entwurf',
'unpaid' => 'Unbezahlt',
'aging' => 'Altern',
'aging' => 'Versendet',
'age' => 'Alter',
'days' => 'Tage',
'age_group_0' => '0 - 30 Tage',
@ -2398,28 +2399,28 @@ Sobald Sie die Beträge erhalten haben, kommen Sie bitte wieder zurück zu diese
'mark_ready' => 'Mark Ready',
'limits' => 'Limits',
'fees' => 'Fees',
'fee' => 'Fee',
'fees' => 'Gebühren',
'fee' => 'Gebühr',
'set_limits_fees' => 'Set :gateway_type Limits/Fees',
'fees_tax_help' => 'Enable line item taxes to set the fee tax rates.',
'fees_sample' => 'The fee for a :amount invoice would be :total.',
'discount_sample' => 'The discount for a :amount invoice would be :total.',
'no_fees' => 'No Fees',
'no_fees' => 'Keine Gebühren',
'gateway_fees_disclaimer' => 'Warning: not all states/payment gateways allow adding fees, please review local laws/terms of service.',
'percent' => 'Percent',
'location' => 'Location',
'percent' => 'Prozent',
'location' => 'Ort',
'line_item' => 'Line Item',
'surcharge' => 'Surcharge',
'surcharge' => 'Gebühr',
'location_first_surcharge' => 'Enabled - First surcharge',
'location_second_surcharge' => 'Enabled - Second surcharge',
'location_line_item' => 'Enabled - Line item',
'online_payment_surcharge' => 'Online Payment Surcharge',
'gateway_fees' => 'Gateway Fees',
'fees_disabled' => 'Fees are disabled',
'fees_disabled' => 'Gebühren sind deaktiviert',
'gateway_fees_help' => 'Automatically add an online payment surcharge/discount.',
'gateway' => 'Gateway',
'gateway_fee_change_warning' => 'If there are unpaid invoices with fees they need to be updated manually.',
'fees_surcharge_help' => 'Customize surcharge :link.',
'fees_surcharge_help' => 'Gebühren anpassen :link.',
'label_and_taxes' => 'label and taxes',
'billable' => 'Billable',
'logo_warning_too_large' => 'The image file is too large.',
@ -2428,41 +2429,47 @@ Sobald Sie die Beträge erhalten haben, kommen Sie bitte wieder zurück zu diese
'error_refresh_page' => 'An error occurred, please refresh the page and try again.',
'data' => 'Data',
'imported_settings' => 'Successfully imported settings',
'lang_Greek' => 'Greek',
'imported_settings' => 'Einstellungen erfolgreich aktualisiert',
'lang_Greek' => 'Griechisch',
'reset_counter' => 'Reset Counter',
'next_reset' => 'Next Reset',
'reset_counter_help' => 'Automatically reset the invoice and quote counters.',
'auto_bill_failed' => 'Auto-billing for invoice :invoice_number failed',
'online_payment_discount' => 'Online Payment Discount',
'created_new_company' => 'Successfully created new company',
'fees_disabled_for_gateway' => 'Fees are disabled for this gateway.',
'logout_and_delete' => 'Log Out/Delete Account',
'online_payment_discount' => 'Online-Zahlungsrabatt',
'created_new_company' => 'Neues Unternehmen erfolgreich erstellt',
'fees_disabled_for_gateway' => 'Gebühren sind für diesen Gateway deaktiviert.',
'logout_and_delete' => 'Ausloggen/Konto löschen',
'tax_rate_type_help' => 'Inclusive taxes adjust the line item cost when selected.',
'invoice_footer_help' => 'Use $pageNumber and $pageCount to display the page information.',
'invoice_footer_help' => 'Verwende $pageNumber und $pageCount um Seiteninformationen anzuzeigen.',
'credit_note' => 'Credit Note',
'credit_issued_to' => 'Credit issued to',
'credit_to' => 'Credit to',
'your_credit' => 'Your Credit',
'credit_number' => 'Credit Number',
'create_credit_note' => 'Create Credit Note',
'menu' => 'Menu',
'menu' => 'Menü',
'error_incorrect_gateway_ids' => 'Error: The gateways table has incorrect ids.',
'purge_data' => 'Purge Data',
'delete_data' => 'Delete Data',
'purge_data_help' => 'Permanently delete all data in the account, keeping the account and settings.',
'cancel_account_help' => 'Permanently delete the account along with all data and setting.',
'purge_successful' => 'Successfully purged account data',
'forbidden' => 'Forbidden',
'purge_data' => 'Daten säubern',
'delete_data' => 'Daten löschen',
'purge_data_help' => 'Lösche unwiederbringlich alle Daten des Kontos, wobei das Konto und die Einstellungen erhalten bleiben.',
'cancel_account_help' => 'Lösche unwiederbringlich das Konto, mitsamt aller Daten und Einstellungen.',
'purge_successful' => 'Erfolgreich Kontodaten gelöscht',
'forbidden' => 'Verboten',
'purge_data_message' => 'Warning: This will permanently erase your data, there is no undo.',
'contact_phone' => 'Contact Phone',
'contact_email' => 'Contact Email',
'reply_to_email' => 'Reply-To Email',
'reply_to_email_help' => 'Specify the reply-to address for client emails.',
'bcc_email_help' => 'Privately include this address with client emails.',
'import_complete' => 'Your import has successfully completed.',
'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.',
'contact_phone' => 'Telefonnummer des Kontakts',
'contact_email' => 'E-Mail-Adresse des Kontakts',
'reply_to_email' => 'Antwort-E-Mail-Adresse',
'reply_to_email_help' => 'Gib die Antwort-E-Mail-Adresse an, die für den Kundenkontakt genutzt werden soll.',
'bcc_email_help' => 'Sende unsichtbar zusätzlich alle ausgehenden E-Mails an die hier angegebene Adresse.',
'import_complete' => 'Ihr Import wurde erfolgreich abgeschlossen.',
'confirm_account_to_import' => 'Bitte bestätigen Sie Ihr Konto um Daten zu importieren.',
'import_started' => 'Ihr Import wurde gestartet, wir senden Ihnen eine E-Mail zu, sobald er abgeschlossen wurde.',
'listening' => 'Listening...',
'microphone_help' => 'Say \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -369,7 +369,7 @@ email που είναι συνδεδεμένη με το λογαριασμό σ
'confirm_email_quote' => 'Είστε σίγουροι ότι θέλετε να αποστείλετε αυτή την προσφορά;',
'confirm_recurring_email_invoice' => 'Είστε σίγουροι ότι θέλετε να αποστέλλεται αυτό το παραστατικό;',
'cancel_account' => 'Διαγραφή Λογαριασμού',
'cancel_account_message' => 'Warning: This will permanently delete your account, there is no undo.',
'cancel_account_message' => 'Προσοχή: Αυτό θα σβήσει το λογαριασμό σας, χωρίς δυνατότητα αναίρεσης.',
'go_back' => 'Επιστροφή',
'data_visualizations' => 'Απεικονίσεις Δεδομένων',
'sample_data' => 'Εμφάνιση δείγματος δεδομένων',
@ -732,7 +732,7 @@ email που είναι συνδεδεμένη με το λογαριασμό σ
'recurring_hour' => 'Επαναλαμβανόμενη Ώρα',
'pattern' => 'Μοτίβο',
'pattern_help_title' => 'Βοήθεια Μοτίβων',
'pattern_help_1' => 'Create custom numbers by specifying a pattern',
'pattern_help_1' => 'Δημιουργείστε προσαρμοσμένους αριθμούς καθορίζοντας ένα πρότυπο',
'pattern_help_2' => 'Διαθέσιμες μεταβλητές:',
'pattern_help_3' => 'Για παράδειγμα, το :example θα μετατραπεί σε :value',
'see_options' => 'Προβολή επιλογών',
@ -851,6 +851,7 @@ email που είναι συνδεδεμένη με το λογαριασμό σ
'dark' => 'Σκούρο',
'industry_help' => 'Χρησιμοποιείται για να παρέχει συγκρίσεις μέσων όρων εταιριών ίδιου μεγέθους στους ίδιους επαγγελματικούς τομείς.',
'subdomain_help' => 'Ορίστε τον υποτομέα ή εμφάνιστε το τιμολόγιο στη δική σας ιστοσελίδα',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Ορίστε ένα πρόθεμα ή χρησιμοποιήστε ένα προσαρμοσμένο μοτίβο για να καθορίζετε δυναμικά τον αριθμό τιμολογίου.',
'quote_number_help' => 'Ορίστε ένα πρόθεμα ή χρησιμοποιήστε ένα προσαρμοσμένο μοτίβο για να καθορίζετε δυναμικά τον αριθμό προσφοράς.',
'custom_client_fields_helps' => 'Προσθέστε ένα πεδίο όταν δημιουργείτε ένα πελάτη και εμφανίστε την ετικέτα και την τιμή στο αρχείο PDF.',
@ -1041,7 +1042,7 @@ email που είναι συνδεδεμένη με το λογαριασμό σ
'invoiced_amount' => 'Τιμολογημένο Ποσό',
'invoice_item_fields' => 'Πεδία Προϊόντων Τιμολογίου',
'custom_invoice_item_fields_help' => 'Προσθέστε ένα πεδίο όταν δημιουργείτε ένα προϊόν τιμολογίου και εμφανίστε την ετικέτα και την τιμή στο αρχείο PDF.',
'recurring_invoice_number' => 'Αριθμός Επαναλαμβανόμενου Τιμολογίου',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Ορίστε ένα πρόθεμα που να περιλαμβάνεται στον αριθμό τιμολογίου των επαναλαμβανόμενων τιμολογίων. Η εξ\'ορισμού τιμή είναι \'R\'.',
// Client Passwords
@ -2448,21 +2449,27 @@ email που είναι συνδεδεμένη με το λογαριασμό σ
'create_credit_note' => 'Δημιουργία Πιστωτικού Σημειώματος',
'menu' => 'Μενού',
'error_incorrect_gateway_ids' => 'Σφάλμα: Ο πίνακας των πυλών (gateways) έχει λάθος αριθμούς.',
'purge_data' => 'Purge Data',
'delete_data' => 'Delete Data',
'purge_data_help' => 'Permanently delete all data in the account, keeping the account and settings.',
'cancel_account_help' => 'Permanently delete the account along with all data and setting.',
'purge_successful' => 'Successfully purged account data',
'forbidden' => 'Forbidden',
'purge_data_message' => 'Warning: This will permanently erase your data, there is no undo.',
'contact_phone' => 'Contact Phone',
'contact_email' => 'Contact Email',
'reply_to_email' => 'Reply-To Email',
'reply_to_email_help' => 'Specify the reply-to address for client emails.',
'bcc_email_help' => 'Privately include this address with client emails.',
'import_complete' => 'Your import has successfully completed.',
'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.',
'purge_data' => 'Εκκαθάριση Δεδομένων',
'delete_data' => 'Διαγραφή Δεδομένων',
'purge_data_help' => 'Οριστική διαγραφή όλων των δεδομένων στο λογαριασμό, κρατώντας μόνο το λογαριασμό και τις ρυθμίσεις.',
'cancel_account_help' => 'Οριστική διαγραφή του λογαριασμού με όλα τα δεδομένα και τις ρυθμίσεις.',
'purge_successful' => 'Επιτυχής εκκαθάριση δεδομένων λογαριασμού',
'forbidden' => 'Απαγορευμένο',
'purge_data_message' => 'Προσοχή: Αυτό θα σβήσει όλα σας τα δεδομένα, χωρίς δυνατότητα αναίρεσης.',
'contact_phone' => 'Τηλέφωνο Επικοινωνίας',
'contact_email' => 'Email Επικοινωνίας',
'reply_to_email' => 'Email Απάντησης',
'reply_to_email_help' => 'Ορίστε τη διεύθυνση απάντησης για τα emails που απευθύνονται στους πελάτες.',
'bcc_email_help' => 'Ορίστε τη διεύθυνση κρυφής αποστολής για τα emails που απευθύνονται στους πελάτες.',
'import_complete' => 'Επιτυχής ολοκλήρωση της εισαγωγής',
'confirm_account_to_import' => 'Παρακαλώ επιβεβαιώστε το λογαριασμό σας για εισαγωγή δεδομένων',
'import_started' => 'Η εισαγωγή δεδομένων ξεκίνησε, θα σας αποσταλεί email με την ολοκλήρωση.',
'listening' => 'Listening...',
'microphone_help' => 'Say \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'Dark',
'industry_help' => 'Used to provide comparisons against the averages of companies of similar size and industry.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a field when creating a client and display the label and value on the PDF.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2463,6 +2464,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -845,6 +845,7 @@ $LANG = array(
'dark' => 'Oscuro',
'industry_help' => 'Usado para proporcionar comparaciones de las medias de las empresas de tamaño y industria similar.',
'subdomain_help' => 'Asigne el suubdominio o mostrar la factura en su propio sitio web.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Especifique un prefijo o utilice un patrón a medida para establecer dinámicamente el número de factura.',
'quote_number_help' => 'Especifique un prefijo o utilice un patrón a medida para establecer dinámicamente el número de presupuesto.',
'custom_client_fields_helps' => 'Agregar una entrada de texto a la pagina de crear/editar cliente y mostrar la etiqueta y el valor en el PDF.',
@ -1034,7 +1035,7 @@ $LANG = array(
'invoiced_amount' => 'Importe Facturado',
'invoice_item_fields' => 'Campos de Ítem de Factura',
'custom_invoice_item_fields_help' => 'Agregar un campo al crear un ítem de factura y mostrar la etiqueta y valor en el PDF.',
'recurring_invoice_number' => 'Número de Factura Recurrente',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Especificar un prefijo para las facturas recurrentes. Por defecto es \'R\'.',
// Client Passwords
@ -2456,6 +2457,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -846,6 +846,7 @@ Acceder a 10 hermosos diseños de Factura',
'dark' => 'Oscuro',
'industry_help' => 'Usado para proporcionar comparaciones de las medias de empresas de sectores y tamaño similares.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Especifique un prefijo o utilice un patrón a medida para establecer dinámicamente el número de factura.',
'quote_number_help' => 'Especifique un prefijo o utilice un patrón a medida para establecer dinámicamente el número de presupuesto.',
'custom_client_fields_helps' => 'Añadir un campo al crear un cliente y mostrar la etiqueta y su valor en el PDF.',
@ -1037,7 +1038,7 @@ Atención! tu password puede estar transmitida como texto plano, considera habil
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Campos de concepto de factura',
'custom_invoice_item_fields_help' => 'Añadir un campo al crear un concepto de factura y mostrar la etiqueta y su valor en el PDF.',
'recurring_invoice_number' => 'Número de factura recurrente',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Especifique un prefijo que se antepondrá al número de factura sólo para las facturas recurrentes. El valor predeterminado es \'R\'.',
// Client Passwords
@ -2459,6 +2460,12 @@ Atención! tu password puede estar transmitida como texto plano, considera habil
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -845,6 +845,7 @@ Si vous avez besoin d\'aide à ce sujet, vous pouvez publier une question sur no
'dark' => 'Sombre',
'industry_help' => 'Utilisé dans le but de fournir des statistiques la taille et le secteur de l\'entreprise.',
'subdomain_help' => 'Définissez un sous-domaine ou affichez la facture sur votre propre site web.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a text input to the client create/edit page and display the label and value on the PDF.',
@ -1035,7 +1036,7 @@ Si vous avez besoin d\'aide à ce sujet, vous pouvez publier une question sur no
'invoiced_amount' => 'Montant de la facture',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Numéros de Factures Récurrentes',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2457,6 +2458,12 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -845,6 +845,7 @@ $LANG = array(
'dark' => 'Foncé',
'industry_help' => 'Pour des fins de comparaison entre des entreprises de même taille et du même secteur d\'activité.',
'subdomain_help' => 'Définissez le sous-domaine ou affichez la facture sur votre site web.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Spécifiez un préfixe ou utilisez un modèle personnalisé pour la création du numéro de facture.',
'quote_number_help' => 'Spécifiez un préfixe ou utilisez un modèle personnalisé pour la création du numéro de soumission.',
'custom_client_fields_helps' => 'Ajoutez un champ personnalisé à la page de création/édition de client et affichez le titre et la valeur dans le fichier PDF.',
@ -1032,7 +1033,7 @@ $LANG = array(
'invoiced_amount' => 'Montant facturé',
'invoice_item_fields' => 'Champs d\'items de facture',
'custom_invoice_item_fields_help' => 'Ajoutez un champ lors de la création d\'une facture pour afficher le libellé et la valeur du champ sur le PDF.',
'recurring_invoice_number' => 'Numéro de facture récurrente',
'recurring_invoice_number' => 'Numéro récurrent',
'recurring_invoice_number_prefix_help' => 'Spécifiez un préfixe qui sera ajouté au numéro de la facture récurrente. La valeur par défaut est \'R\'.',
// Client Passwords
@ -2452,9 +2453,15 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
'reply_to_email' => 'Courriel de réponse',
'reply_to_email_help' => 'Spécifie une adresse courriel de réponse',
'bcc_email_help' => 'Inclut de façon privée cette adresse avec les courriels du client.',
'import_complete' => 'Your import has successfully completed.',
'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.',
'import_complete' => 'L\'importation est réussie.',
'confirm_account_to_import' => 'Veuillez confirmer votre compte pour l\'importation des données.',
'import_started' => 'L\'importation est en cours. Vous recevrez un courriel lorsqu\'elle sera complétée.',
'listening' => 'En écoute...',
'microphone_help' => 'Dites \'Nouvelle facture pour...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'Tamno',
'industry_help' => 'Koristi se za usporedbe između prosjeka poduzeća sličnih veličina i djelatnosti.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Odredite prefiks ili koristite prilagođeni uzorak za dinamično postavljanje brojeva računa.',
'quote_number_help' => 'Odredite prefiks ili koristite prilagođeni uzorak za dinamično postavljanje brojeva ponuda.',
'custom_client_fields_helps' => 'Add a field when creating a client and display the label and value on the PDF.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2463,6 +2464,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -845,6 +845,7 @@ $LANG = array(
'dark' => 'Dark',
'industry_help' => 'Used to provide comparisons against the averages of companies of similar size and industry.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a text input to the client create/edit page and display the label and value on the PDF.',
@ -1035,7 +1036,7 @@ $LANG = array(
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2456,6 +2457,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'ダーク',
'industry_help' => 'Used to provide comparisons against the averages of companies of similar size and industry.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a field when creating a client and display the label and value on the PDF.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2463,6 +2464,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'Dark',
'industry_help' => 'Used to provide comparisons against the averages of companies of similar size and industry.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a text input to the client create/edit page and display the label and value on the PDF.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2463,6 +2464,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'Dark',
'industry_help' => 'Used to provide comparisons against the averages of companies of similar size and industry.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a text input to the client create/edit page and display the label and value on the PDF.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2463,6 +2464,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -845,6 +845,7 @@ $LANG = array(
'dark' => 'Donker',
'industry_help' => 'Wordt gebruikt om een vergelijking te kunnen maken met de gemiddelden van andere bedrijven uit dezelfde sector en van dezelfde grootte.',
'subdomain_help' => 'Stel het subdomein in of toon het factuur op uw eigen website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Kies een voorvoegsel of gebruik een patroon om het factuurnummer dynamisch te genereren.',
'quote_number_help' => 'Kies een voorvoegsel of gebruik een patroon om het offertenummer dynamisch te genereren.',
'custom_client_fields_helps' => 'Plaatst een tekstveld op de klanten aanmaak-/bewerkpagina en toont het gekozen label op de PDF.',
@ -1032,7 +1033,7 @@ $LANG = array(
'invoiced_amount' => 'Gefactureerd bedrag',
'invoice_item_fields' => 'Factuurregels',
'custom_invoice_item_fields_help' => 'Voeg een veld toe bij het aanmaken van een factuurregel en toon het label met de waarde op de PDF.',
'recurring_invoice_number' => 'Nummer terugkerende factuur',
'recurring_invoice_number' => 'Terugkerend nummer',
'recurring_invoice_number_prefix_help' => 'Kies een voorvoegsel voor het factuurnummer van terugkerende facturen. De standaard is: \'R\'.',
// Client Passwords
@ -2452,9 +2453,15 @@ Kom terug naar deze betalingsmethode pagina zodra u de bedragen heeft ontvangen
'reply_to_email' => 'Antwoord naar e-mail',
'reply_to_email_help' => 'Geef het antwoord-aan adres voor klant e-mails.',
'bcc_email_help' => 'Dit adres heimelijk gebruiken met klant e-mails.',
'import_complete' => 'Your import has successfully completed.',
'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.',
'import_complete' => 'Het importeren is succesvol uitgevoerd.',
'confirm_account_to_import' => 'Gelieve uw account te bevestigen om de gegevens te importeren.',
'import_started' => 'Het importeren is gestart, we sturen u een e-mail van zodra het proces afgerond is.',
'listening' => 'Luisteren...',
'microphone_help' => 'Zeg \'nieuw factuur voor...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'Ciemny',
'industry_help' => 'Informacje używane w celach porównawczych przy obliczaniu statystyk firm podobnych rozmiarów i branż.',
'subdomain_help' => 'Ustaw subdomenę lub wyświetl fakturę na swojej stronie.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a field when creating a client and display the label and value on the PDF.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Fakturowana kwota',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Numer faktury okresowej',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Dodaj własny prefix do numeru faktury okresowej. Wartość domyślna to \'R\'.',
// Client Passwords
@ -2463,6 +2464,12 @@ Gdy przelewy zostaną zaksięgowane na Twoim koncie, wróć do tej strony i klik
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -845,6 +845,7 @@ $LANG = array(
'dark' => 'Escuro',
'industry_help' => 'Usado para fornecer comparações contra as médias das empresas de tamanho e indústria similar.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Especifique um prefixo ou usar um padrão personalizado para definir dinamicamente o número da fatura.',
'quote_number_help' => 'Especifique um prefixo ou usar um padrão personalizado para definir dinamicamente o número do orçamento.',
'custom_client_fields_helps' => 'Adicionar uma entrada de texto na página Criar/Editar Cliente e exibir no PDF.',
@ -1032,7 +1033,7 @@ $LANG = array(
'invoiced_amount' => 'Total Faturado',
'invoice_item_fields' => 'Campos de Ítens da Fatura',
'custom_invoice_item_fields_help' => 'Adicionar um campo ao adicionar um ítem na fatura e exibir no PDF.',
'recurring_invoice_number' => 'Número da Fatura Recorrente',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Informe um prefixo para a numeração das faturas recorrentes. O valor padrão é \'R\'.',
// Client Passwords
@ -2454,6 +2455,12 @@ Quando tiver os valores dos depósitos, volte a esta pagina e complete a verific
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -848,6 +848,7 @@ $LANG = array(
'dark' => 'E mbylltë',
'industry_help' => 'Përdoret për të realizuar krahasime ndaj kompanive mesatere me numër puntorësh të ngjashëm.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Caktoni një prefiks ose ndonjë shabllon të caktuar për të dinamizuar numrin e faturave.',
'quote_number_help' => 'Caktoni një prefiks ose ndonjë shabllon të caktuar për të dinamizuar numrin e ofertave.',
'custom_client_fields_helps' => 'Shtoni një fushë ë kur të zgjedhni klientin të shfaqet vlera në PDF.',
@ -1039,7 +1040,7 @@ $LANG = array(
'invoice_item_fields' => '
Fushat e njësive faturë',
'custom_invoice_item_fields_help' => 'Shtoni një fushë ë kur të krijoni faturë dhe etiketa me vlerë të shfaqen në PDF.',
'recurring_invoice_number' => 'Numri i faturës së përsëritshme',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Cakto një prefiks që i shtohet numrit të faturave të përsëritshme. Vlera e paracaktuar është "R".',
// Client Passwords
@ -2461,6 +2462,12 @@ Pasi të keni pranuar shumat, kthehuni në faqen e metodave të pagesës dhe kli
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -850,6 +850,7 @@ $LANG = array(
'dark' => 'Mörk',
'industry_help' => 'Används för att ge jämförelser mot genomsnitten för företag med liknande storlek och bransch.',
'subdomain_help' => 'Ställ in subdomänen eller visa fakturorna på din egen hemsida',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specifiera ett prefix eller anpassat mönster för att dynamiskt sätta fakturanummer.',
'quote_number_help' => 'Specifiera ett prefix eller använd ett anpassat mönster för att dynamiskt sätta offert nummer.',
'custom_client_fields_helps' => 'Lägga till ett fält när du skapar en klient och visa etiketten och värdet på PDF.',
@ -1040,7 +1041,7 @@ $LANG = array(
'invoiced_amount' => 'Fakturerad summa',
'invoice_item_fields' => 'Fakturerat varu belopp',
'custom_invoice_item_fields_help' => 'Lägg till ett fält när fakturan skapas och visa namn samt värde på PDF´n',
'recurring_invoice_number' => 'Återkommande faktura nummer',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Specificera ett prefix att lägga till på återkommande fakturor. Standard värde är \'R\'',
// Client Passwords
@ -2476,6 +2477,12 @@ Den här funktionen kräver att en produkt skapas och en betalningsgateway är k
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -851,6 +851,7 @@ $LANG = array(
'dark' => 'Dark',
'industry_help' => 'Used to provide comparisons against the averages of companies of similar size and industry.',
'subdomain_help' => 'Set the subdomain or display the invoice on your own website.',
'website_help' => 'Display the invoice in an iFrame on your own website',
'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.',
'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.',
'custom_client_fields_helps' => 'Add a field when creating a client and display the label and value on the PDF.',
@ -1041,7 +1042,7 @@ $LANG = array(
'invoiced_amount' => 'Invoiced Amount',
'invoice_item_fields' => 'Invoice Item Fields',
'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.',
'recurring_invoice_number' => 'Recurring Invoice Number',
'recurring_invoice_number' => 'Recurring Number',
'recurring_invoice_number_prefix_help' => 'Speciy a prefix to be added to the invoice number for recurring invoices. The default value is \'R\'.',
// Client Passwords
@ -2463,6 +2464,12 @@ $LANG = array(
'import_complete' => 'Your import has successfully completed.',
'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 \'new invoice for...\'',
'voice_commands' => 'Voice Commands',
'sample_commands' => 'Sample commands',
'voice_commands_feedback' => 'We\'re actively working to improve this feature, if there\'s a command you\'d like us to support please email us at :email.',
'payment_type_Venmo' => 'Venmo',
);

View File

@ -51,12 +51,10 @@
<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist" style="border: none">
@if (Utils::isNinja())
<li role="presentation" class="active">
<a href="#link" aria-controls="link" role="tab" data-toggle="tab">{{ trans('texts.link') }}</a>
</li>
@endif
<li role="presentation" {{ Utils::isNinja() ? '' : 'class="active"' }}>
<li role="presentation" class="active">
<a href="#link" aria-controls="link" role="tab" data-toggle="tab">{{ trans('texts.link') }}</a>
</li>
<li role="presentation">
<a href="#navigation" aria-controls="navigation" role="tab" data-toggle="tab">{{ trans('texts.navigation') }}</a>
</li>
<li role="presentation">
@ -66,11 +64,10 @@
</div>
<div class="tab-content">
@if (Utils::isNinja())
<div role="tabpanel" class="tab-pane active" id="link">
<div class="panel-body">
@if (! Utils::isReseller())
@if (Utils::isNinja() && ! Utils::isReseller())
{!! Former::inline_radios('domain_id')
->label(trans('texts.domain'))
->radios([
@ -80,36 +77,38 @@
->help($account->iframe_url ? 'domain_help_website' : 'domain_help') !!}
@endif
{!! Former::inline_radios('custom_invoice_link')
->onchange('onCustomLinkChange()')
->label(trans('texts.customize'))
->radios([
trans('texts.subdomain') => ['value' => 'subdomain', 'name' => 'custom_link'],
trans('texts.website') => ['value' => 'website', 'name' => 'custom_link'],
])->check($account->iframe_url ? 'website' : 'subdomain') !!}
{{ Former::setOption('capitalize_translations', false) }}
@if (Utils::isNinja())
{!! Former::text('subdomain')
->placeholder(Utils::isNinja() ? 'app' : trans('texts.www'))
->onchange('onSubdomainChange()')
->addGroupClass('subdomain')
->label(' ')
->help(trans('texts.subdomain_help')) !!}
{!! Former::inline_radios('custom_invoice_link')
->onchange('onCustomLinkChange()')
->label(trans('texts.customize'))
->radios([
trans('texts.subdomain') => ['value' => 'subdomain', 'name' => 'custom_link'],
trans('texts.website') => ['value' => 'website', 'name' => 'custom_link'],
])->check($account->iframe_url ? 'website' : 'subdomain') !!}
{{ Former::setOption('capitalize_translations', false) }}
{!! Former::text('subdomain')
->placeholder(Utils::isNinja() ? 'app' : trans('texts.www'))
->onchange('onSubdomainChange()')
->addGroupClass('subdomain')
->label(' ')
->help(trans('texts.subdomain_help')) !!}
@endif
{!! Former::text('iframe_url')
->placeholder('https://www.example.com/invoice')
->appendIcon('question-sign')
->addGroupClass('iframe_url')
->label(' ')
->help(trans('texts.subdomain_help')) !!}
->label(Utils::isNinja() ? ' ' : trans('texts.website'))
->help(trans(Utils::isNinja() ? 'texts.subdomain_help' : 'texts.website_help')) !!}
{!! Former::plaintext('preview')
->value($account->getSampleLink()) !!}
</div>
</div>
@endif
<div role="tabpanel" class="tab-pane {{ Utils::isNinja() ? '' : 'active' }}" id="navigation">
<div role="tabpanel" class="tab-pane" id="navigation">
<div class="panel-body">
{!! Former::checkbox('enable_client_portal')

View File

@ -309,12 +309,15 @@
</div>
<form id="search-form" class="navbar-form navbar-right" role="search">
<div class="form-group">
<input type="text" id="search" style="width: 240px;padding-top:0px;padding-bottom:0px"
class="form-control" placeholder="{{ trans('texts.search') . ': ' . trans('texts.search_hotkey')}}">
{!! Former::open('/handle_command')->id('search-form')->addClass('navbar-form navbar-right')->role('search') !!}
<div class="form-group has-feedback">
<input type="text" name="command" id="search" style="width: 240px;padding-top:0px;padding-bottom:0px;margin-right:12px;"
class="form-control" placeholder="{{ trans('texts.search') . ': ' . trans('texts.search_hotkey')}}"/>
@if (env('SPEECH_ENABLED'))
@include('partials/speech_recognition')
@endif
</div>
</form>
{!! Former::close() !!}
@if (false && Utils::isAdmin())
<ul class="nav navbar-nav navbar-right">
@ -394,7 +397,7 @@
<a href="{{ url(NINJA_FORUM_URL) }}" target="_blank" title="{{ trans('texts.support_forum') }}">
<i class="fa fa-list-ul"></i>
</a>
<a href="javascript:showKeyboardShortcuts()" target="_blank" title="{{ trans('texts.keyboard_shortcuts') }}">
<a href="javascript:showKeyboardShortcuts()" target="_blank" title="{{ trans('texts.help') }}">
<i class="fa fa-question-circle"></i>
</a>
<a href="{{ url(SOCIAL_LINK_FACEBOOK) }}" target="_blank" title="Facebook">

View File

@ -35,6 +35,16 @@ function ViewModel(data) {
@endif
}
self.clearBlankContacts = function() {
var client = self.invoice().client();
var contacts = client.contacts();
$(contacts).each(function(index, contact) {
if (index > 0 && contact.isBlank()) {
client.contacts.remove(contact);
}
});
}
self.invoice_taxes = ko.observable({{ Auth::user()->account->invoice_taxes ? 'true' : 'false' }});
self.invoice_item_taxes = ko.observable({{ Auth::user()->account->invoice_item_taxes ? 'true' : 'false' }});
self.show_item_taxes = ko.observable({{ Auth::user()->account->show_item_taxes ? 'true' : 'false' }});
@ -115,6 +125,8 @@ function ViewModel(data) {
}
model.setDueDate();
model.clearBlankContacts();
setComboboxValue($('.client_select'), -1, name);
var client = $.parseJSON(ko.toJSON(self.invoice().client()));
@ -638,6 +650,10 @@ function ContactModel(data) {
ko.mapping.fromJS(data, {}, this);
}
self.isBlank = ko.computed(function() {
return ! self.first_name() && ! self.last_name() && ! self.email() && ! self.phone();
});
self.displayName = ko.computed(function() {
var str = '';
if (self.first_name() || self.last_name()) {

View File

@ -29,52 +29,95 @@
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="myModalLabel">{{ trans('texts.keyboard_shortcuts') }}</h4>
<h4 class="modal-title" id="myModalLabel">{{ trans('texts.help') }}</h4>
</div>
<div class="container" style="width: 100%; padding-bottom: 0px !important">
<div class="panel panel-default">
<div class="panel-body help-panel">
<div class="row">
<div class="col-md-3"><div>?</div></div>
<div class="col-md-3 key-label">{{ trans('texts.help') }}</div>
<div class="col-md-3"><div>N</div><div>C</div></div>
<div class="col-md-3 key-label">{{ trans('texts.new_client') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>/</div></div>
<div class="col-md-3 key-label">{{ trans('texts.search') }}</div>
<div class="col-md-3"><div>N</div><div>I</div></div>
<div class="col-md-3 key-label">{{ trans('texts.new_invoice') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>M</div></div>
<div class="col-md-3 key-label">{{ trans('texts.menu') }}</div>
<div class="col-md-3"><div>N</div><div>...</div></div>
<div class="col-md-3 key-label">{{ trans('texts.new_...') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>H</div></div>
<div class="col-md-3 key-label">{{ trans('texts.history') }}</div>
</div>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"><div>L</div><div>C</div></div>
<div class="col-md-3 key-label">{{ trans('texts.list_clients') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>G</div><div>D</div></div>
<div class="col-md-3 key-label">{{ trans('texts.dashboard') }}</div>
<div class="col-md-3"><div>L</div><div>I</div></div>
<div class="col-md-3 key-label">{{ trans('texts.list_invoices') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>G</div><div>S</div></div>
<div class="col-md-3 key-label">{{ trans('texts.settings') }}</div>
<div class="col-md-3"><div>L</div><div>...</div></div>
<div class="col-md-3 key-label">{{ trans('texts.list_...') }}</div>
@if (Utils::isNinja() && Utils::isPro())
<div role="tabpanel">
<ul class="nav nav-tabs" role="tablist" style="border: none">
<li role="presentation" class="active">
<a href="#keyboard_shortcuts" aria-controls="keyboard_shortcuts" role="tab" data-toggle="tab">{{ trans('texts.keyboard_shortcuts') }}</a>
</li>
<li role="presentation">
<a href="#voice_commands" aria-controls="voice_commands" role="tab" data-toggle="tab">{{ trans('texts.voice_commands') }}</a>
</li>
</ul>
</div>
</br>
@endif
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="keyboard_shortcuts">
<div class="row">
<div class="col-md-3"><div>?</div></div>
<div class="col-md-3 key-label">{{ trans('texts.help') }}</div>
<div class="col-md-3"><div>N</div><div>C</div></div>
<div class="col-md-3 key-label">{{ trans('texts.new_client') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>/</div></div>
<div class="col-md-3 key-label">{{ trans('texts.search') }}</div>
<div class="col-md-3"><div>N</div><div>I</div></div>
<div class="col-md-3 key-label">{{ trans('texts.new_invoice') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>M</div></div>
<div class="col-md-3 key-label">{{ trans('texts.menu') }}</div>
<div class="col-md-3"><div>N</div><div>...</div></div>
<div class="col-md-3 key-label">{{ trans('texts.new_...') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>H</div></div>
<div class="col-md-3 key-label">{{ trans('texts.history') }}</div>
</div>
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"><div>L</div><div>C</div></div>
<div class="col-md-3 key-label">{{ trans('texts.list_clients') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>G</div><div>D</div></div>
<div class="col-md-3 key-label">{{ trans('texts.dashboard') }}</div>
<div class="col-md-3"><div>L</div><div>I</div></div>
<div class="col-md-3 key-label">{{ trans('texts.list_invoices') }}</div>
</div>
<div class="row">
<div class="col-md-3"><div>G</div><div>S</div></div>
<div class="col-md-3 key-label">{{ trans('texts.settings') }}</div>
<div class="col-md-3"><div>L</div><div>...</div></div>
<div class="col-md-3 key-label">{{ trans('texts.list_...') }}</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="voice_commands">
<div class="row">
<p>
{{ trans('texts.sample_commands') }}:
</p>
<p>
<ul>
<li>Go to the dashboard</li>
<li>List active and deleted tasks</li>
<li>Find &lt;client name&gt;</li>
<li>Show me &lt;client name&gt;'s overdue invoices</li>
<li>New invoice for &lt;client name&gt;</li>
<li>Create payment for invoice &lt;invoice number&gt;</li>
</ul>
</p>
<p>
{!! trans('texts.voice_commands_feedback', ['email' => HTML::mailto(CONTACT_EMAIL)]) !!}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
@ -132,6 +175,12 @@
$('#left-menu-toggle').trigger('click');
});
@if (Utils::isNinja())
Mousetrap.bind('r', function(e) {
onMicrophoneClick();
});
@endif
@foreach([
'i' => ENTITY_INVOICE,
'p' => ENTITY_PAYMENT,

View File

@ -228,7 +228,7 @@
{{ Former::setOption('TwitterBootstrap3.labelWidths.small', 4) }}
</div>
<center><div id="errorTaken" style="display:none">&nbsp;<br/><b>{{ trans('texts.email_taken') }}<b></div></center>
<center><div id="errorTaken" style="display:none">&nbsp;<br/><b>{{ trans('texts.email_taken') }}</b></div></center>
<div class="col-md-12">
@if (Auth::user()->registered)

View File

@ -0,0 +1,182 @@
<i id="microphone" class="fa fa-microphone form-control-feedback"
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;
}
#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
var langs =
[['Afrikaans', ['af-ZA']],
['Bahasa Indonesia',['id-ID']],
['Bahasa Melayu', ['ms-MY']],
['Català', ['ca-ES']],
['Čeština', ['cs-CZ']],
['Dansk', ['da-DK']],
['Deutsch', ['de-DE']],
['English', ['en-AU', 'Australia'],
['en-CA', 'Canada'],
['en-IN', 'India'],
['en-NZ', 'New Zealand'],
['en-ZA', 'South Africa'],
['en-GB', 'United Kingdom'],
['en-US', 'United States']],
['Español', ['es-AR', 'Argentina'],
['es-BO', 'Bolivia'],
['es-CL', 'Chile'],
['es-CO', 'Colombia'],
['es-CR', 'Costa Rica'],
['es-EC', 'Ecuador'],
['es-SV', 'El Salvador'],
['es-ES', 'España'],
['es-US', 'Estados Unidos'],
['es-GT', 'Guatemala'],
['es-HN', 'Honduras'],
['es-MX', 'México'],
['es-NI', 'Nicaragua'],
['es-PA', 'Panamá'],
['es-PY', 'Paraguay'],
['es-PE', 'Perú'],
['es-PR', 'Puerto Rico'],
['es-DO', 'República Dominicana'],
['es-UY', 'Uruguay'],
['es-VE', 'Venezuela']],
['Euskara', ['eu-ES']],
['Filipino', ['fil-PH']],
['Français', ['fr-FR']],
['Galego', ['gl-ES']],
['Hrvatski', ['hr_HR']],
['IsiZulu', ['zu-ZA']],
['Íslenska', ['is-IS']],
['Italiano', ['it-IT', 'Italia'],
['it-CH', 'Svizzera']],
['Lietuvių', ['lt-LT']],
['Magyar', ['hu-HU']],
['Nederlands', ['nl-NL']],
['Norsk bokmål', ['nb-NO']],
['Polski', ['pl-PL']],
['Português', ['pt-BR', 'Brasil'],
['pt-PT', 'Portugal']],
['Română', ['ro-RO']],
['Slovenščina', ['sl-SI']],
['Slovenčina', ['sk-SK']],
['Suomi', ['fi-FI']],
['Svenska', ['sv-SE']],
['Tiếng Việt', ['vi-VN']],
['Türkçe', ['tr-TR']],
['Ελληνικά', ['el-GR']],
['български', ['bg-BG']],
['Pусский', ['ru-RU']],
['Српски', ['sr-RS']],
['Українська', ['uk-UA']],
['한국어', ['ko-KR']],
['中文', ['cmn-Hans-CN', '普通话 (中国大陆)'],
['cmn-Hans-HK', '普通话 (香港)'],
['cmn-Hant-TW', '中文 (台灣)'],
['yue-Hant-HK', '粵語 (香港)']],
['日本語', ['ja-JP']],
['हिन्दी', ['hi-IN']],
['ภาษาไทย', ['th-TH']]];
var final_transcript = '';
var recognizing = false;
var ignore_onend;
if (!('webkitSpeechRecognition' in window)) {
$('.fa-microphone').hide();
} else {
var recognition = new webkitSpeechRecognition();
recognition.continuous = false;
recognition.interimResults = true;
recognition.onstart = function() {
recognizing = true;
};
recognition.onerror = function(event) {
$('.fa-microphone').show();
$('#search').val('');
if (event.error == 'no-speech') {
ignore_onend = true;
}
if (event.error == 'audio-capture') {
ignore_onend = true;
}
if (event.error == 'not-allowed') {
ignore_onend = true;
}
};
recognition.onend = function() {
recognizing = false;
$('.fa-microphone').show();
if (ignore_onend) {
return;
}
if (!final_transcript) {
return;
}
$('#search-form').submit();
};
recognition.onresult = function(event) {
var interim_transcript = '';
if (typeof(event.results) == 'undefined') {
recognition.onend = null;
recognition.stop();
$('.fa-microphone').hide();
return;
}
for (var i = event.resultIndex; i < event.results.length; ++i) {
if (event.results[i].isFinal) {
final_transcript += event.results[i][0].transcript;
} else {
interim_transcript += event.results[i][0].transcript;
}
}
final_transcript = capitalize(final_transcript);
var value = final_transcript || interim_transcript;
var $search = document.getElementById('search');
$search.value = value;
$search.scrollLeft = $search.scrollWidth;
};
}
var first_char = /\S/;
function capitalize(s) {
return s.replace(first_char, function(m) { return m.toUpperCase(); });
}
function onMicrophoneClick() {
//$('#search').val("");
//$('#search-form').submit();
//return;
$('.fa-microphone').hide();
$('#search').val("{{ trans('texts.listening') }}");
if (recognizing) {
recognition.stop();
return;
}
final_transcript = '';
recognition.lang = 'en-US';
recognition.start();
ignore_onend = false;
}
</script>

View File

@ -35,9 +35,9 @@
</div>
-->
@if($entityType == ENTITY_INVOICE && $account->getTokenGatewayId() && $client->hasAutoBillConfigurableInvoices())
@if($entityType == ENTITY_INVOICE && $client->hasRecurringInvoices())
<div class="pull-right" style="margin-top:5px">
{!! Button::info(trans("texts.manage_auto_bill"))->asLinkTo(URL::to('/client/invoices/recurring'))->appendIcon(Icon::create('repeat')) !!}
{!! Button::primary(trans("texts.recurring_invoices"))->asLinkTo(URL::to('/client/invoices/recurring')) !!}
</div>
@endif
<h3>{{ $title }}</h3>
@ -49,7 +49,7 @@
->render('datatable') !!}
</div>
@if($entityType == ENTITY_RECURRING_INVOICE)
@if ($entityType == ENTITY_RECURRING_INVOICE)
{!! Former::open(URL::to('/client/invoices/auto_bill'))->id('auto_bill_form') !!}
<input type="hidden" name="public_id" id="auto_bill_public_id">
<input type="hidden" name="enable" id="auto_bill_enable">