Merge pull request #355 from Lykegenes/master

Charts & reports SQLite compatibility
This commit is contained in:
Hillel Coren 2015-07-28 10:00:32 +03:00
commit da6e59a925
4 changed files with 141 additions and 99 deletions

View File

@ -1,6 +1,7 @@
<?php namespace App\Http\Controllers; <?php namespace App\Http\Controllers;
use Auth; use Auth;
use Config;
use Input; use Input;
use Utils; use Utils;
use DB; use DB;
@ -149,53 +150,90 @@ class ReportController extends BaseController
$reportTotals['balance'][$currencyId] += $record->balance; $reportTotals['balance'][$currencyId] += $record->balance;
} }
if ($action == 'export') { if ($action == 'export')
{
self::export($exportData, $reportTotals); self::export($exportData, $reportTotals);
} }
} }
if ($enableChart) { if ($enableChart)
foreach ([ENTITY_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT] as $entityType) { {
$records = DB::table($entityType.'s') foreach ([ENTITY_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT] as $entityType)
->select(DB::raw('sum(amount) as total, concat(YEAR('.$entityType.'_date), '.$groupBy.'('.$entityType.'_date)) as '.$groupBy)) {
->where('account_id', '=', Auth::user()->account_id) // SQLite does not support the YEAR(), MONTH(), WEEK() and similar functions.
->where($entityType.'s.is_deleted', '=', false) // Let's see if SQLite is being used.
->where($entityType.'s.'.$entityType.'_date', '>=', $startDate->format('Y-m-d')) if (Config::get('database.connections.'.Config::get('database.default').'.driver') == 'sqlite')
->where($entityType.'s.'.$entityType.'_date', '<=', $endDate->format('Y-m-d')) {
->groupBy($groupBy); // Replace the unsupported function with it's date format counterpart
switch ($groupBy)
{
case 'MONTH':
$dateFormat = '%m'; // returns 01-12
break;
case 'WEEK':
$dateFormat = '%W'; // returns 00-53
break;
case 'DAYOFYEAR':
$dateFormat = '%j'; // returns 001-366
break;
default:
$dateFormat = '%m'; // MONTH by default
break;
}
if ($entityType == ENTITY_INVOICE) { // Concatenate the year and the chosen timeframe (Month, Week or Day)
$timeframe = 'strftime("%Y", '.$entityType.'_date) || strftime("'.$dateFormat.'", '.$entityType.'_date)';
}
else
{
// Supported by Laravel's other DBMS drivers (MySQL, MSSQL and PostgreSQL)
$timeframe = 'concat(YEAR('.$entityType.'_date), '.$groupBy.'('.$entityType.'_date))';
}
$records = DB::table($entityType.'s')
->select(DB::raw('sum(amount) as total, '.$timeframe.' as '.$groupBy))
->where('account_id', '=', Auth::user()->account_id)
->where($entityType.'s.is_deleted', '=', false)
->where($entityType.'s.'.$entityType.'_date', '>=', $startDate->format('Y-m-d'))
->where($entityType.'s.'.$entityType.'_date', '<=', $endDate->format('Y-m-d'))
->groupBy($groupBy);
if ($entityType == ENTITY_INVOICE)
{
$records->where('is_quote', '=', false) $records->where('is_quote', '=', false)
->where('is_recurring', '=', false); ->where('is_recurring', '=', false);
} }
$totals = $records->lists('total'); $totals = $records->lists('total');
$dates = $records->lists($groupBy); $dates = $records->lists($groupBy);
$data = array_combine($dates, $totals); $data = array_combine($dates, $totals);
$padding = $groupBy == 'DAYOFYEAR' ? 'day' : ($groupBy == 'WEEK' ? 'week' : 'month'); $padding = $groupBy == 'DAYOFYEAR' ? 'day' : ($groupBy == 'WEEK' ? 'week' : 'month');
$endDate->modify('+1 '.$padding); $endDate->modify('+1 '.$padding);
$interval = new DateInterval('P1'.substr($groupBy, 0, 1)); $interval = new DateInterval('P1'.substr($groupBy, 0, 1));
$period = new DatePeriod($startDate, $interval, $endDate); $period = new DatePeriod($startDate, $interval, $endDate);
$endDate->modify('-1 '.$padding); $endDate->modify('-1 '.$padding);
$totals = []; $totals = [];
foreach ($period as $d) { foreach ($period as $d)
{
$dateFormat = $groupBy == 'DAYOFYEAR' ? 'z' : ($groupBy == 'WEEK' ? 'W' : 'n'); $dateFormat = $groupBy == 'DAYOFYEAR' ? 'z' : ($groupBy == 'WEEK' ? 'W' : 'n');
$date = $d->format('Y'.$dateFormat); $date = $d->format('Y'.$dateFormat);
$totals[] = isset($data[$date]) ? $data[$date] : 0; $totals[] = isset($data[$date]) ? $data[$date] : 0;
if ($entityType == ENTITY_INVOICE) { if ($entityType == ENTITY_INVOICE)
{
$labelFormat = $groupBy == 'DAYOFYEAR' ? 'j' : ($groupBy == 'WEEK' ? 'W' : 'F'); $labelFormat = $groupBy == 'DAYOFYEAR' ? 'j' : ($groupBy == 'WEEK' ? 'W' : 'F');
$label = $d->format($labelFormat); $label = $d->format($labelFormat);
$labels[] = $label; $labels[] = $label;
} }
} }
$max = max($totals); $max = max($totals);
if ($max > 0) { if ($max > 0)
{
$datasets[] = [ $datasets[] = [
'totals' => $totals, 'totals' => $totals,
'colors' => $entityType == ENTITY_INVOICE ? '78,205,196' : ($entityType == ENTITY_CREDIT ? '199,244,100' : '255,107,107'), 'colors' => $entityType == ENTITY_INVOICE ? '78,205,196' : ($entityType == ENTITY_CREDIT ? '199,244,100' : '255,107,107'),

View File

@ -251,6 +251,10 @@ class Utils
$currency = Currency::find(1); $currency = Currency::find(1);
} }
if (!$value) {
$value = 0;
}
Cache::add('currency', $currency, DEFAULT_QUERY_CACHE); Cache::add('currency', $currency, DEFAULT_QUERY_CACHE);
return $currency->symbol.number_format($value, $currency->precision, $currency->decimal_separator, $currency->thousand_separator); return $currency->symbol.number_format($value, $currency->precision, $currency->decimal_separator, $currency->thousand_separator);
@ -362,7 +366,7 @@ class Utils
$timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE); $timezone = Session::get(SESSION_TIMEZONE, DEFAULT_TIMEZONE);
$format = Session::get(SESSION_DATETIME_FORMAT, DEFAULT_DATETIME_FORMAT); $format = Session::get(SESSION_DATETIME_FORMAT, DEFAULT_DATETIME_FORMAT);
$dateTime = DateTime::createFromFormat('Y-m-d H:i:s', $date); $dateTime = DateTime::createFromFormat('Y-m-d H:i:s', $date);
$dateTime->setTimeZone(new DateTimeZone($timezone)); $dateTime->setTimeZone(new DateTimeZone($timezone));

View File

@ -1,4 +1,4 @@
<?php <?php
return array( return array(
@ -35,11 +35,11 @@ return array(
'invoice_number_short' => 'Facture #', 'invoice_number_short' => 'Facture #',
'po_number' => 'Numéro du bon de commande', 'po_number' => 'Numéro du bon de commande',
'po_number_short' => 'Bon de commande #', 'po_number_short' => 'Bon de commande #',
'frequency_id' => 'Fréquence', 'frequency_id' => 'Fréquence',
'discount' => 'Remise', 'discount' => 'Remise',
'taxes' => 'Taxes', 'taxes' => 'Taxes',
'tax' => 'Taxe', 'tax' => 'Taxe',
'item' => 'Article', 'item' => 'Article',
'description' => 'Description', 'description' => 'Description',
'unit_cost' => 'Coût unitaire', 'unit_cost' => 'Coût unitaire',
'quantity' => 'Quantité', 'quantity' => 'Quantité',
@ -117,11 +117,11 @@ return array(
'billed_client' => 'client facturé', 'billed_client' => 'client facturé',
'billed_clients' => 'clients facturés', 'billed_clients' => 'clients facturés',
'active_client' => 'client actif', 'active_client' => 'client actif',
'active_clients' => 'clients actifs', 'active_clients' => 'clients actifs',
'invoices_past_due' => 'Date limite de paiement dépassée', 'invoices_past_due' => 'Date limite de paiement dépassée',
'upcoming_invoices' => 'Factures à venir', 'upcoming_invoices' => 'Factures à venir',
'average_invoice' => 'Moyenne de facturation', 'average_invoice' => 'Moyenne de facturation',
// list pages // list pages
'archive' => 'Archiver', 'archive' => 'Archiver',
'delete' => 'Supprimer', 'delete' => 'Supprimer',
@ -276,7 +276,7 @@ return array(
// Payment page // Payment page
'secure_payment' => 'Paiement sécurisé', 'secure_payment' => 'Paiement sécurisé',
'card_number' => 'Numéro de carte', 'card_number' => 'Numéro de carte',
'expiration_month' => 'Mois d\'expiration', 'expiration_month' => 'Mois d\'expiration',
'expiration_year' => 'Année d\'expiration', 'expiration_year' => 'Année d\'expiration',
'cvv' => 'CVV', 'cvv' => 'CVV',
@ -297,8 +297,8 @@ return array(
'remove_logo_link' => 'Cliquez ici', 'remove_logo_link' => 'Cliquez ici',
], ],
'logout' => 'Se déconnecter', 'logout' => 'Se déconnecter',
'sign_up_to_save' => 'Connectez vous pour sauvegarder votre travail', 'sign_up_to_save' => 'Connectez vous pour sauvegarder votre travail',
'agree_to_terms' =>'J\'accepte les conditions d\'utilisation d\'Invoice ninja :terms', 'agree_to_terms' =>'J\'accepte les conditions d\'utilisation d\'Invoice ninja :terms',
'terms_of_service' => 'Conditions d\'utilisation', 'terms_of_service' => 'Conditions d\'utilisation',
'email_taken' => 'L\'adresse courriel existe déjà', 'email_taken' => 'L\'adresse courriel existe déjà',
@ -319,7 +319,7 @@ return array(
'field_label' => 'Nom du champ', 'field_label' => 'Nom du champ',
'field_value' => 'Valeur du champ', 'field_value' => 'Valeur du champ',
'edit' => 'Éditer', 'edit' => 'Éditer',
'view_as_recipient' => 'Voir en tant que destinataire', 'view_as_recipient' => 'Voir en tant que destinataire',
// product management // product management
'product_library' => 'Inventaire', 'product_library' => 'Inventaire',
@ -387,7 +387,7 @@ return array(
'notification_quote_sent_subject' => 'Le devis :invoice a été envoyé à :client', 'notification_quote_sent_subject' => 'Le devis :invoice a été envoyé à :client',
'notification_quote_viewed_subject' => 'Le devis :invoice a été visionné par :client', 'notification_quote_viewed_subject' => 'Le devis :invoice a été visionné par :client',
'notification_quote_sent' => 'Le devis :invoice de :amount a été envoyé au client :client.', 'notification_quote_sent' => 'Le devis :invoice de :amount a été envoyé au client :client.',
'notification_quote_viewed' => 'Le devis :invoice de :amount a été visioné par le client :client.', 'notification_quote_viewed' => 'Le devis :invoice de :amount a été visioné par le client :client.',
'session_expired' => 'Votre session a expiré.', 'session_expired' => 'Votre session a expiré.',
@ -426,7 +426,7 @@ return array(
'sample_data' => 'Données fictives présentées', 'sample_data' => 'Données fictives présentées',
'hide' => 'Cacher', 'hide' => 'Cacher',
'new_version_available' => 'Une nouvelle version de :releases_link est disponible. Vous utilisez v:user_version, la plus récente est v:latest_version', 'new_version_available' => 'Une nouvelle version de :releases_link est disponible. Vous utilisez v:user_version, la plus récente est v:latest_version',
'invoice_settings' => 'Paramètres des factures', 'invoice_settings' => 'Paramètres des factures',
'invoice_number_prefix' => 'Préfixe du numéro de facture', 'invoice_number_prefix' => 'Préfixe du numéro de facture',
@ -436,7 +436,7 @@ return array(
'share_invoice_counter' => 'Partager le compteur de facture', 'share_invoice_counter' => 'Partager le compteur de facture',
'invoice_issued_to' => 'Facture destinée à', 'invoice_issued_to' => 'Facture destinée à',
'invalid_counter' => 'Pour éviter un éventuel conflit, merci de définir un préfixe pour le numéro de facture ou pour le numéro de devis', 'invalid_counter' => 'Pour éviter un éventuel conflit, merci de définir un préfixe pour le numéro de facture ou pour le numéro de devis',
'mark_sent' => 'Marquer comme envoyé', 'mark_sent' => 'Marquer comme envoyé',
'gateway_help_1' => ':link to sign up for Authorize.net.', 'gateway_help_1' => ':link to sign up for Authorize.net.',
'gateway_help_2' => ':link to sign up for Authorize.net.', 'gateway_help_2' => ':link to sign up for Authorize.net.',
@ -452,7 +452,7 @@ return array(
'more_designs_self_host_text' => '', 'more_designs_self_host_text' => '',
'buy' => 'Acheter', 'buy' => 'Acheter',
'bought_designs' => 'Les nouveaux modèles ont été ajoutés avec succès', 'bought_designs' => 'Les nouveaux modèles ont été ajoutés avec succès',
'sent' => 'envoyé', 'sent' => 'envoyé',
'timesheets' => 'Feuilles de temps', 'timesheets' => 'Feuilles de temps',
@ -460,7 +460,7 @@ return array(
'payment_cvv' => '*Numéro à 3 ou 4 chiffres au dos de votre carte', 'payment_cvv' => '*Numéro à 3 ou 4 chiffres au dos de votre carte',
'payment_footer1' => '*L\'adresse de facturation doit correspondre à celle enregistrée avec votre carte bancaire', 'payment_footer1' => '*L\'adresse de facturation doit correspondre à celle enregistrée avec votre carte bancaire',
'payment_footer2' => '*Merci de cliquer sur "Payer maintenant" une seule fois. Le processus peut prendre jusqu\'à 1 minute.', 'payment_footer2' => '*Merci de cliquer sur "Payer maintenant" une seule fois. Le processus peut prendre jusqu\'à 1 minute.',
'vat_number' => 'Numéro de TVA', 'vat_number' => 'Numéro de TVA',
'id_number' => 'Numéro ID', 'id_number' => 'Numéro ID',
'white_label_link' => 'Marque blanche', 'white_label_link' => 'Marque blanche',
@ -485,7 +485,7 @@ return array(
'reason_for_canceling' => 'Aidez nous à améliorer notre site en nous disant pourquoi vous partez.', 'reason_for_canceling' => 'Aidez nous à améliorer notre site en nous disant pourquoi vous partez.',
'discount_percent' => 'Pourcent', 'discount_percent' => 'Pourcent',
'discount_amount' => 'Montant', 'discount_amount' => 'Montant',
'invoice_history' => 'Historique des factures', 'invoice_history' => 'Historique des factures',
'quote_history' => 'Historique des devis', 'quote_history' => 'Historique des devis',
'current_version' => 'Version courante', 'current_version' => 'Version courante',
@ -503,7 +503,7 @@ return array(
'payment_email' => 'Email de paiement', 'payment_email' => 'Email de paiement',
'quote_email' => 'Email de déclaration', 'quote_email' => 'Email de déclaration',
'reset_all' => 'Réinitialiser', 'reset_all' => 'Réinitialiser',
'approve' => 'Accepter', 'approve' => 'Accepter',
'token_billing_type_id' => 'Token Billing', 'token_billing_type_id' => 'Token Billing',
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.', 'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
@ -527,7 +527,7 @@ return array(
'order_overview' => 'Order overview', 'order_overview' => 'Order overview',
'match_address' => '*Address must match address associated with credit card.', 'match_address' => '*Address must match address associated with credit card.',
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.', 'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
'default_invoice_footer' => 'Définir par défaut', 'default_invoice_footer' => 'Définir par défaut',
'invoice_footer' => 'Pied de facture', 'invoice_footer' => 'Pied de facture',
'save_as_default_footer' => 'Définir comme pied de facture par défatu', 'save_as_default_footer' => 'Définir comme pied de facture par défatu',
@ -577,7 +577,7 @@ return array(
'notification_quote_approved' => 'The following client :client approved Quote :invoice for :amount.', 'notification_quote_approved' => 'The following client :client approved Quote :invoice for :amount.',
'resend_confirmation' => 'Resend confirmation email', 'resend_confirmation' => 'Resend confirmation email',
'confirmation_resent' => 'The confirmation email was resent', 'confirmation_resent' => 'The confirmation email was resent',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.', 'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Carte de crédit', 'payment_type_credit_card' => 'Carte de crédit',
'payment_type_paypal' => 'PayPal', 'payment_type_paypal' => 'PayPal',
@ -585,7 +585,7 @@ return array(
'knowledge_base' => 'Base de connaissances', 'knowledge_base' => 'Base de connaissances',
'partial' => 'Partiel', 'partial' => 'Partiel',
'partial_remaining' => ':partial de :balance', 'partial_remaining' => ':partial de :balance',
'more_fields' => 'Plus de champs', 'more_fields' => 'Plus de champs',
'less_fields' => 'Moins de champs', 'less_fields' => 'Moins de champs',
'client_name' => 'Nom du client', 'client_name' => 'Nom du client',
@ -597,7 +597,7 @@ return array(
'view_documentation' => 'Voir documentation', 'view_documentation' => 'Voir documentation',
'app_title' => 'Free Open-Source Online Invoicing', 'app_title' => 'Free Open-Source Online Invoicing',
'app_description' => 'Invoice Ninja is a free, open-source solution for invoicing and billing customers. With Invoice Ninja, you can easily build and send beautiful invoices from any device that has access to the web. Your clients can print your invoices, download them as pdf files, and even pay you online from within the system.', 'app_description' => 'Invoice Ninja is a free, open-source solution for invoicing and billing customers. With Invoice Ninja, you can easily build and send beautiful invoices from any device that has access to the web. Your clients can print your invoices, download them as pdf files, and even pay you online from within the system.',
'rows' => 'lignes', 'rows' => 'lignes',
'www' => 'www', 'www' => 'www',
'logo' => 'Logo', 'logo' => 'Logo',
@ -628,7 +628,7 @@ return array(
'archive_task' => 'Archiver tâche', 'archive_task' => 'Archiver tâche',
'restore_task' => 'Restaurer tâche', 'restore_task' => 'Restaurer tâche',
'delete_task' => 'Supprimer tâche', 'delete_task' => 'Supprimer tâche',
'stop_task' => 'Arrêter tâcher', 'stop_task' => 'Arrêter tâche',
'time' => 'Temps', 'time' => 'Temps',
'start' => 'Début', 'start' => 'Début',
'stop' => 'Fin', 'stop' => 'Fin',
@ -682,7 +682,7 @@ return array(
'resume' => 'Resume', 'resume' => 'Resume',
'break_duration' => 'Break', 'break_duration' => 'Break',
'edit_details' => 'Editer détails', 'edit_details' => 'Modifier',
'work' => 'Travail', 'work' => 'Travail',
'timezone_unset' => 'Please :link to set your timezone', 'timezone_unset' => 'Please :link to set your timezone',
'click_here' => 'cliquer ici', 'click_here' => 'cliquer ici',

View File

@ -1,4 +1,4 @@
<?php <?php
return array( return array(
@ -35,11 +35,11 @@ return array(
'invoice_number_short' => 'Facture #', 'invoice_number_short' => 'Facture #',
'po_number' => 'Numéro du bon de commande', 'po_number' => 'Numéro du bon de commande',
'po_number_short' => 'Bon de commande #', 'po_number_short' => 'Bon de commande #',
'frequency_id' => 'Fréquence', 'frequency_id' => 'Fréquence',
'discount' => 'Remise', 'discount' => 'Remise',
'taxes' => 'Taxes', 'taxes' => 'Taxes',
'tax' => 'Taxe', 'tax' => 'Taxe',
'item' => 'Article', 'item' => 'Article',
'description' => 'Description', 'description' => 'Description',
'unit_cost' => 'Coût unitaire', 'unit_cost' => 'Coût unitaire',
'quantity' => 'Quantité', 'quantity' => 'Quantité',
@ -117,11 +117,11 @@ return array(
'billed_client' => 'client facturé', 'billed_client' => 'client facturé',
'billed_clients' => 'clients facturés', 'billed_clients' => 'clients facturés',
'active_client' => 'client actif', 'active_client' => 'client actif',
'active_clients' => 'clients actifs', 'active_clients' => 'clients actifs',
'invoices_past_due' => 'Date limite de paiement dépassée', 'invoices_past_due' => 'Date limite de paiement dépassée',
'upcoming_invoices' => 'Factures à venir', 'upcoming_invoices' => 'Factures à venir',
'average_invoice' => 'Moyenne de facturation', 'average_invoice' => 'Moyenne de facturation',
// list pages // list pages
'archive' => 'Archiver', 'archive' => 'Archiver',
'delete' => 'Supprimer', 'delete' => 'Supprimer',
@ -276,7 +276,7 @@ return array(
// Payment page // Payment page
'secure_payment' => 'Paiement sécurisé', 'secure_payment' => 'Paiement sécurisé',
'card_number' => 'Numéro de carte', 'card_number' => 'Numéro de carte',
'expiration_month' => 'Mois d\'expiration', 'expiration_month' => 'Mois d\'expiration',
'expiration_year' => 'Année d\'expiration', 'expiration_year' => 'Année d\'expiration',
'cvv' => 'CVV', 'cvv' => 'CVV',
@ -297,8 +297,8 @@ return array(
'remove_logo_link' => 'Cliquez ici', 'remove_logo_link' => 'Cliquez ici',
], ],
'logout' => 'Se déconnecter', 'logout' => 'Se déconnecter',
'sign_up_to_save' => 'Connectez vous pour sauvegarder votre travail', 'sign_up_to_save' => 'Connectez vous pour sauvegarder votre travail',
'agree_to_terms' =>'J\'accepte les conditions d\'utilisation d\'Invoice ninja :terms', 'agree_to_terms' =>'J\'accepte les conditions d\'utilisation d\'Invoice ninja :terms',
'terms_of_service' => 'Conditions d\'utilisation', 'terms_of_service' => 'Conditions d\'utilisation',
'email_taken' => 'L\'adresse courriel existe déjà', 'email_taken' => 'L\'adresse courriel existe déjà',
@ -319,7 +319,7 @@ return array(
'field_label' => 'Nom du champ', 'field_label' => 'Nom du champ',
'field_value' => 'Valeur du champ', 'field_value' => 'Valeur du champ',
'edit' => 'Éditer', 'edit' => 'Éditer',
'view_as_recipient' => 'Voir en tant que destinataire', 'view_as_recipient' => 'Voir en tant que destinataire',
// product management // product management
'product_library' => 'Inventaire', 'product_library' => 'Inventaire',
@ -387,7 +387,7 @@ return array(
'notification_quote_sent_subject' => 'Le devis :invoice a été envoyé à :client', 'notification_quote_sent_subject' => 'Le devis :invoice a été envoyé à :client',
'notification_quote_viewed_subject' => 'Le devis :invoice a été visionné par :client', 'notification_quote_viewed_subject' => 'Le devis :invoice a été visionné par :client',
'notification_quote_sent' => 'Le devis :invoice de :amount a été envoyé au client :client.', 'notification_quote_sent' => 'Le devis :invoice de :amount a été envoyé au client :client.',
'notification_quote_viewed' => 'Le devis :invoice de :amount a été visioné par le client :client.', 'notification_quote_viewed' => 'Le devis :invoice de :amount a été visioné par le client :client.',
'session_expired' => 'Votre session a expiré.', 'session_expired' => 'Votre session a expiré.',
@ -426,7 +426,7 @@ return array(
'sample_data' => 'Données fictives présentées', 'sample_data' => 'Données fictives présentées',
'hide' => 'Cacher', 'hide' => 'Cacher',
'new_version_available' => 'Une nouvelle version de :releases_link est disponible. Vous utilisez v:user_version, la plus récente est v:latest_version', 'new_version_available' => 'Une nouvelle version de :releases_link est disponible. Vous utilisez v:user_version, la plus récente est v:latest_version',
'invoice_settings' => 'Paramètres des factures', 'invoice_settings' => 'Paramètres des factures',
'invoice_number_prefix' => 'Préfixe du numéro de facture', 'invoice_number_prefix' => 'Préfixe du numéro de facture',
@ -436,7 +436,7 @@ return array(
'share_invoice_counter' => 'Partager le compteur de facture', 'share_invoice_counter' => 'Partager le compteur de facture',
'invoice_issued_to' => 'Facture destinée à', 'invoice_issued_to' => 'Facture destinée à',
'invalid_counter' => 'Pour éviter un éventuel conflit, merci de définir un préfixe pour le numéro de facture ou pour le numéro de devis', 'invalid_counter' => 'Pour éviter un éventuel conflit, merci de définir un préfixe pour le numéro de facture ou pour le numéro de devis',
'mark_sent' => 'Marquer comme envoyé', 'mark_sent' => 'Marquer comme envoyé',
'gateway_help_1' => ':link to sign up for Authorize.net.', 'gateway_help_1' => ':link to sign up for Authorize.net.',
'gateway_help_2' => ':link to sign up for Authorize.net.', 'gateway_help_2' => ':link to sign up for Authorize.net.',
@ -452,7 +452,7 @@ return array(
'more_designs_self_host_text' => '', 'more_designs_self_host_text' => '',
'buy' => 'Acheter', 'buy' => 'Acheter',
'bought_designs' => 'Les nouveaux modèles ont été ajoutés avec succès', 'bought_designs' => 'Les nouveaux modèles ont été ajoutés avec succès',
'sent' => 'envoyé', 'sent' => 'envoyé',
'timesheets' => 'Feuilles de temps', 'timesheets' => 'Feuilles de temps',
@ -460,7 +460,7 @@ return array(
'payment_cvv' => '*This is the 3-4 digit number onthe back of your card', 'payment_cvv' => '*This is the 3-4 digit number onthe back of your card',
'payment_footer1' => '*Billing address must match address associated with credit card.', 'payment_footer1' => '*Billing address must match address associated with credit card.',
'payment_footer2' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.', 'payment_footer2' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
'vat_number' => 'Numéro de TVA', 'vat_number' => 'Numéro de TVA',
'id_number' => 'Numéro ID', 'id_number' => 'Numéro ID',
'white_label_link' => 'Marque blanche', 'white_label_link' => 'Marque blanche',
@ -485,7 +485,7 @@ return array(
'reason_for_canceling' => 'Aidez nous à améliorer notre site en nous disant pourquoi vous partez.', 'reason_for_canceling' => 'Aidez nous à améliorer notre site en nous disant pourquoi vous partez.',
'discount_percent' => 'Pourcent', 'discount_percent' => 'Pourcent',
'discount_amount' => 'Montant', 'discount_amount' => 'Montant',
'invoice_history' => 'Historique des factures', 'invoice_history' => 'Historique des factures',
'quote_history' => 'Historique des devis', 'quote_history' => 'Historique des devis',
'current_version' => 'Version courante', 'current_version' => 'Version courante',
@ -503,7 +503,7 @@ return array(
'payment_email' => 'Courriel de paiement', 'payment_email' => 'Courriel de paiement',
'quote_email' => 'Courriel de devis', 'quote_email' => 'Courriel de devis',
'reset_all' => 'Tout remettre à zéro', 'reset_all' => 'Tout remettre à zéro',
'approve' => 'Approuver', 'approve' => 'Approuver',
'token_billing_type_id' => 'Token Billing', 'token_billing_type_id' => 'Token Billing',
'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.', 'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.',
@ -527,7 +527,7 @@ return array(
'order_overview' => 'Order overview', 'order_overview' => 'Order overview',
'match_address' => '*Address must match address associated with credit card.', 'match_address' => '*Address must match address associated with credit card.',
'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.', 'click_once' => '*Please click "PAY NOW" only once - transaction may take up to 1 minute to process.',
'default_invoice_footer' => 'Set default invoice footer', 'default_invoice_footer' => 'Set default invoice footer',
'invoice_footer' => 'Invoice footer', 'invoice_footer' => 'Invoice footer',
'save_as_default_footer' => 'Save as default footer', 'save_as_default_footer' => 'Save as default footer',
@ -571,13 +571,13 @@ return array(
'send_email' => 'Send email', 'send_email' => 'Send email',
'set_password' => 'Set Password', 'set_password' => 'Set Password',
'converted' => 'Converted', 'converted' => 'Converted',
'email_approved' => 'Email me when a quote is <b>approved</b>', 'email_approved' => 'Email me when a quote is <b>approved</b>',
'notification_quote_approved_subject' => 'Quote :invoice was approved by :client', 'notification_quote_approved_subject' => 'Quote :invoice was approved by :client',
'notification_quote_approved' => 'The following client :client approved Quote :invoice for :amount.', 'notification_quote_approved' => 'The following client :client approved Quote :invoice for :amount.',
'resend_confirmation' => 'Resend confirmation email', 'resend_confirmation' => 'Resend confirmation email',
'confirmation_resent' => 'The confirmation email was resent', 'confirmation_resent' => 'The confirmation email was resent',
'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.', 'gateway_help_42' => ':link to sign up for BitPay.<br/>Note: use a Legacy API Key, not an API token.',
'payment_type_credit_card' => 'Credit card', 'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal', 'payment_type_paypal' => 'PayPal',
@ -597,7 +597,7 @@ return array(
'view_documentation' => 'View Documentation', 'view_documentation' => 'View Documentation',
'app_title' => 'Free Open-Source Online Invoicing', 'app_title' => 'Free Open-Source Online Invoicing',
'app_description' => 'Invoice Ninja is a free, open-source solution for invoicing and billing customers. With Invoice Ninja, you can easily build and send beautiful invoices from any device that has access to the web. Your clients can print your invoices, download them as pdf files, and even pay you online from within the system.', 'app_description' => 'Invoice Ninja is a free, open-source solution for invoicing and billing customers. With Invoice Ninja, you can easily build and send beautiful invoices from any device that has access to the web. Your clients can print your invoices, download them as pdf files, and even pay you online from within the system.',
'rows' => 'rows', 'rows' => 'rows',
'www' => 'www', 'www' => 'www',
'logo' => 'Logo', 'logo' => 'Logo',
@ -619,50 +619,50 @@ return array(
'last_invoice_sent' => 'Last invoice sent :date', 'last_invoice_sent' => 'Last invoice sent :date',
'processed_updates' => 'Successfully completed update', 'processed_updates' => 'Successfully completed update',
'tasks' => 'Tasks', 'tasks' => 'Tâches',
'new_task' => 'New Task', 'new_task' => 'Nouvelle Tâche',
'start_time' => 'Start Time', 'start_time' => 'Démarrée à',
'created_task' => 'Successfully created task', 'created_task' => 'Tâche créée avec succès',
'updated_task' => 'Successfully updated task', 'updated_task' => 'Tâche modifiée avec succès',
'edit_task' => 'Edit Task', 'edit_task' => 'Edit Task',
'archive_task' => 'Archive Task', 'archive_task' => 'Archiver la Tâche',
'restore_task' => 'Restore Task', 'restore_task' => 'Restaurer la Tâche',
'delete_task' => 'Delete Task', 'delete_task' => 'Supprimer la Tâche',
'stop_task' => 'Stop Task', 'stop_task' => 'Arrêter la Tâche',
'time' => 'Time', 'time' => 'Time',
'start' => 'Start', 'start' => 'Démarrer',
'stop' => 'Stop', 'stop' => 'Arrêter',
'now' => 'Now', 'now' => 'Now',
'timer' => 'Timer', 'timer' => 'Timer',
'manual' => 'Manual', 'manual' => 'Manual',
'date_and_time' => 'Date & Time', 'date_and_time' => 'Date & Time',
'second' => 'second', 'second' => 'seconde',
'seconds' => 'seconds', 'seconds' => 'secondes',
'minute' => 'minute', 'minute' => 'minute',
'minutes' => 'minutes', 'minutes' => 'minutes',
'hour' => 'hour', 'hour' => 'heure',
'hours' => 'hours', 'hours' => 'heures',
'task_details' => 'Task Details', 'task_details' => 'Détails de la Tâche',
'duration' => 'Duration', 'duration' => 'Durée',
'end_time' => 'End Time', 'end_time' => 'Arrêtée à',
'end' => 'End', 'end' => 'End',
'invoiced' => 'Invoiced', 'invoiced' => 'Invoiced',
'logged' => 'Logged', 'logged' => 'Logged',
'running' => 'Running', 'running' => 'Running',
'task_error_multiple_clients' => 'The tasks can\'t belong to different clients', 'task_error_multiple_clients' => 'Une tâche ne peut appartenir à plusieurs clients',
'task_error_running' => 'Please stop running tasks first', 'task_error_running' => 'Merci d\'arrêter les tâches en cours',
'task_error_invoiced' => 'Tasks have already been invoiced', 'task_error_invoiced' => 'Ces tâches ont déjà été facturées',
'restored_task' => 'Successfully restored task', 'restored_task' => 'Tâche restaurée avec succès',
'archived_task' => 'Successfully archived task', 'archived_task' => 'Tâche archivée avec succès',
'archived_tasks' => 'Successfully archived :count tasks', 'archived_tasks' => ':count tâches archivées avec succès',
'deleted_task' => 'Successfully deleted task', 'deleted_task' => 'Tâche supprimée avec succès',
'deleted_tasks' => 'Successfully deleted :count tasks', 'deleted_tasks' => ':count tâches supprimées avec succès',
'create_task' => 'Create Task', 'create_task' => 'Créer une Tâche',
'stopped_task' => 'Successfully stopped task', 'stopped_task' => 'Tâche arrêtée avec succès',
'invoice_task' => 'Invoice Task', 'invoice_task' => 'Facturer Tâche',
'invoice_labels' => 'Invoice Labels', 'invoice_labels' => 'Invoice Labels',
'prefix' => 'Prefix', 'prefix' => 'Préfixe',
'counter' => 'Counter', 'counter' => 'Compteur',
'payment_type_dwolla' => 'Dwolla', 'payment_type_dwolla' => 'Dwolla',
'gateway_help_43' => ':link to sign up for Dwolla.', 'gateway_help_43' => ':link to sign up for Dwolla.',
@ -681,12 +681,12 @@ return array(
'pro_plan_feature7' => 'Customize Invoice Field Titles & Numbering', 'pro_plan_feature7' => 'Customize Invoice Field Titles & Numbering',
'pro_plan_feature8' => 'Option to Attach PDFs to Client Emails', 'pro_plan_feature8' => 'Option to Attach PDFs to Client Emails',
'resume' => 'Resume', 'resume' => 'Continuer',
'break_duration' => 'Break', 'break_duration' => 'Pause',
'edit_details' => 'Edit Details', 'edit_details' => 'Modifier',
'work' => 'Work', 'work' => 'Travail',
'timezone_unset' => 'Please :link to set your timezone', 'timezone_unset' => 'Please :link to set your timezone',
'click_here' => 'click here', 'click_here' => 'cliquer içi',
'email_receipt' => 'Email payment receipt to the client', 'email_receipt' => 'Email payment receipt to the client',
'created_payment_emailed_client' => 'Successfully created payment and emailed client', 'created_payment_emailed_client' => 'Successfully created payment and emailed client',