1
0
mirror of https://github.com/invoiceninja/invoiceninja.git synced 2024-11-08 20:22:42 +01:00

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;
use Auth;
use Config;
use Input;
use Utils;
use DB;
@ -149,53 +150,90 @@ class ReportController extends BaseController
$reportTotals['balance'][$currencyId] += $record->balance;
}
if ($action == 'export') {
if ($action == 'export')
{
self::export($exportData, $reportTotals);
}
}
if ($enableChart) {
foreach ([ENTITY_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT] as $entityType) {
$records = DB::table($entityType.'s')
->select(DB::raw('sum(amount) as total, concat(YEAR('.$entityType.'_date), '.$groupBy.'('.$entityType.'_date)) 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 ($enableChart)
{
foreach ([ENTITY_INVOICE, ENTITY_PAYMENT, ENTITY_CREDIT] as $entityType)
{
// SQLite does not support the YEAR(), MONTH(), WEEK() and similar functions.
// Let's see if SQLite is being used.
if (Config::get('database.connections.'.Config::get('database.default').'.driver') == 'sqlite')
{
// 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)
->where('is_recurring', '=', false);
}
$totals = $records->lists('total');
$dates = $records->lists($groupBy);
$data = array_combine($dates, $totals);
$dates = $records->lists($groupBy);
$data = array_combine($dates, $totals);
$padding = $groupBy == 'DAYOFYEAR' ? 'day' : ($groupBy == 'WEEK' ? 'week' : 'month');
$endDate->modify('+1 '.$padding);
$interval = new DateInterval('P1'.substr($groupBy, 0, 1));
$period = new DatePeriod($startDate, $interval, $endDate);
$period = new DatePeriod($startDate, $interval, $endDate);
$endDate->modify('-1 '.$padding);
$totals = [];
foreach ($period as $d) {
foreach ($period as $d)
{
$dateFormat = $groupBy == 'DAYOFYEAR' ? 'z' : ($groupBy == 'WEEK' ? 'W' : 'n');
$date = $d->format('Y'.$dateFormat);
$totals[] = isset($data[$date]) ? $data[$date] : 0;
if ($entityType == ENTITY_INVOICE) {
if ($entityType == ENTITY_INVOICE)
{
$labelFormat = $groupBy == 'DAYOFYEAR' ? 'j' : ($groupBy == 'WEEK' ? 'W' : 'F');
$label = $d->format($labelFormat);
$label = $d->format($labelFormat);
$labels[] = $label;
}
}
$max = max($totals);
if ($max > 0) {
if ($max > 0)
{
$datasets[] = [
'totals' => $totals,
'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);
}
if (!$value) {
$value = 0;
}
Cache::add('currency', $currency, DEFAULT_QUERY_CACHE);
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);
$format = Session::get(SESSION_DATETIME_FORMAT, DEFAULT_DATETIME_FORMAT);
$dateTime = DateTime::createFromFormat('Y-m-d H:i:s', $date);
$dateTime->setTimeZone(new DateTimeZone($timezone));

View File

@ -1,4 +1,4 @@
<?php
<?php
return array(
@ -35,11 +35,11 @@ return array(
'invoice_number_short' => 'Facture #',
'po_number' => 'Numéro du bon de commande',
'po_number_short' => 'Bon de commande #',
'frequency_id' => 'Fréquence',
'frequency_id' => 'Fréquence',
'discount' => 'Remise',
'taxes' => 'Taxes',
'tax' => 'Taxe',
'item' => 'Article',
'item' => 'Article',
'description' => 'Description',
'unit_cost' => 'Coût unitaire',
'quantity' => 'Quantité',
@ -117,11 +117,11 @@ return array(
'billed_client' => 'client facturé',
'billed_clients' => 'clients facturés',
'active_client' => 'client actif',
'active_clients' => 'clients actifs',
'active_clients' => 'clients actifs',
'invoices_past_due' => 'Date limite de paiement dépassée',
'upcoming_invoices' => 'Factures à venir',
'average_invoice' => 'Moyenne de facturation',
// list pages
'archive' => 'Archiver',
'delete' => 'Supprimer',
@ -276,7 +276,7 @@ return array(
// Payment page
'secure_payment' => 'Paiement sécurisé',
'card_number' => 'Numéro de carte',
'expiration_month' => 'Mois d\'expiration',
'expiration_month' => 'Mois d\'expiration',
'expiration_year' => 'Année d\'expiration',
'cvv' => 'CVV',
@ -297,8 +297,8 @@ return array(
'remove_logo_link' => 'Cliquez ici',
],
'logout' => 'Se déconnecter',
'sign_up_to_save' => 'Connectez vous pour sauvegarder votre travail',
'logout' => 'Se déconnecter',
'sign_up_to_save' => 'Connectez vous pour sauvegarder votre travail',
'agree_to_terms' =>'J\'accepte les conditions d\'utilisation d\'Invoice ninja :terms',
'terms_of_service' => 'Conditions d\'utilisation',
'email_taken' => 'L\'adresse courriel existe déjà',
@ -319,7 +319,7 @@ return array(
'field_label' => 'Nom du champ',
'field_value' => 'Valeur du champ',
'edit' => 'Éditer',
'view_as_recipient' => 'Voir en tant que destinataire',
'view_as_recipient' => 'Voir en tant que destinataire',
// product management
'product_library' => 'Inventaire',
@ -387,7 +387,7 @@ return array(
'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_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é.',
@ -426,7 +426,7 @@ return array(
'sample_data' => 'Données fictives présentées',
'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',
'invoice_settings' => 'Paramètres des factures',
'invoice_number_prefix' => 'Préfixe du numéro de facture',
@ -436,7 +436,7 @@ return array(
'share_invoice_counter' => 'Partager le compteur de facture',
'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',
'mark_sent' => 'Marquer comme envoyé',
'mark_sent' => 'Marquer comme envoyé',
'gateway_help_1' => ':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' => '',
'buy' => 'Acheter',
'bought_designs' => 'Les nouveaux modèles ont été ajoutés avec succès',
'sent' => 'envoyé',
'timesheets' => 'Feuilles de temps',
@ -460,7 +460,7 @@ return array(
'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_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',
'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.',
'discount_percent' => 'Pourcent',
'discount_amount' => 'Montant',
'invoice_history' => 'Historique des factures',
'quote_history' => 'Historique des devis',
'current_version' => 'Version courante',
@ -503,7 +503,7 @@ return array(
'payment_email' => 'Email de paiement',
'quote_email' => 'Email de déclaration',
'reset_all' => 'Réinitialiser',
'approve' => 'Accepter',
'approve' => 'Accepter',
'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.',
@ -527,7 +527,7 @@ return array(
'order_overview' => 'Order overview',
'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.',
'default_invoice_footer' => 'Définir par défaut',
'invoice_footer' => 'Pied de facture',
'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.',
'resend_confirmation' => 'Resend confirmation email',
'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.',
'payment_type_credit_card' => 'Carte de crédit',
'payment_type_paypal' => 'PayPal',
@ -585,7 +585,7 @@ return array(
'knowledge_base' => 'Base de connaissances',
'partial' => 'Partiel',
'partial_remaining' => ':partial de :balance',
'more_fields' => 'Plus de champs',
'less_fields' => 'Moins de champs',
'client_name' => 'Nom du client',
@ -597,7 +597,7 @@ return array(
'view_documentation' => 'Voir documentation',
'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.',
'rows' => 'lignes',
'www' => 'www',
'logo' => 'Logo',
@ -628,7 +628,7 @@ return array(
'archive_task' => 'Archiver tâche',
'restore_task' => 'Restaurer tâche',
'delete_task' => 'Supprimer tâche',
'stop_task' => 'Arrêter tâcher',
'stop_task' => 'Arrêter tâche',
'time' => 'Temps',
'start' => 'Début',
'stop' => 'Fin',
@ -682,7 +682,7 @@ return array(
'resume' => 'Resume',
'break_duration' => 'Break',
'edit_details' => 'Editer détails',
'edit_details' => 'Modifier',
'work' => 'Travail',
'timezone_unset' => 'Please :link to set your timezone',
'click_here' => 'cliquer ici',

View File

@ -1,4 +1,4 @@
<?php
<?php
return array(
@ -35,11 +35,11 @@ return array(
'invoice_number_short' => 'Facture #',
'po_number' => 'Numéro du bon de commande',
'po_number_short' => 'Bon de commande #',
'frequency_id' => 'Fréquence',
'frequency_id' => 'Fréquence',
'discount' => 'Remise',
'taxes' => 'Taxes',
'tax' => 'Taxe',
'item' => 'Article',
'item' => 'Article',
'description' => 'Description',
'unit_cost' => 'Coût unitaire',
'quantity' => 'Quantité',
@ -117,11 +117,11 @@ return array(
'billed_client' => 'client facturé',
'billed_clients' => 'clients facturés',
'active_client' => 'client actif',
'active_clients' => 'clients actifs',
'active_clients' => 'clients actifs',
'invoices_past_due' => 'Date limite de paiement dépassée',
'upcoming_invoices' => 'Factures à venir',
'average_invoice' => 'Moyenne de facturation',
// list pages
'archive' => 'Archiver',
'delete' => 'Supprimer',
@ -276,7 +276,7 @@ return array(
// Payment page
'secure_payment' => 'Paiement sécurisé',
'card_number' => 'Numéro de carte',
'expiration_month' => 'Mois d\'expiration',
'expiration_month' => 'Mois d\'expiration',
'expiration_year' => 'Année d\'expiration',
'cvv' => 'CVV',
@ -297,8 +297,8 @@ return array(
'remove_logo_link' => 'Cliquez ici',
],
'logout' => 'Se déconnecter',
'sign_up_to_save' => 'Connectez vous pour sauvegarder votre travail',
'logout' => 'Se déconnecter',
'sign_up_to_save' => 'Connectez vous pour sauvegarder votre travail',
'agree_to_terms' =>'J\'accepte les conditions d\'utilisation d\'Invoice ninja :terms',
'terms_of_service' => 'Conditions d\'utilisation',
'email_taken' => 'L\'adresse courriel existe déjà',
@ -319,7 +319,7 @@ return array(
'field_label' => 'Nom du champ',
'field_value' => 'Valeur du champ',
'edit' => 'Éditer',
'view_as_recipient' => 'Voir en tant que destinataire',
'view_as_recipient' => 'Voir en tant que destinataire',
// product management
'product_library' => 'Inventaire',
@ -387,7 +387,7 @@ return array(
'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_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é.',
@ -426,7 +426,7 @@ return array(
'sample_data' => 'Données fictives présentées',
'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',
'invoice_settings' => 'Paramètres des factures',
'invoice_number_prefix' => 'Préfixe du numéro de facture',
@ -436,7 +436,7 @@ return array(
'share_invoice_counter' => 'Partager le compteur de facture',
'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',
'mark_sent' => 'Marquer comme envoyé',
'mark_sent' => 'Marquer comme envoyé',
'gateway_help_1' => ':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' => '',
'buy' => 'Acheter',
'bought_designs' => 'Les nouveaux modèles ont été ajoutés avec succès',
'sent' => 'envoyé',
'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_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.',
'vat_number' => 'Numéro de TVA',
'vat_number' => 'Numéro de TVA',
'id_number' => 'Numéro ID',
'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.',
'discount_percent' => 'Pourcent',
'discount_amount' => 'Montant',
'invoice_history' => 'Historique des factures',
'quote_history' => 'Historique des devis',
'current_version' => 'Version courante',
@ -503,7 +503,7 @@ return array(
'payment_email' => 'Courriel de paiement',
'quote_email' => 'Courriel de devis',
'reset_all' => 'Tout remettre à zéro',
'approve' => 'Approuver',
'approve' => 'Approuver',
'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.',
@ -527,7 +527,7 @@ return array(
'order_overview' => 'Order overview',
'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.',
'default_invoice_footer' => 'Set default invoice footer',
'invoice_footer' => 'Invoice footer',
'save_as_default_footer' => 'Save as default footer',
@ -571,13 +571,13 @@ return array(
'send_email' => 'Send email',
'set_password' => 'Set Password',
'converted' => 'Converted',
'email_approved' => 'Email me when a quote is <b>approved</b>',
'notification_quote_approved_subject' => 'Quote :invoice was approved by :client',
'notification_quote_approved' => 'The following client :client approved Quote :invoice for :amount.',
'resend_confirmation' => 'Resend confirmation email',
'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.',
'payment_type_credit_card' => 'Credit card',
'payment_type_paypal' => 'PayPal',
@ -597,7 +597,7 @@ return array(
'view_documentation' => 'View Documentation',
'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.',
'rows' => 'rows',
'www' => 'www',
'logo' => 'Logo',
@ -619,50 +619,50 @@ return array(
'last_invoice_sent' => 'Last invoice sent :date',
'processed_updates' => 'Successfully completed update',
'tasks' => 'Tasks',
'new_task' => 'New Task',
'start_time' => 'Start Time',
'created_task' => 'Successfully created task',
'updated_task' => 'Successfully updated task',
'tasks' => 'Tâches',
'new_task' => 'Nouvelle Tâche',
'start_time' => 'Démarrée à',
'created_task' => 'Tâche créée avec succès',
'updated_task' => 'Tâche modifiée avec succès',
'edit_task' => 'Edit Task',
'archive_task' => 'Archive Task',
'restore_task' => 'Restore Task',
'delete_task' => 'Delete Task',
'stop_task' => 'Stop Task',
'archive_task' => 'Archiver la Tâche',
'restore_task' => 'Restaurer la Tâche',
'delete_task' => 'Supprimer la Tâche',
'stop_task' => 'Arrêter la Tâche',
'time' => 'Time',
'start' => 'Start',
'stop' => 'Stop',
'start' => 'Démarrer',
'stop' => 'Arrêter',
'now' => 'Now',
'timer' => 'Timer',
'manual' => 'Manual',
'date_and_time' => 'Date & Time',
'second' => 'second',
'seconds' => 'seconds',
'second' => 'seconde',
'seconds' => 'secondes',
'minute' => 'minute',
'minutes' => 'minutes',
'hour' => 'hour',
'hours' => 'hours',
'task_details' => 'Task Details',
'duration' => 'Duration',
'end_time' => 'End Time',
'hour' => 'heure',
'hours' => 'heures',
'task_details' => 'Détails de la Tâche',
'duration' => 'Durée',
'end_time' => 'Arrêtée à',
'end' => 'End',
'invoiced' => 'Invoiced',
'logged' => 'Logged',
'running' => 'Running',
'task_error_multiple_clients' => 'The tasks can\'t belong to different clients',
'task_error_running' => 'Please stop running tasks first',
'task_error_invoiced' => 'Tasks have already been invoiced',
'restored_task' => 'Successfully restored task',
'archived_task' => 'Successfully archived task',
'archived_tasks' => 'Successfully archived :count tasks',
'deleted_task' => 'Successfully deleted task',
'deleted_tasks' => 'Successfully deleted :count tasks',
'create_task' => 'Create Task',
'stopped_task' => 'Successfully stopped task',
'invoice_task' => 'Invoice Task',
'task_error_multiple_clients' => 'Une tâche ne peut appartenir à plusieurs clients',
'task_error_running' => 'Merci d\'arrêter les tâches en cours',
'task_error_invoiced' => 'Ces tâches ont déjà été facturées',
'restored_task' => 'Tâche restaurée avec succès',
'archived_task' => 'Tâche archivée avec succès',
'archived_tasks' => ':count tâches archivées avec succès',
'deleted_task' => 'Tâche supprimée avec succès',
'deleted_tasks' => ':count tâches supprimées avec succès',
'create_task' => 'Créer une Tâche',
'stopped_task' => 'Tâche arrêtée avec succès',
'invoice_task' => 'Facturer Tâche',
'invoice_labels' => 'Invoice Labels',
'prefix' => 'Prefix',
'counter' => 'Counter',
'prefix' => 'Préfixe',
'counter' => 'Compteur',
'payment_type_dwolla' => '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_feature8' => 'Option to Attach PDFs to Client Emails',
'resume' => 'Resume',
'break_duration' => 'Break',
'edit_details' => 'Edit Details',
'work' => 'Work',
'resume' => 'Continuer',
'break_duration' => 'Pause',
'edit_details' => 'Modifier',
'work' => 'Travail',
'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',
'created_payment_emailed_client' => 'Successfully created payment and emailed client',