From 3a50fd6aa2c74c93e1aa0ea504989f2ea953ef35 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Sun, 13 Apr 2014 16:34:58 +0300 Subject: [PATCH 1/3] Working on pro plan --- app/controllers/AccountController.php | 4 ++-- app/controllers/ClientController.php | 4 ++-- app/controllers/InvoiceController.php | 2 ++ app/controllers/PaymentController.php | 11 +++++++--- app/lang/de/texts.php | 5 +++++ app/lang/en/texts.php | 4 ++-- app/lang/es/texts.php | 4 ++++ app/lang/fr/texts.php | 4 ++++ app/lang/it/texts.php | 4 ++++ app/lang/nl/texts.php | 5 +++++ app/lang/pt_BR/texts.php | 6 ++++++ app/models/Account.php | 5 ----- app/models/User.php | 5 +++++ app/ninja/repositories/AccountRepository.php | 22 +++++++++++++------- app/routes.php | 17 ++++++++++----- app/views/accounts/payments.blade.php | 10 +++------ app/views/invoices/edit.blade.php | 9 +++----- public/js/script.js | 13 ++++++------ 18 files changed, 88 insertions(+), 46 deletions(-) diff --git a/app/controllers/AccountController.php b/app/controllers/AccountController.php index 3f8706f19d..4aecedeef5 100755 --- a/app/controllers/AccountController.php +++ b/app/controllers/AccountController.php @@ -370,9 +370,9 @@ class AccountController extends \BaseController { $csv->heading = false; $csv->auto($name); - if (count($csv->data) + Client::scope()->count() > MAX_NUM_CLIENTS) + if (count($csv->data) + Client::scope()->count() > Auth::user()->getMaxNumClients()) { - $message = Utils::pluralize('limit_clients', MAX_NUM_CLIENTS); + $message = Utils::pluralize('limit_clients', Auth::user()->getMaxNumClients()); Session::flash('error', $message); return Redirect::to('company/import_export'); } diff --git a/app/controllers/ClientController.php b/app/controllers/ClientController.php index a8238e1f24..bc6fc75785 100755 --- a/app/controllers/ClientController.php +++ b/app/controllers/ClientController.php @@ -67,9 +67,9 @@ class ClientController extends \BaseController { */ public function create() { - if (Client::scope()->count() > MAX_NUM_CLIENTS) + if (Client::scope()->count() > Auth::user()->getMaxNumClients()) { - return View::make('error', ['error' => "Sorry, you've exceeded the limit of " . MAX_NUM_CLIENTS . " clients"]); + return View::make('error', ['error' => "Sorry, you've exceeded the limit of " . Auth::user()->getMaxNumClients() . " clients"]); } $data = array( diff --git a/app/controllers/InvoiceController.php b/app/controllers/InvoiceController.php index ec66c426a5..eb4fba8bfb 100755 --- a/app/controllers/InvoiceController.php +++ b/app/controllers/InvoiceController.php @@ -142,6 +142,7 @@ class InvoiceController extends \BaseController { $invoice->invoice_date = Utils::fromSqlDate($invoice->invoice_date); $invoice->due_date = Utils::fromSqlDate($invoice->due_date); + $invoice->is_pro = $client->account->isPro(); $data = array( 'showBreadcrumbs' => false, @@ -162,6 +163,7 @@ class InvoiceController extends \BaseController { $invoice->due_date = Utils::fromSqlDate($invoice->due_date); $invoice->start_date = Utils::fromSqlDate($invoice->start_date); $invoice->end_date = Utils::fromSqlDate($invoice->end_date); + $invoice->is_pro = Auth::user()->isPro(); $contactIds = DB::table('invitations') ->join('contacts', 'contacts.id', '=','invitations.contact_id') diff --git a/app/controllers/PaymentController.php b/app/controllers/PaymentController.php index 285d4ed872..42bce237bc 100755 --- a/app/controllers/PaymentController.php +++ b/app/controllers/PaymentController.php @@ -116,12 +116,10 @@ class PaymentController extends \BaseController $gateway->$function($val); } - /* if (!Utils::isProd()) { $gateway->setTestMode(true); - } - */ + } return $gateway; } @@ -427,6 +425,13 @@ class PaymentController extends \BaseController $payment->save(); + if ($invoice->account->account_key == NINJA_ACCOUNT_KEY) + { + $account = Account::find($invoice->client->public_id); + $account->pro_plan_paid = date_create()->format('Y-m-d'); + $account->save(); + } + return $payment; } diff --git a/app/lang/de/texts.php b/app/lang/de/texts.php index 01660aa02a..d7aa08c97d 100644 --- a/app/lang/de/texts.php +++ b/app/lang/de/texts.php @@ -305,5 +305,10 @@ return array( 'password' => 'Passwort', 'invoice_subject' => 'Neue Rechnung von :account', 'close' => 'Schließen', + + 'pro_plan_product' => 'Pro Plan', + 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', + 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + ); diff --git a/app/lang/en/texts.php b/app/lang/en/texts.php index e690961728..56de18ac6d 100644 --- a/app/lang/en/texts.php +++ b/app/lang/en/texts.php @@ -307,7 +307,7 @@ return array( 'password' => 'Password', 'pro_plan_product' => 'Pro Plan', - 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan', - 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your membership will begin.', + 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', + 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', ); diff --git a/app/lang/es/texts.php b/app/lang/es/texts.php index 04c9875638..62b42794c3 100644 --- a/app/lang/es/texts.php +++ b/app/lang/es/texts.php @@ -305,5 +305,9 @@ return array( 'erase_data' => 'This will permanently erase your data.', 'password' => 'Password', + 'pro_plan_product' => 'Pro Plan', + 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', + 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + ); diff --git a/app/lang/fr/texts.php b/app/lang/fr/texts.php index f69c0e51df..441c8b795a 100644 --- a/app/lang/fr/texts.php +++ b/app/lang/fr/texts.php @@ -305,6 +305,10 @@ return array( 'success_message' => 'You have succesfully registered. Please visit the link in the account confirmation email to verify your email address.', 'erase_data' => 'This will permanently erase your data.', 'password' => 'Password', + + 'pro_plan_product' => 'Pro Plan', + 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', + 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', ); diff --git a/app/lang/it/texts.php b/app/lang/it/texts.php index 19c9ea4430..e70b99fef1 100644 --- a/app/lang/it/texts.php +++ b/app/lang/it/texts.php @@ -306,5 +306,9 @@ return array( 'erase_data' => 'Questo eliminerà definitivamente i tuoi dati.', 'password' => 'Password', + 'pro_plan_product' => 'Pro Plan', + 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', + 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + ); diff --git a/app/lang/nl/texts.php b/app/lang/nl/texts.php index 00dfd8c3fa..fcc58959f4 100644 --- a/app/lang/nl/texts.php +++ b/app/lang/nl/texts.php @@ -305,5 +305,10 @@ return array( 'password' => 'Wachtwoord', 'invoice_subject' => 'Nieuwe factuur van :account', 'close' => 'Sluiten', + + 'pro_plan_product' => 'Pro Plan', + 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', + 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + ); diff --git a/app/lang/pt_BR/texts.php b/app/lang/pt_BR/texts.php index 8d9bd4126e..f43223bbfb 100644 --- a/app/lang/pt_BR/texts.php +++ b/app/lang/pt_BR/texts.php @@ -293,4 +293,10 @@ return array( 'close' => 'Fechar', 'invoice_subject' => 'Nova fatura de :account', 'payment_subject' => 'Recebido Pagamento de', + + 'pro_plan_product' => 'Pro Plan', + 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', + 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + + ); diff --git a/app/models/Account.php b/app/models/Account.php index bd4927970c..25adac65d1 100755 --- a/app/models/Account.php +++ b/app/models/Account.php @@ -220,11 +220,6 @@ class Account extends Eloquent return true; } - if (!Auth::check()) - { - return false; - } - $datePaid = $this->pro_plan_paid; if (!$datePaid || $datePaid == '0000-00-00') diff --git a/app/models/User.php b/app/models/User.php index 275e4de964..cbdfb040d9 100755 --- a/app/models/User.php +++ b/app/models/User.php @@ -133,4 +133,9 @@ class User extends ConfideUser implements UserInterface, RemindableInterface return true; } } + + public function getMaxNumClients() + { + return $this->isPro() ? MAX_NUM_CLIENTS_PRO : MAX_NUM_CLIENTS; + } } \ No newline at end of file diff --git a/app/ninja/repositories/AccountRepository.php b/app/ninja/repositories/AccountRepository.php index 75e5ad64de..9fc3d25f82 100755 --- a/app/ninja/repositories/AccountRepository.php +++ b/app/ninja/repositories/AccountRepository.php @@ -11,6 +11,7 @@ use Auth; use Invitation; use Invoice; use InvoiceItem; +use AccountGateway; class AccountRepository { @@ -104,19 +105,18 @@ class AccountRepository } $account = Auth::user()->account; + $lastInvoice = Invoice::withTrashed()->whereAccountId($account->id)->orderBy('public_id', 'DESC')->first(); + $publicId = $lastInvoice ? ($lastInvoice->public_id + 1) : 1; - $ninjaAccount = $this->getNinjaAccount(); + $ninjaAccount = $this->getNinjaAccount($publicId); $ninjaClient = $this->getNinjaClient($ninjaAccount); - $invoice = $this->createNinjaInvoice($ninjaAccount, $ninjaClient); + $invoice = $this->createNinjaInvoice($publicId, $ninjaAccount, $ninjaClient); return $invoice; } - private function createNinjaInvoice($account, $client) + private function createNinjaInvoice($publicId, $account, $client) { - $lastInvoice = Invoice::withTrashed()->whereAccountId($account->id)->orderBy('public_id', 'DESC')->first(); - $publicId = $lastInvoice ? ($lastInvoice->public_id + 1) : 1; - $invoice = new Invoice(); $invoice->account_id = $account->id; $invoice->user_id = $account->users()->first()->id; @@ -150,7 +150,7 @@ class AccountRepository return $invoice; } - private function getNinjaAccount() + private function getNinjaAccount($publicId) { $account = Account::whereAccountKey(NINJA_ACCOUNT_KEY)->first(); @@ -168,7 +168,6 @@ class AccountRepository $account->save(); $random = str_random(RANDOM_KEY_LENGTH); - $user = new User(); $user->registered = true; $user->confirmed = true; @@ -181,6 +180,13 @@ class AccountRepository $user->notify_sent = false; $user->notify_paid = false; $account->users()->save($user); + + $accountGateway = new AccountGateway(); + $accountGateway->user_id = $user->id; + $accountGateway->gateway_id = NINJA_GATEWAY_ID; + $accountGateway->public_id = $publicId; + $accountGateway->config = isset($_ENV['NINJA_GATEWAY_CONFIG']) ? $_ENV['NINJA_GATEWAY_CONFIG'] : null; + $account->account_gateways()->save($accountGateway); } return $account; diff --git a/app/routes.php b/app/routes.php index 0b0741333a..e2d0b2399d 100755 --- a/app/routes.php +++ b/app/routes.php @@ -200,6 +200,7 @@ define('RECENTLY_VIEWED_LIMIT', 8); define('LOGGED_ERROR_LIMIT', 100); define('RANDOM_KEY_LENGTH', 32); define('MAX_NUM_CLIENTS', 1000); +define('MAX_NUM_CLIENTS_PRO', 5000); define('INVOICE_STATUS_DRAFT', 1); define('INVOICE_STATUS_SENT', 2); @@ -236,21 +237,27 @@ define('DEFAULT_LOCALE', 'en'); define('RESULT_SUCCESS', 'success'); define('RESULT_FAILURE', 'failure'); -define('GATEWAY_PAYPAL_EXPRESS', 17); -define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h'); -define('PRO_PLAN_PRICE', 40); -define('REQUESTED_PRO_PLAN', 'REQUESTED_PRO_PLAN'); define('PAYMENT_LIBRARY_OMNIPAY', 1); define('PAYMENT_LIBRARY_PHP_PAYMENTS', 2); +define('GATEWAY_PAYPAL_EXPRESS', 17); define('GATEWAY_BEANSTREAM', 29); +define('GATEWAY_PSIGATE', 30); + +define('PRO_PLAN_PRICE', 40); +define('REQUESTED_PRO_PLAN', 'REQUESTED_PRO_PLAN'); +define('NINJA_ACCOUNT_KEY', 'zg4ylmzDkdkPOT8yoKQw9LTWaoZJx79h'); +define('NINJA_GATEWAY_ID', GATEWAY_PAYPAL_EXPRESS); + + +/* define('GATEWAY_AMAZON', 30); define('GATEWAY_BLUEPAY', 31); define('GATEWAY_BRAINTREE', 32); define('GATEWAY_GOOGLE', 33); -define('GATEWAY_PSIGATE', 34); define('GATEWAY_QUICKBOOKS', 35); +*/ if (Auth::check() && !Session::has(SESSION_TIMEZONE)) { diff --git a/app/views/accounts/payments.blade.php b/app/views/accounts/payments.blade.php index 893ba0a752..378f03c02b 100755 --- a/app/views/accounts/payments.blade.php +++ b/app/views/accounts/payments.blade.php @@ -5,9 +5,6 @@ {{ Former::open()->addClass('col-md-8 col-md-offset-2') }} {{ Former::populate($account) }} - {{ Former::populateField('notify_sent', intval(Auth::user()->notify_sent)) }} - {{ Former::populateField('notify_viewed', intval(Auth::user()->notify_viewed)) }} - {{ Former::populateField('notify_paid', intval(Auth::user()->notify_paid)) }} {{ Former::legend('Payment Gateway') }} @@ -24,10 +21,9 @@ @endif
- {{ Former::radios('recommendedGateway_id') - ->label('Recommended Gateways') - ->radios($recommendedGateways) - ->class('recommended-gateway')}} + {{ Former::radios('recommendedGateway_id')->label('Recommended Gateways') + ->radios($recommendedGateways)->class('recommended-gateway') + }}
{{ Former::select('gateway_id')->label('PayPal & Other Gateways')->addOption('', '') diff --git a/app/views/invoices/edit.blade.php b/app/views/invoices/edit.blade.php index 5e821377c2..0f8540b7e9 100755 --- a/app/views/invoices/edit.blade.php +++ b/app/views/invoices/edit.blade.php @@ -633,17 +633,14 @@ function createInvoiceModel() { var invoice = ko.toJS(model).invoice; - + invoice.is_pro = {{ Auth::user()->isPro() }}; + @if (file_exists($account->getLogoPath())) invoice.image = "{{ HTML::image_data($account->getLogoPath()) }}"; invoice.imageWidth = {{ $account->getLogoWidth() }}; invoice.imageHeight = {{ $account->getLogoHeight() }}; @endif - - //define logo images - - invoice.imageLogo1 = "{{ HTML::image_data('images/report_logo1.jpg') }}"; invoice.imageLogoWidth1 =120; invoice.imageLogoHeight1 = 40 @@ -1019,7 +1016,7 @@ } else { - if (clients.length > {{ MAX_NUM_CLIENTS}}) + if (clients.length > {{ Auth::user()->getMaxNumClients() }}) { return ''; } diff --git a/public/js/script.js b/public/js/script.js index 562eaf7398..4fec766b62 100644 --- a/public/js/script.js +++ b/public/js/script.js @@ -97,9 +97,10 @@ function GetReportTemplate4(doc, invoice, layout, checkMath) { var totalX = layout.headerRight - (doc.getStringUnitWidth(total) * doc.internal.getFontSize()); doc.text(totalX, y, total); - - doc.setFontType("normal"); - doc.text(layout.marginLeft, 790, "Created by InvoiceNinja.com"); + if (!invoice.is_pro) { + doc.setFontType("normal"); + doc.text(layout.marginLeft, 790, "Created by InvoiceNinja.com"); + } return doc; } @@ -688,7 +689,7 @@ function GetReportTemplate1(doc, invoice, layout, checkMath) doc.addImage(invoice.image, 'JPEG', layout.marginLeft, 30); } - if (invoice.imageLogo1) + if (!invoice.is_pro && invoice.imageLogo1) { pageHeight=820; y=pageHeight-invoice.imageLogoHeight1; @@ -1043,7 +1044,7 @@ function Report2AddFooter (invoice,doc) doc.rect(x1, y1, w2, h2, 'FD'); - if (invoice.imageLogo2) + if (!invoice.is_pro && invoice.imageLogo2) { pageHeight=820; var left = 250;//headerRight ; @@ -1084,7 +1085,7 @@ function Report3AddFooter (invoice, account, doc, layout) doc.rect(x1, y1, w2, h2, 'FD'); - if (invoice.imageLogo3) + if (!invoice.is_pro && invoice.imageLogo3) { pageHeight=820; // var left = 25;//250;//headerRight ; From 777c4a6240394c8f08b77b5e2207cb23e96f80dc Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Sun, 13 Apr 2014 16:38:07 +0300 Subject: [PATCH 2/3] Working on pro plan --- app/controllers/UserController.php | 2 +- app/lang/de/texts.php | 2 +- app/lang/en/texts.php | 2 +- app/lang/es/texts.php | 2 +- app/lang/fr/texts.php | 2 +- app/lang/it/texts.php | 2 +- app/lang/nl/texts.php | 2 +- app/lang/pt_BR/texts.php | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/controllers/UserController.php b/app/controllers/UserController.php index 3045bc846e..0e04261fa3 100755 --- a/app/controllers/UserController.php +++ b/app/controllers/UserController.php @@ -193,7 +193,7 @@ class UserController extends BaseController { if ($invoice = $this->accountRepo->enableProPlan()) { $this->contactMailer->sendInvoice($invoice); - $notice_msg = trans('texts.pro_plan_succes'); + $notice_msg = trans('texts.pro_plan_success'); } } diff --git a/app/lang/de/texts.php b/app/lang/de/texts.php index d7aa08c97d..f87a0d310a 100644 --- a/app/lang/de/texts.php +++ b/app/lang/de/texts.php @@ -308,7 +308,7 @@ return array( 'pro_plan_product' => 'Pro Plan', 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', - 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + 'pro_plan_success' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', ); diff --git a/app/lang/en/texts.php b/app/lang/en/texts.php index 56de18ac6d..459ffe7bb9 100644 --- a/app/lang/en/texts.php +++ b/app/lang/en/texts.php @@ -308,6 +308,6 @@ return array( 'pro_plan_product' => 'Pro Plan', 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', - 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + 'pro_plan_success' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', ); diff --git a/app/lang/es/texts.php b/app/lang/es/texts.php index 62b42794c3..f1252896d1 100644 --- a/app/lang/es/texts.php +++ b/app/lang/es/texts.php @@ -307,7 +307,7 @@ return array( 'pro_plan_product' => 'Pro Plan', 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', - 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + 'pro_plan_success' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', ); diff --git a/app/lang/fr/texts.php b/app/lang/fr/texts.php index 441c8b795a..2cb2564f99 100644 --- a/app/lang/fr/texts.php +++ b/app/lang/fr/texts.php @@ -308,7 +308,7 @@ return array( 'pro_plan_product' => 'Pro Plan', 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', - 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + 'pro_plan_success' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', ); diff --git a/app/lang/it/texts.php b/app/lang/it/texts.php index e70b99fef1..80084dd0fc 100644 --- a/app/lang/it/texts.php +++ b/app/lang/it/texts.php @@ -308,7 +308,7 @@ return array( 'pro_plan_product' => 'Pro Plan', 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', - 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + 'pro_plan_success' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', ); diff --git a/app/lang/nl/texts.php b/app/lang/nl/texts.php index fcc58959f4..a042310ab7 100644 --- a/app/lang/nl/texts.php +++ b/app/lang/nl/texts.php @@ -308,7 +308,7 @@ return array( 'pro_plan_product' => 'Pro Plan', 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', - 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + 'pro_plan_success' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', ); diff --git a/app/lang/pt_BR/texts.php b/app/lang/pt_BR/texts.php index f43223bbfb..0280fa85c2 100644 --- a/app/lang/pt_BR/texts.php +++ b/app/lang/pt_BR/texts.php @@ -296,7 +296,7 @@ return array( 'pro_plan_product' => 'Pro Plan', 'pro_plan_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', - 'pro_plan_succes' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', + 'pro_plan_success' => 'Thanks for joining! Once the invoice is paid your Pro Plan membership will begin.', ); From 43a7e236f3d666c585a0c4203777bc3543f4f9f1 Mon Sep 17 00:00:00 2001 From: pierrefaure Date: Sun, 13 Apr 2014 17:48:56 +0200 Subject: [PATCH 3/3] Update texts.php // recurring invoices && // dashboard => OK --- app/lang/fr/texts.php | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/app/lang/fr/texts.php b/app/lang/fr/texts.php index 2cb2564f99..6fb9552013 100644 --- a/app/lang/fr/texts.php +++ b/app/lang/fr/texts.php @@ -102,25 +102,25 @@ return array( 'no_items' => 'Aucun élément', // recurring invoices - 'recurring_invoices' => 'Recurring Invoices', - 'recurring_help' => '

Automatically send clients the same invoices weekly, bi-monthly, monthly, quarterly or annually.

-

Use :MONTH, :QUARTER or :YEAR for dynamic dates. Basic math works as well, for example :MONTH-1.

-

Examples of dynamic invoice variables:

+ 'recurring_invoices' => 'Factures récurrentes', + 'recurring_help' => '

Envoyer automatiquement la même facture à vos clients de façon hebdomadaire, bimensuelle, mensuelle, trimestrielle ou annuelle.

+

Utiliser :MONTH, :QUARTER ou :YEAR pour des dates dynamiques. Les opérations simples fonctionnent également, par exemple :MONTH-1.

+

Exemples de variables dynamiques pour les factures:

    -
  • "Gym membership for the month of :MONTH" => "Gym membership for the month of July"
  • -
  • ":YEAR+1 yearly subscription" => "2015 Yearly Subscription"
  • -
  • "Retainer payment for :QUARTER+1" => "Retainer payment for Q2"
  • +
  • "Adhésion au club de gym pour le mois de :MONTH" => "Adhésion au club de gym pour le mois de Juillet"
  • +
  • ":YEAR+1 - abonnement annuel" => "2015 - abonnement annuel"
  • +
  • "Acompte pour le :QUARTER+1" => "Acompte pour le Q2"
', // dashboard - 'in_total_revenue' => 'in total revenue', - 'billed_client' => 'billed client', - 'billed_clients' => 'billed clients', - 'active_client' => 'active client', - 'active_clients' => 'active clients', - 'invoices_past_due' => 'Invoices Past Due', - 'upcoming_invoices' => 'Upcoming invoices', - 'average_invoice' => 'Average invoice', + 'in_total_revenue' => 'de bénéfice total', + 'billed_client' => 'client facturé', + 'billed_clients' => 'clients facturés', + 'active_client' => 'client actif', + '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' => 'Archive',