1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-10 21:22:58 +01:00

Merge pull request #8991 from turbo124/v5-develop

v5.7.53
This commit is contained in:
David Bomba 2023-11-24 10:24:32 +11:00 committed by GitHub
commit cab854287f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 680 additions and 129 deletions

View File

@ -1 +1 @@
5.7.52
5.7.53

View File

@ -85,7 +85,7 @@ class BackupUpdate extends Command
->each(function ($company) {
$company_logo_path = $company->settings->company_logo;
if ($company_logo_path == 'https://invoicing.co/images/new_logo.png' || $company_logo_path == '') {
if ($company_logo_path == config('ninja.app_logo') || $company_logo_path == '') {
return;
}

View File

@ -977,7 +977,7 @@ class CheckData extends Command
$cc = ClientContact::on('db-ninja-01')->where('company_id', config('ninja.ninja_default_company_id'))->where('email', $cu->user->email)->first();
if ($cc) {
$ninja_portal_url = "https://invoiceninja.invoicing.co/client/ninja/{$cc->contact_key}/{$cu->account->key}";
$ninja_portal_url = config('ninja.ninja_client_portal')."/client/ninja/{$cc->contact_key}/{$cu->account->key}";
$cu->ninja_portal_url = $ninja_portal_url;
$cu->save();
@ -990,7 +990,7 @@ class CheckData extends Command
$cc = $c->contacts()->first();
if ($cc) {
$ninja_portal_url = "https://invoiceninja.invoicing.co/client/ninja/{$cc->contact_key}/{$cu->account->key}";
$ninja_portal_url = config('ninja.ninja_client_portal')."/client/ninja/{$cc->contact_key}/{$cu->account->key}";
$cu->ninja_portal_url = $ninja_portal_url;
$cu->save();

View File

@ -55,7 +55,7 @@ class ContactLoginController extends Controller
/** @var \App\Models\Company $company **/
if ($company) {
$account = $company->account;
} elseif (! $company && strpos($request->getHost(), 'invoicing.co') !== false) {
} elseif (! $company && strpos($request->getHost(), config('ninja.app_domain')) !== false) {
$subdomain = explode('.', $request->getHost())[0];
MultiDB::findAndSetDbByDomain(['subdomain' => $subdomain]);
$company = Company::where('subdomain', $subdomain)->first();

View File

@ -51,7 +51,7 @@ class YodleeController extends BaseController
$this->getAccounts($company, $token);
}
$redirect_url = isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react'] ? 'https://app.invoicing.co/#/' : 'https://invoicing.co/';
$redirect_url = isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react'] ? config('ninja.react_url') : config('ninja.app_url');
$data = [
'access_token' => $yodlee->getAccessToken(),

View File

@ -530,8 +530,8 @@ class BaseController extends Controller
$paginator = $query->paginate($limit);
/** @phpstan-ignore-next-line **/
$query = $paginator->getCollection();
/** @phpstan-ignore-next-line */
$query = $paginator->getCollection(); // @phpstan-ignore-line
$resource = new Collection($query, $transformer, $this->entity_type);
@ -636,7 +636,8 @@ class BaseController extends Controller
$paginator = $query->paginate($limit);
/** @phpstan-ignore-next-line **/
$query = $paginator->getCollection();
$query = $paginator->getCollection();// @phpstan-ignore-line
$resource = new Collection($query, $transformer, $this->entity_type);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
}
@ -885,7 +886,8 @@ class BaseController extends Controller
$paginator = $query->paginate($limit);
/** @phpstan-ignore-next-line **/
$query = $paginator->getCollection();
$query = $paginator->getCollection();// @phpstan-ignore-line
$resource = new Collection($query, $transformer, $this->entity_type);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
@ -951,7 +953,8 @@ class BaseController extends Controller
if ($query instanceof Builder) {
$limit = $this->resolveQueryLimit();
$paginator = $query->paginate($limit);
$query = $paginator->getCollection();
$query = $paginator->getCollection();// @phpstan-ignore-line
$resource = new Collection($query, $transformer, $this->entity_type);
$resource->setPaginator(new IlluminatePaginatorAdapter($paginator));
}
@ -1092,8 +1095,8 @@ class BaseController extends Controller
/** @var \App\Models\Account $account */
//always redirect invoicing.co to invoicing.co
if (Ninja::isHosted() && !in_array(request()->getSchemeAndHttpHost(), ['https://staging.invoicing.co', 'https://invoicing.co', 'https://demo.invoicing.co', 'https://invoiceninja.net'])) {
return redirect()->secure('https://invoicing.co');
if (Ninja::isHosted() && !in_array(request()->getSchemeAndHttpHost(), ['https://staging.invoicing.co', 'https://invoicing.co', 'https://demo.invoicing.co', 'https://invoiceninja.net', config('ninja.app_url')])) {
return redirect()->secure(config('ninja.app_url'));
}
if (config('ninja.require_https') && ! request()->isSecure()) {

View File

@ -44,7 +44,7 @@ class ApplePayDomainController extends Controller
$domain_name = $request->getHost();
if (strpos($domain_name, 'invoicing.co') !== false) {
if (strpos($domain_name, config('ninja.app_domain')) !== false) {
$subdomain = explode('.', $domain_name)[0];
$query = [

View File

@ -53,10 +53,6 @@ class PreviewController extends BaseController
public function live(PreviewInvoiceRequest $request): mixed
{
if (Ninja::isHosted() && !in_array($request->getHost(), ['preview.invoicing.co','staging.invoicing.co'])) {
return response()->json(['message' => 'This server cannot handle this request.'], 400);
}
$start = microtime(true);
/** Build models */

View File

@ -51,7 +51,7 @@ class StripeConnectController extends BaseController
}
$stripe_client_id = config('ninja.ninja_stripe_client_id');
$redirect_uri = 'https://invoicing.co/stripe/completed';
$redirect_uri = config('ninja.app_url').'/stripe/completed';
$endpoint = "https://connect.stripe.com/oauth/authorize?response_type=code&client_id={$stripe_client_id}&redirect_uri={$redirect_uri}&scope=read_write&state={$token}";
return redirect($endpoint);
@ -139,9 +139,9 @@ class StripeConnectController extends BaseController
// StripeWebhook::dispatch($company->company_key, $company_gateway->id);
if(isset($request->getTokenContent()['is_react']) && $request->getTokenContent()['is_react']) {
$redirect_uri = 'https://app.invoicing.co/#/settings/online_payments';
$redirect_uri = config('ninja.react_url').'/#/settings/online_payments';
} else {
$redirect_uri = 'https://invoicing.co/stripe/completed';
$redirect_uri = config('ninja.app_url').'/stripe/completed';
}
//response here

View File

@ -22,7 +22,7 @@ class ContactRegister
$domain_name = $request->getHost();
/* Hosted */
if (strpos($domain_name, 'invoicing.co') !== false) {
if (strpos($domain_name, config('ninja.app_domain')) !== false) {
$subdomain = explode('.', $domain_name)[0];
$query = [

View File

@ -32,8 +32,7 @@ class SessionDomains
$domain_name = $request->getHost();
if (strpos($domain_name, 'invoicing.co') !== false) {
// config(['session.domain' => '.invoicing.co']);
if (strpos($domain_name, config('ninja.app_domain')) !== false) {
} else {
config(['session.domain' => $domain_name]);
}

View File

@ -41,7 +41,7 @@ class SetDomainNameDb
$domain_name = $request->getHost();
if (strpos($domain_name, 'invoicing.co') !== false) {
if (strpos($domain_name, config('ninja.app_domain')) !== false) {
$subdomain = explode('.', $domain_name)[0];
$query = [

View File

@ -28,34 +28,45 @@ class StoreExpenseRequest extends Request
*/
public function authorize() : bool
{
return auth()->user()->can('create', Expense::class);
/** @var \App\Models\User $user */
$user = auth()->user();
return $user->can('create', Expense::class);
}
public function rules()
{
/** @var \App\Models\User $user */
$user = auth()->user();
$rules = [];
if ($this->number) {
$rules['number'] = Rule::unique('expenses')->where('company_id', auth()->user()->company()->id);
$rules['number'] = Rule::unique('expenses')->where('company_id', $user->company()->id);
}
if ($this->client_id) {
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.auth()->user()->company()->id;
$rules['client_id'] = 'bail|sometimes|exists:clients,id,company_id,'.$user->company()->id;
}
$rules['category_id'] = 'bail|nullable|sometimes|exists:expense_categories,id,company_id,'.auth()->user()->company()->id.',is_deleted,0';
$rules['category_id'] = 'bail|nullable|sometimes|exists:expense_categories,id,company_id,'.$user->company()->id.',is_deleted,0';
$rules['payment_date'] = 'bail|nullable|sometimes|date:Y-m-d';
$rules['date'] = 'bail|sometimes|date:Y-m-d';
return $this->globalRules($rules);
}
public function prepareForValidation()
{
/** @var \App\Models\User $user */
$user = auth()->user();
$input = $this->all();
$input = $this->decodePrimaryKeys($input);
if (! array_key_exists('currency_id', $input) || strlen($input['currency_id']) == 0) {
$input['currency_id'] = (string) auth()->user()->company()->settings->currency_id;
$input['currency_id'] = (string) $user->company()->settings->currency_id;
}
if (array_key_exists('color', $input) && is_null($input['color'])) {
@ -80,7 +91,6 @@ class StoreExpenseRequest extends Request
public function messages()
{
return [
// 'unique' => ctrans('validation.unique', ['attribute' => 'number']),
];
}
}

View File

@ -39,7 +39,7 @@ class StripeConnectFailed extends Mailable
{
return new Envelope(
subject: "Stripe Connect not configured, please login and connect.",
from: "maildelivery@invoicing.co",
from: config('ninja.contact.email'),
to: $this->user->email,
);
}

View File

@ -41,6 +41,12 @@ class ExpenseRepository extends BaseRepository
*/
public function save(array $data, Expense $expense): Expense
{
if(isset($data['payment_date']) && $data['payment_date'] == $expense->payment_date) {
//do nothing
} elseif(isset($data['payment_date']) && strlen($data['payment_date']) > 1 && $expense->company->notify_vendor_when_paid) {
nlog("NOT SAME");
}
$expense->fill($data);
if (!$expense->id) {
@ -50,8 +56,8 @@ class ExpenseRepository extends BaseRepository
if (empty($expense->number)) {
$expense = $this->findAndSaveNumber($expense);
}
$expense->saveQuietly();
else
$expense->saveQuietly();
if (array_key_exists('documents', $data)) {
$this->saveDocuments($data['documents'], $expense);

View File

@ -158,7 +158,12 @@ class Statement
->where('company_id', $this->client->company_id)
->first();
$ts = $template->service()->build([
$ts = $template->service();
$ts->addGlobal(['show_credits' => $this->options['show_credits_table']]);
$ts->addGlobal(['show_aging' => $this->options['show_aging_table']]);
$ts->addGlobal(['show_payments' => $this->options['show_payments_table']]);
$ts->build([
'variables' => collect([$variables]),
'invoices' => $this->getInvoices()->get(),
'payments' => $this->options['show_payments_table'] ? $this->getPayments()->get() : collect([]),
@ -400,6 +405,7 @@ class Statement
protected function getAging(): array
{
return [
ctrans('texts.current') => $this->getAgingAmount('0'),
'0-30' => $this->getAgingAmount('30'),
'30-60' => $this->getAgingAmount('60'),
'60-90' => $this->getAgingAmount('90'),
@ -421,14 +427,23 @@ class Statement
$from = $ranges[0];
$to = $ranges[1];
$amount = Invoice::withTrashed()
$query = Invoice::withTrashed()
->where('client_id', $this->client->id)
->where('company_id', $this->client->company_id)
->whereIn('status_id', [Invoice::STATUS_SENT, Invoice::STATUS_PARTIAL])
->where('balance', '>', 0)
->where('is_deleted', 0)
->whereBetween('due_date', [$to, $from])
->sum('balance');
->where('is_deleted', 0);
if($range == '0'){
$query->where(function ($q) use($to, $from){
$q->whereBetween('due_date', [$to, $from])->orWhereNull('due_date');
});
}
else {
$query->whereBetween('due_date', [$to, $from]);
}
$amount = $query->sum('balance');
return Number::formatMoney($amount, $this->client);
}
@ -444,6 +459,10 @@ class Statement
$ranges = [];
switch ($range) {
case '0':
$ranges[0] = now()->subYears(50);
$ranges[1] = now()->startOfDay()->subMinute();
return $ranges;
case '30':
$ranges[0] = now()->startOfDay();
$ranges[1] = now()->startOfDay()->subDays(30);

View File

@ -213,7 +213,7 @@ class PdfMock
'$client.billing_address2' => '63993 Aiyana View',
'$client.billing_address1' => '8447',
'$client.shipping_country' => 'USA',
'$invoiceninja.whitelabel' => 'https://invoicing.co/images/new_logo.png',
'$invoiceninja.whitelabel' => config('ninja.app_logo'),
'$client.billing_address' => '8447<br/>63993 Aiyana View<br/>Aufderharchester, North Carolina 11243<br/>United States<br/>',
'$client.billing_country' => 'USA',
'$task.gross_line_total' => '100',
@ -483,12 +483,15 @@ class PdfMock
'_rate3' => '',
'$taxes' => '$40.00',
'$total' => '$10.00',
'$refund' => '',
'$refunded' => '',
'$phone' => '&nbsp;',
'$terms' => 'Default company invoice terms',
'$from' => 'Bob Jones',
'$item' => '',
'$date' => '25/Feb/2023',
'$tax' => '',
'$net' => 'Net',
'$dir' => 'ltr',
'$to' => 'Jimmy Giggles',
'$show_paid_stamp' => $this->settings->show_paid_stamp ? 'flex' : 'none',
@ -803,6 +806,8 @@ class PdfMock
'$tax_rate1_label' => ctrans('texts.tax_rate1'),
'$tax_rate2_label' => ctrans('texts.tax_rate2'),
'$tax_rate3_label' => ctrans('texts.tax_rate3'),
'$refund_label' => ctrans('texts.refund'),
'$refunded_label' => ctrans('texts.refunded'),
'$phone_label' => ctrans('texts.phone'),
'$email_label' => ctrans('texts.email'),
'$taxes_label' => ctrans('texts.taxes'),
@ -811,6 +816,7 @@ class PdfMock
'$item_label' => ctrans('texts.item'),
'$date_label' => ctrans('texts.date'),
'$tax_label' => ctrans('texts.tax'),
'$net_label' => ctrans('texts.net'),
'$dir_label' => '',
'$to_label' => ctrans('texts.to'),
'$start_date_label' => ctrans('texts.start_date'),
@ -831,7 +837,7 @@ class PdfMock
'$purchase_order.due_date' => '02-12-2021',
'$vendor.billing_address1' => '589',
'$vendor.billing_address2' => '761 Odessa Centers Suite 673',
'$invoiceninja.whitelabel' => 'https://invoicing.co/images/new_logo.png',
'$invoiceninja.whitelabel' => config('ninja.app_logo'),
'$purchase_order.custom1' => 'Custom 1',
'$purchase_order.custom2' => 'Custom 2',
'$purchase_order.custom3' => 'Custom 3',
@ -907,7 +913,7 @@ class PdfMock
'$created_by_user' => 'Mr. Louvenia Armstrong Prof. Reyes Anderson',
'$vendor.currency' => 'USD',
'$company.country' => 'United States',
'$tech_hero_image' => 'https://invoicing.co/images/pdf-designs/tech-hero-image.jpg',
'$tech_hero_image' => config('ninja.app_url').'/images/pdf-designs/tech-hero-image.jpg',
'$company.website' => 'http://www.dare.com/vero-consequatur-eveniet-dolorum-exercitationem-alias-repellat.html',
'$gross_subtotal' => '$10,256.40',
'$emailSignature' => '&nbsp;',
@ -1115,6 +1121,8 @@ class PdfMock
'$tax_rate1' => '',
'$tax_rate2' => '',
'$tax_rate3' => '',
'$refund' => 'Refund',
'$refunded' => 'Refunded',
'$total' => '$10,256.40',
'$taxes' => '$488.40',
'$phone' => '&nbsp;',
@ -1123,6 +1131,7 @@ class PdfMock
'$date' => '14/Mar/2023',
'$tax' => '',
'$dir' => 'ltr',
'$net' => 'Net',
'$to' => '',
],
'labels' => $this->vendorLabels(),
@ -1334,6 +1343,8 @@ class PdfMock
'$tax_rate1_label' => ctrans('texts.tax_rate1'),
'$tax_rate2_label' => ctrans('texts.tax_rate2'),
'$tax_rate3_label' => ctrans('texts.tax_rate3'),
'$refund_label' => ctrans('texts.refund'),
'$refunded_label' => ctrans('texts.refunded'),
'$total_label' => ctrans('texts.total'),
'$taxes_label' => ctrans('texts.taxes'),
'$phone_label' => ctrans('texts.phone'),
@ -1341,6 +1352,7 @@ class PdfMock
'$item_label' => ctrans('texts.item'),
'$date_label' => ctrans('texts.date'),
'$tax_label' => ctrans('texts.tax'),
'$net_label' => ctrans('texts.net'),
'$dir_label' => '',
'$to_label' => ctrans('texts.to'),
];

File diff suppressed because one or more lines are too long

View File

@ -53,6 +53,8 @@ class TemplateService
private array $variables = [];
private array $global_vars = [];
public ?Company $company;
private ?Client $client;
@ -124,6 +126,7 @@ class TemplateService
{
$this->compose()
->processData($data)
->setGlobals()
->parseNinjaBlocks()
->processVariables($data)
->parseGlobalStacks()
@ -145,6 +148,25 @@ class TemplateService
return $this;
}
private function setGlobals(): self
{
foreach($this->global_vars as $key => $value) {
$this->twig->addGlobal($key, $value);
}
$this->global_vars = [];
return $this;
}
public function addGlobal(array $var): self
{
$this->global_vars = array_merge($this->global_vars, $var);
return $this;
}
/**
* Returns a Mock Template
*
@ -159,6 +181,10 @@ class TemplateService
$this->data = $tm->engines;
$this->variables = $tm->variables[0];
$this->twig->addGlobal('currency_code', $this->company->currency()->code);
$this->twig->addGlobal('show_credits', true);
$this->twig->addGlobal('show_aging', true);
$this->twig->addGlobal('show_payments', true);
$this->parseNinjaBlocks()
->parseGlobalStacks()
@ -442,6 +468,7 @@ class TemplateService
'balance' => Number::formatMoney($invoice->balance, $invoice->client),
'status_id' => $invoice->status_id,
'status' => Invoice::stringStatus($invoice->status_id),
'amount_raw' => $invoice->amount ,
'balance_raw' => $invoice->balance,
'number' => $invoice->number ?: '',
'discount' => $invoice->discount,
@ -550,6 +577,8 @@ class TemplateService
$this->payment = $payment;
$this->addGlobal(['currency_code' => $payment->currency->code ?? $this->company->currency()->code]);
$credits = $payment->credits->map(function ($credit) use ($payment) {
return [
'credit' => $credit->number,
@ -827,11 +856,11 @@ class TemplateService
*/
public function processPayments($payments): array
{
nlog("processing payments");
$payments = collect($payments)->map(function ($payment) {
return $this->transformPayment($payment);
})->toArray();
nlog($payments);
return $payments;
}

View File

@ -166,6 +166,7 @@ class HtmlEngine
$data['$exchange_rate'] = ['value' => $this->entity->exchange_rate ?: ' ', 'label' => ctrans('texts.exchange_rate')];
$data['$triangular_tax'] = ['value' => ctrans('texts.triangular_tax'), 'label' => ''];
$data['$tax_info'] = ['value' => $this->taxLabel(), 'label' => ''];
$data['$net'] = ['value' => '', 'label' => ctrans('texts.net')];
if ($this->entity_string == 'invoice' || $this->entity_string == 'recurring_invoice') {
$data['$entity'] = ['value' => ctrans('texts.invoice'), 'label' => ctrans('texts.invoice')];
@ -664,6 +665,8 @@ class HtmlEngine
$data['$payment.custom2'] = ['value' => '', 'label' => ctrans('texts.payment')];
$data['$payment.custom3'] = ['value' => '', 'label' => ctrans('texts.payment')];
$data['$payment.custom4'] = ['value' => '', 'label' => ctrans('texts.payment')];
$data['$refund'] = ['value' => '', 'label' => ctrans('texts.refund')];
$data['$refunded'] = ['value' => '', 'label' => ctrans('texts.refunded')];
$data['$payment.amount'] = ['value' => '', 'label' => ctrans('texts.payment')];
$data['$payment.date'] = ['value' => '', 'label' => ctrans('texts.payment_date')];

View File

@ -11,12 +11,14 @@ return [
'version_url' => 'https://pdf.invoicing.co/api/version',
'app_name' => env('APP_NAME', 'Invoice Ninja'),
'app_env' => env('APP_ENV', 'selfhosted'),
'app_logo' => env('APP_LOGO', 'https://invoicing.co/images/new_logo.png'),
'ninja_client_portal' => env('NINJA_CLIENT_PORTAL', 'https://invoiceninja.invoicing.co'),
'debug_enabled' => env('APP_DEBUG', false),
'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => env('APP_VERSION','5.7.52'),
'app_tag' => env('APP_TAG','5.7.52'),
'app_version' => env('APP_VERSION','5.7.53'),
'app_tag' => env('APP_TAG','5.7.53'),
'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', false),

View File

@ -4260,7 +4260,7 @@ $LANG = array(
'direct_debit' => 'Direct Debit',
'clone_to_expense' => 'Clone to Expense',
'checkout' => 'Checkout',
'acss' => 'Pre-authorized debit payments',
'acss' => 'ACSS Debit',
'invalid_amount' => 'Invalid amount. Number/Decimal values only.',
'client_payment_failure_body' => 'Payment for Invoice :invoice for amount :amount failed.',
'browser_pay' => 'Google Pay, Apple Pay, Microsoft Pay',

View File

@ -958,7 +958,7 @@ $LANG = array(
'header_font_id' => 'Police de l\'en-tête',
'body_font_id' => 'Police du corps',
'color_font_help' => 'Note: la couleur principale et les polices sont aussi utilisées dans le portail client et dans les modèles de courriels personnalisés.',
'live_preview' => 'PRÉVISUALISATION',
'live_preview' => 'Prévisualitsation',
'invalid_mail_config' => 'impossible d\'envoyer le courriel, veuillez vérifier vos paramètres courriel.',
'invoice_message_button' => 'Pour voir la facture de :amount, cliquez sur le bouton ci-dessous.',
'quote_message_button' => 'Pour voir la soumission de :amount, cliquez sur le bouton ci-dessous.',
@ -1183,7 +1183,7 @@ $LANG = array(
'page_size' => 'Taille de page',
'live_preview_disabled' => 'La prévisualisation en direct a été désactivée pour cette police',
'invoice_number_padding' => 'Remplissage (padding)',
'preview' => 'PRÉVISUALISATION',
'preview' => 'Prévisualitsation',
'list_vendors' => 'Liste des fournisseurs',
'add_users_not_supported' => 'Mettre à niveau vers le plan Enterprise plan pour ajouter des utilisateurs à votre compte.',
'enterprise_plan_features' => 'Le Plan entreprise offre le support pour de multiple utilisateurs ainsi que l\'ajout de pièces jointes, :link pour voir la liste complète des fonctionnalités.',
@ -5181,6 +5181,30 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
'payment_receipt' => 'Reçu de paiement #',
'load_template_description' => 'Le modèle s\'appliquera à:',
'run_template' => 'Exécuter le modèle',
'statement_design' => 'Modèle de relevé',
'delivery_note_design' => 'Modèle de note de livraison',
'payment_receipt_design' => 'Modèle de reçu de paiement',
'payment_refund_design' => 'Modèle de paiement de remboursement',
'task_extension_banner' => 'Ajouter l\'extension Chrome pour gérer vos tâches',
'watch_video' => 'Regardez',
'view_extension' => 'Voir l\'extension',
'reactivate_email' => 'Réactiver le courriel',
'email_reactivated' => 'Le courriel a été réactivé',
'template_help' => 'Enable using the design as a template',
'quarter' => 'Quarter',
'item_description' => 'Description d\'article',
'task_item' => 'Article de tâche',
'record_state' => 'État de l\'enregistrement',
'save_files_to_this_folder' => 'Sauvegarder les fichiers dans ce dossier',
'downloads_folder' => 'Dossier de téléchargements',
'total_invoiced_quotes' => 'Soumissions facturées',
'total_invoice_paid_quotes' => 'Soumissions de factures payées',
'downloads_folder_does_not_exist' => 'Le dossier de téléchargements n\'existe pas :value',
'user_logged_in_notification' => 'User Logged in Notification',
'user_logged_in_notification_help' => 'Send an email when logging in from a new location',
'payment_email_all_contacts' => 'Courriel de paiement à tous les contacts',
'payment_email_all_contacts_help' => 'Envoi un courriel de paiement à tous les contacts lorsqu\'activé',
'add_line' => 'Ajouter une ligne',
);
return $LANG;

View File

@ -64,7 +64,7 @@ $LANG = array(
'archive_invoice' => 'Archiver la facture',
'delete_invoice' => 'Supprimer la facture',
'email_invoice' => 'Envoyer la facture par courriel',
'enter_payment' => 'Inscrire un paiement',
'enter_payment' => 'Saisir un paiement',
'tax_rates' => 'Taux de TVA',
'rate' => 'Taux',
'settings' => 'Paramètres',
@ -125,8 +125,8 @@ $LANG = array(
'filter' => 'Filtrer',
'new_client' => 'Nouveau client',
'new_invoice' => 'Nouvelle facture',
'new_payment' => 'Inscrire un paiement',
'new_credit' => 'Inscrire un crédit',
'new_payment' => 'Saisir un paiement',
'new_credit' => 'Saisir un crédit',
'contact' => 'Contact',
'date_created' => 'Date de création',
'last_login' => 'Dernière connexion',
@ -150,7 +150,7 @@ $LANG = array(
'edit_client' => 'Modifier le client',
'edit_invoice' => 'Modifier la facture',
'create_invoice' => 'Créer une facture',
'enter_credit' => 'Inscrire un crédit',
'enter_credit' => 'Saisir un crédit',
'last_logged_in' => 'Dernière connexion',
'details' => 'Détails',
'standing' => 'En attente',
@ -387,7 +387,7 @@ $LANG = array(
'more_designs_self_host_text' => '',
'buy' => 'Acheter',
'bought_designs' => 'Les nouveaux modèles ont été ajoutés avec succès',
'sent' => 'Envoyé',
'sent' => 'Envoyée',
'vat_number' => 'N° de taxe',
'timesheets' => 'Feuilles de temps',
'payment_title' => 'Veuillez entrer votre adresse de facturation et vos information de carte de crédit',
@ -5181,6 +5181,30 @@ Lorsque les montant apparaîtront sur votre relevé, veuillez revenir sur cette
'payment_receipt' => 'Reçu de paiement # :number',
'load_template_description' => 'Le modèle sera appliqué aux éléments suivants :',
'run_template' => 'Exécuter le modèle',
'statement_design' => 'Modèle de relevé',
'delivery_note_design' => 'Delivery Note Design',
'payment_receipt_design' => 'Modèle de reçu de paiement',
'payment_refund_design' => 'Payment Refund Design',
'task_extension_banner' => 'Add the Chrome extension to manage your tasks',
'watch_video' => 'Regardez la vidéo',
'view_extension' => 'Voir l\'extension',
'reactivate_email' => 'Réactiver l\'adresse email',
'email_reactivated' => 'L\'adresse email a été réactivée',
'template_help' => 'Enable using the design as a template',
'quarter' => 'Quarter',
'item_description' => 'Description d\'article',
'task_item' => 'Task Item',
'record_state' => 'Record State',
'save_files_to_this_folder' => 'Sauvegarder les fichiers dans ce dossier',
'downloads_folder' => 'Dossier de téléchargements',
'total_invoiced_quotes' => 'Offres facturées',
'total_invoice_paid_quotes' => 'Offres de factures payées',
'downloads_folder_does_not_exist' => 'Le dossier de téléchargements n\'existe pas :value',
'user_logged_in_notification' => 'Notification de connexion d\'utilisateur',
'user_logged_in_notification_help' => 'Send an email when logging in from a new location',
'payment_email_all_contacts' => 'Email de paiement à tous les contacts',
'payment_email_all_contacts_help' => 'Sends the payment email to all contacts when enabled',
'add_line' => 'Ajouter une ligne',
);
return $LANG;

View File

@ -1889,7 +1889,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/companies/{id}/upload":
put:
post:
tags:
- companies
summary: "Uploads a document to a company"
@ -1907,6 +1907,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the client object"
@ -3429,7 +3446,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/expenses/{id}/upload":
put:
post:
tags:
- expense
summary: "Uploads a document to a expense"
@ -3447,6 +3464,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Expense object"
@ -3801,7 +3835,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/group_settings/{id}/upload":
put:
post:
tags:
- group_settings
summary: "Uploads a document to a group setting"
@ -3819,6 +3853,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Group Setting object"
@ -4926,7 +4977,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/recurring_expenses/{id}/upload":
put:
post:
tags:
- recurring_expense
summary: "Uploads a document to a recurring_expense"
@ -4944,6 +4995,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the RecurringExpense object"
@ -8620,7 +8688,7 @@ paths:
$ref: '#/components/responses/default'
"/api/v1/products/{id}/upload":
put:
post:
tags:
- products
summary: "Add product document"
@ -9021,7 +9089,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/tasks/{id}/upload":
put:
post:
tags:
- tasks
summary: "Uploads a task document"
@ -9039,6 +9107,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Task object"
@ -9440,7 +9525,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/projects/{id}/upload":
put:
post:
tags:
- projects
summary: "Uploads a project document"
@ -9458,6 +9543,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Project object"
@ -9924,7 +10026,7 @@ paths:
default:
$ref: '#/components/responses/default'
'/api/v1/clients/{id}/upload':
put:
post:
tags:
- clients
summary: 'Add client document'
@ -10614,7 +10716,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/credits/{id}/upload":
put:
post:
tags:
- credits
summary: "Upload a credit document"
@ -10632,6 +10734,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Credit object"
@ -11142,7 +11261,7 @@ paths:
$ref: "#/components/responses/default"
"/api/v1/payments/{id}/upload":
put:
post:
tags:
- payments
summary: "Upload a payment document"
@ -11160,6 +11279,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Payment object"
@ -12400,7 +12536,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/recurring_invoices/{id}/upload":
put:
post:
tags:
- Recurring Invoices
summary: "Add recurring invoice document"
@ -12418,6 +12554,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the RecurringInvoice object"
@ -12929,7 +13082,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/quotes/{id}/upload":
put:
post:
tags:
- quotes
summary: "Upload a quote document"
@ -12947,6 +13100,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Quote object"
@ -13367,7 +13537,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/purchase_orders/{id}/upload":
put:
post:
tags:
- Purchase Orders
summary: "Uploads a purchase order document"
@ -13385,6 +13555,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Purchase Order object"
@ -13794,7 +13981,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/vendors/{id}/upload":
put:
post:
tags:
- vendors
summary: "Uploads a vendor document"
@ -13812,6 +13999,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Vendor object"
@ -20666,27 +20870,31 @@ components:
id:
description: 'The expense hashed id'
type: string
example: Opnel5aKBz
example: 'Opnel5aKBz'
user_id:
description: 'The user hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
assigned_user_id:
description: 'The assigned user hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
project_id:
description: 'The associated project_id'
type: string
example: 'Opnel5aKBz'
company_id:
description: 'The company hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
client_id:
description: 'The client hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
invoice_id:
description: 'The related invoice hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
bank_id:
description: 'The bank id related to this expense'
type: string
@ -20694,15 +20902,15 @@ components:
invoice_currency_id:
description: 'The currency id of the related invoice'
type: string
example: ''
example: '1'
expense_currency_id:
description: 'The currency id of the expense'
type: string
example: ''
example: '2'
invoice_category_id:
description: 'The invoice category id'
type: string
example: ''
example: 'Opnel5aKBz'
payment_type_id:
description: 'The payment type id'
type: string
@ -20710,7 +20918,7 @@ components:
recurring_expense_id:
description: 'The related recurring expense this expense was created from'
type: string
example: ''
example: 'Opnel5aKBz'
private_notes:
description: 'The private notes of the expense'
type: string
@ -20743,30 +20951,34 @@ components:
description: 'A custom value'
type: string
example: ''
tax_amount:
description: 'The tax amount'
type: number
example: 10.00
tax_name1:
description: 'Tax name'
description: 'Tax Name 1'
type: string
example: ''
example: 'GST'
tax_name2:
description: 'Tax name'
description: 'Tax Name 2'
type: string
example: ''
example: 'VAT'
tax_name3:
description: 'Tax Name 3'
type: string
example: 'IVA'
tax_rate1:
description: 'Tax rate'
description: 'Tax rate 1'
type: number
format: float
example: '10.00'
tax_rate2:
description: 'Tax rate'
description: 'Tax rate 2'
type: number
format: float
example: '10.00'
tax_name3:
description: 'Tax name'
type: string
example: ''
tax_rate3:
description: 'Tax rate'
description: 'Tax rate 3'
type: number
format: float
example: '10.00'
@ -20786,13 +20998,13 @@ components:
format: float
example: '0.80'
date:
description: 'The expense date formate Y-m-d'
description: 'The expense date format Y-m-d'
type: string
example: '2022-12-01'
payment_date:
description: 'The date of payment for the expense, format Y-m-d'
type: string
example: ''
example: '2022-12-01'
should_be_invoiced:
description: 'Flag whether the expense should be invoiced'
type: boolean

View File

@ -3,27 +3,31 @@
id:
description: 'The expense hashed id'
type: string
example: Opnel5aKBz
example: 'Opnel5aKBz'
user_id:
description: 'The user hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
assigned_user_id:
description: 'The assigned user hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
project_id:
description: 'The associated project_id'
type: string
example: 'Opnel5aKBz'
company_id:
description: 'The company hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
client_id:
description: 'The client hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
invoice_id:
description: 'The related invoice hashed id'
type: string
example: ''
example: 'Opnel5aKBz'
bank_id:
description: 'The bank id related to this expense'
type: string
@ -31,15 +35,15 @@
invoice_currency_id:
description: 'The currency id of the related invoice'
type: string
example: ''
example: '1'
expense_currency_id:
description: 'The currency id of the expense'
type: string
example: ''
example: '2'
invoice_category_id:
description: 'The invoice category id'
type: string
example: ''
example: 'Opnel5aKBz'
payment_type_id:
description: 'The payment type id'
type: string
@ -47,7 +51,7 @@
recurring_expense_id:
description: 'The related recurring expense this expense was created from'
type: string
example: ''
example: 'Opnel5aKBz'
private_notes:
description: 'The private notes of the expense'
type: string
@ -80,30 +84,34 @@
description: 'A custom value'
type: string
example: ''
tax_amount:
description: 'The tax amount'
type: number
example: 10.00
tax_name1:
description: 'Tax name'
description: 'Tax Name 1'
type: string
example: ''
example: 'GST'
tax_name2:
description: 'Tax name'
description: 'Tax Name 2'
type: string
example: ''
example: 'VAT'
tax_name3:
description: 'Tax Name 3'
type: string
example: 'IVA'
tax_rate1:
description: 'Tax rate'
description: 'Tax rate 1'
type: number
format: float
example: '10.00'
tax_rate2:
description: 'Tax rate'
description: 'Tax rate 2'
type: number
format: float
example: '10.00'
tax_name3:
description: 'Tax name'
type: string
example: ''
tax_rate3:
description: 'Tax rate'
description: 'Tax rate 3'
type: number
format: float
example: '10.00'
@ -123,13 +131,13 @@
format: float
example: '0.80'
date:
description: 'The expense date formate Y-m-d'
description: 'The expense date format Y-m-d'
type: string
example: '2022-12-01'
payment_date:
description: 'The date of payment for the expense, format Y-m-d'
type: string
example: ''
example: '2022-12-01'
should_be_invoiced:
description: 'Flag whether the expense should be invoiced'
type: boolean

View File

@ -1865,7 +1865,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/companies/{id}/upload":
put:
post:
tags:
- companies
summary: "Uploads a document to a company"
@ -1883,6 +1883,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the client object"
@ -3405,7 +3422,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/expenses/{id}/upload":
put:
post:
tags:
- expense
summary: "Uploads a document to a expense"
@ -3423,6 +3440,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Expense object"
@ -3777,7 +3811,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/group_settings/{id}/upload":
put:
post:
tags:
- group_settings
summary: "Uploads a document to a group setting"
@ -3795,6 +3829,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Group Setting object"
@ -4902,7 +4953,7 @@ paths:
default:
$ref: "#/components/responses/default"
"/api/v1/recurring_expenses/{id}/upload":
put:
post:
tags:
- recurring_expense
summary: "Uploads a document to a recurring_expense"
@ -4920,6 +4971,23 @@ paths:
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the RecurringExpense object"

View File

@ -438,7 +438,7 @@
default:
$ref: '#/components/responses/default'
'/api/v1/clients/{id}/upload':
put:
post:
tags:
- clients
summary: 'Add client document'

View File

@ -385,7 +385,7 @@
default:
$ref: "#/components/responses/default"
"/api/v1/credits/{id}/upload":
put:
post:
tags:
- credits
summary: "Upload a credit document"
@ -403,6 +403,23 @@
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Credit object"

View File

@ -482,7 +482,7 @@
$ref: "#/components/responses/default"
"/api/v1/payments/{id}/upload":
put:
post:
tags:
- payments
summary: "Upload a payment document"
@ -500,6 +500,23 @@
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Payment object"

View File

@ -382,7 +382,7 @@
$ref: '#/components/responses/default'
"/api/v1/products/{id}/upload":
put:
post:
tags:
- products
summary: "Add product document"

View File

@ -340,7 +340,7 @@
default:
$ref: "#/components/responses/default"
"/api/v1/projects/{id}/upload":
put:
post:
tags:
- projects
summary: "Uploads a project document"
@ -358,6 +358,23 @@
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Project object"

View File

@ -392,7 +392,7 @@
default:
$ref: "#/components/responses/default"
"/api/v1/purchase_orders/{id}/upload":
put:
post:
tags:
- Purchase Orders
summary: "Uploads a purchase order document"
@ -410,6 +410,23 @@
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Purchase Order object"

View File

@ -483,7 +483,7 @@
default:
$ref: "#/components/responses/default"
"/api/v1/quotes/{id}/upload":
put:
post:
tags:
- quotes
summary: "Upload a quote document"
@ -501,6 +501,23 @@
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Quote object"

View File

@ -499,7 +499,7 @@
default:
$ref: "#/components/responses/default"
"/api/v1/recurring_invoices/{id}/upload":
put:
post:
tags:
- Recurring Invoices
summary: "Add recurring invoice document"
@ -517,6 +517,23 @@
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the RecurringInvoice object"

View File

@ -340,7 +340,7 @@
default:
$ref: "#/components/responses/default"
"/api/v1/tasks/{id}/upload":
put:
post:
tags:
- tasks
summary: "Uploads a task document"
@ -358,6 +358,23 @@
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Task object"

View File

@ -340,7 +340,7 @@
default:
$ref: "#/components/responses/default"
"/api/v1/vendors/{id}/upload":
put:
post:
tags:
- vendors
summary: "Uploads a vendor document"
@ -358,6 +358,23 @@
type: string
format: string
example: D2J234DFA
requestBody:
description: "File Upload Body"
required: true
content:
multipart/form-data:
schema:
type: object
properties:
_method:
type: string
example: PUT
documents:
type: array
items:
description: "Array of binary documents for upload"
type: string
format: binary
responses:
200:
description: "Returns the Vendor object"