diff --git a/app/Http/Controllers/ImportExportController.php b/app/Http/Controllers/ImportExportController.php index 490106ca6ea0..fdab81f4d9ef 100644 --- a/app/Http/Controllers/ImportExportController.php +++ b/app/Http/Controllers/ImportExportController.php @@ -107,10 +107,13 @@ class ImportExportController extends BaseController if ($request->input(ENTITY_CLIENT)) { $data['clients'] = Client::scope() ->with('user', 'contacts', 'country') + ->withTrashed() + ->where('is_deleted', '=', false) ->get(); $data['contacts'] = Contact::scope() ->with('user', 'client.contacts') + ->withTrashed() ->get(); $data['credits'] = Credit::scope() @@ -121,18 +124,24 @@ class ImportExportController extends BaseController if ($request->input(ENTITY_TASK)) { $data['tasks'] = Task::scope() ->with('user', 'client.contacts') + ->withTrashed() + ->where('is_deleted', '=', false) ->get(); } if ($request->input(ENTITY_INVOICE)) { $data['invoices'] = Invoice::scope() ->with('user', 'client.contacts', 'invoice_status') + ->withTrashed() + ->where('is_deleted', '=', false) ->where('is_quote', '=', false) ->where('is_recurring', '=', false) ->get(); $data['quotes'] = Invoice::scope() ->with('user', 'client.contacts', 'invoice_status') + ->withTrashed() + ->where('is_deleted', '=', false) ->where('is_quote', '=', true) ->where('is_recurring', '=', false) ->get(); @@ -140,6 +149,8 @@ class ImportExportController extends BaseController if ($request->input(ENTITY_PAYMENT)) { $data['payments'] = Payment::scope() + ->withTrashed() + ->where('is_deleted', '=', false) ->with('user', 'client.contacts', 'payment_type', 'invoice', 'account_gateway.gateway') ->get(); } diff --git a/app/Http/Controllers/PublicClientController.php b/app/Http/Controllers/PublicClientController.php index a62b2f2d8594..35271aaf66f8 100644 --- a/app/Http/Controllers/PublicClientController.php +++ b/app/Http/Controllers/PublicClientController.php @@ -49,7 +49,7 @@ class PublicClientController extends BaseController } $invoice = $invitation->invoice; - $query = $this->activityRepo->findByClientId($invoice->client_id); + $query = $this->activityRepo->findByClientPublicId($invoice->client->public_id); $query->where('activities.adjustment', '!=', 0); return Datatable::query($query) diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index 9abe90b45cbc..cc4f3c4946de 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -61,14 +61,6 @@ class ReportController extends BaseController $enableChart = true; } - $displayData = []; - $exportData = []; - $reportTotals = [ - 'amount' => [], - 'balance' => [], - 'paid' => [], - ]; - $dateTypes = [ 'DAYOFYEAR' => 'Daily', 'WEEK' => 'Weekly', @@ -111,6 +103,17 @@ class ReportController extends BaseController if ($enableChart) { $params = array_merge($params, self::generateChart($groupBy, $startDate, $endDate)); } + } else { + $params['columns'] = []; + $params['displayData'] = []; + $params['reportTotals'] = [ + 'amount' => [], + 'balance' => [], + 'paid' => [], + ]; + $params['labels'] = []; + $params['datasets'] = []; + $params['scaleStepWidth'] = 100; } return View::make('reports.chart_builder', $params); @@ -183,7 +186,7 @@ class ReportController extends BaseController if ($entityType == ENTITY_INVOICE) { $labelFormat = $groupBy == 'DAYOFYEAR' ? 'j' : ($groupBy == 'WEEK' ? 'W' : 'F'); - $label = $d->format($labelFormat); + $label = $d->format($labelFormat); $labels[] = $label; } } @@ -256,6 +259,14 @@ class ReportController extends BaseController $lastInvoiceId = null; $sameAsLast = false; + $displayData = []; + + $exportData = []; + $reportTotals = [ + 'amount' => [], + 'balance' => [], + 'paid' => [], + ]; foreach ($data as $record) { $sameAsLast = ($lastInvoiceId == $record->invoice_public_id); diff --git a/app/Http/routes.php b/app/Http/routes.php index a3b120ff9a6f..9d587db5b9df 100644 --- a/app/Http/routes.php +++ b/app/Http/routes.php @@ -1,5 +1,6 @@ diff($date); + $interval = $today->diff($datePaid); return $interval->y == 0; } diff --git a/app/Models/Account.php b/app/Models/Account.php index 958f395ab7a3..a936c0227b1f 100644 --- a/app/Models/Account.php +++ b/app/Models/Account.php @@ -60,6 +60,11 @@ class Account extends Eloquent return $this->hasMany('App\Models\Client'); } + public function contacts() + { + return $this->hasMany('App\Models\Contact'); + } + public function invoices() { return $this->hasMany('App\Models\Invoice'); diff --git a/app/Models/Contact.php b/app/Models/Contact.php index 90203d522e33..23faf964315e 100644 --- a/app/Models/Contact.php +++ b/app/Models/Contact.php @@ -34,7 +34,7 @@ class Contact extends EntityModel public function client() { - return $this->belongsTo('App\Models\Client'); + return $this->belongsTo('App\Models\Client')->withTrashed(); } public function getPersonType() diff --git a/app/Ninja/Repositories/ActivityRepository.php b/app/Ninja/Repositories/ActivityRepository.php index 0893bbffdea4..b2d45b9db01c 100644 --- a/app/Ninja/Repositories/ActivityRepository.php +++ b/app/Ninja/Repositories/ActivityRepository.php @@ -70,6 +70,7 @@ class ActivityRepository ->leftJoin('invoices', 'invoices.id', '=', 'activities.invoice_id') ->leftJoin('payments', 'payments.id', '=', 'activities.payment_id') ->leftJoin('credits', 'credits.id', '=', 'activities.credit_id') + ->where('clients.account_id', '=', Auth::user()->account_id) ->where('clients.public_id', '=', $clientPublicId) ->where('contacts.is_primary', '=', 1) ->whereNull('contacts.deleted_at') diff --git a/app/Ninja/Transformers/AccountTransformer.php b/app/Ninja/Transformers/AccountTransformer.php index ef075967d13d..bbc4f4df9da9 100644 --- a/app/Ninja/Transformers/AccountTransformer.php +++ b/app/Ninja/Transformers/AccountTransformer.php @@ -2,6 +2,7 @@ use App\Models\Account; use App\Models\AccountToken; +use App\Models\Contact; use League\Fractal; use League\Fractal\TransformerAbstract; @@ -10,6 +11,8 @@ class AccountTransformer extends TransformerAbstract protected $defaultIncludes = [ 'users', 'clients', + 'invoices', + 'contacts' ]; public function includeUsers(Account $account) @@ -22,6 +25,16 @@ class AccountTransformer extends TransformerAbstract return $this->collection($account->clients, new ClientTransformer($account)); } + public function includeInvoices(Account $account) + { + return $this->collection($account->invoices, new InvoiceTransformer($account)); + } + + public function includeContacts(Account $account) + { + return $this->collection($account->contacts, new ContactTransformer($account)); + } + public function transform(Account $account) { return [ diff --git a/app/Ninja/Transformers/ClientTransformer.php b/app/Ninja/Transformers/ClientTransformer.php index 3f03ed7e2bc2..fb6834538385 100644 --- a/app/Ninja/Transformers/ClientTransformer.php +++ b/app/Ninja/Transformers/ClientTransformer.php @@ -41,9 +41,9 @@ class ClientTransformer extends EntityTransformer */ protected $defaultIncludes = [ - 'contacts', - 'invoices', - 'quotes', + // 'contacts', + // 'invoices', + // 'quotes', ]; public function includeContacts(Client $client) @@ -64,7 +64,7 @@ class ClientTransformer extends EntityTransformer public function transform(Client $client) { return [ - 'public_id' => (int) $client->public_id, + 'id' => (int) $client->public_id, 'name' => $client->name, 'balance' => (float) $client->balance, 'paid_to_date' => (float) $client->paid_to_date, diff --git a/app/Ninja/Transformers/ContactTransformer.php b/app/Ninja/Transformers/ContactTransformer.php index 0752e504eaf4..b7047fe67e55 100644 --- a/app/Ninja/Transformers/ContactTransformer.php +++ b/app/Ninja/Transformers/ContactTransformer.php @@ -9,7 +9,7 @@ class ContactTransformer extends EntityTransformer public function transform(Contact $contact) { return [ - 'public_id' => (int) $contact->public_id, + 'id' => (int) $contact->public_id, 'first_name' => $contact->first_name, 'last_name' => $contact->last_name, 'email' => $contact->email, @@ -19,7 +19,8 @@ class ContactTransformer extends EntityTransformer 'is_primary' => (bool) $contact->is_primary, 'phone' => $contact->phone, 'last_login' => $contact->last_login, - 'account_key' => $this->account->account_key + 'account_key' => $this->account->account_key, + 'client_id' => $contact->client_id ]; } } \ No newline at end of file diff --git a/app/Ninja/Transformers/InvoiceItemTransformer.php b/app/Ninja/Transformers/InvoiceItemTransformer.php index 3f72de9c847f..ad3f8b7f7c1f 100644 --- a/app/Ninja/Transformers/InvoiceItemTransformer.php +++ b/app/Ninja/Transformers/InvoiceItemTransformer.php @@ -9,7 +9,7 @@ class InvoiceItemTransformer extends EntityTransformer public function transform(InvoiceItem $item) { return [ - 'public_id' => (int) $item->public_id, + 'id' => (int) $item->public_id, 'product_key' => $item->product_key, 'account_key' => $this->account->account_key, 'user_id' => (int) $item->user_id, diff --git a/app/Ninja/Transformers/InvoiceTransformer.php b/app/Ninja/Transformers/InvoiceTransformer.php index c5d47f14d3e3..6e0ef1da528b 100644 --- a/app/Ninja/Transformers/InvoiceTransformer.php +++ b/app/Ninja/Transformers/InvoiceTransformer.php @@ -20,13 +20,11 @@ class InvoiceTransformer extends EntityTransformer * @SWG\Property(property="invoice_status_id", type="integer", example=1) */ - protected $client; - public function __construct(Account $account, Client $client) + public function __construct(Account $account) { parent::__construct($account); - $this->client = $client; } protected $defaultIncludes = [ @@ -42,10 +40,9 @@ class InvoiceTransformer extends EntityTransformer { return [ 'id' => (int) $invoice->public_id, - 'invoice_number' => $invoice->invoice_number, 'amount' => (float) $invoice->amount, 'balance' => (float) $invoice->balance, - 'client_id' => (int) $this->client->public_id, + 'client_id' => (int) $invoice->client->public_id, 'invoice_status_id' => (int) $invoice->invoice_status_id, 'updated_at' => $invoice->updated_at, 'deleted_at' => $invoice->deleted_at, @@ -71,7 +68,8 @@ class InvoiceTransformer extends EntityTransformer 'invoice_footer' => $invoice->invoice_footer, 'partial' => (float) $invoice->partial, 'has_tasks' => (bool) $invoice->has_tasks, - 'auto_bill' => (bool) $invoice->auto_bill + 'auto_bill' => (bool) $invoice->auto_bill, + 'account_key' => $this->account->account_key ]; } } \ No newline at end of file diff --git a/app/Ninja/Transformers/QuoteTransformer.php b/app/Ninja/Transformers/QuoteTransformer.php index 6cbab0b3caac..716b29656a59 100644 --- a/app/Ninja/Transformers/QuoteTransformer.php +++ b/app/Ninja/Transformers/QuoteTransformer.php @@ -17,7 +17,7 @@ class QuoteTransformer extends EntityTransformer public function transform(Invoice $invoice) { return [ - 'public_id' => (int) $invoice->public_id, + 'id' => (int) $invoice->public_id, 'quote_number' => $invoice->invoice_number, 'amount' => (float) $invoice->amount, ]; diff --git a/app/Ninja/Transformers/UserTransformer.php b/app/Ninja/Transformers/UserTransformer.php index e73ad2bd0450..5c5b3ed0e154 100644 --- a/app/Ninja/Transformers/UserTransformer.php +++ b/app/Ninja/Transformers/UserTransformer.php @@ -9,7 +9,7 @@ class UserTransformer extends EntityTransformer public function transform(User $user) { return [ - 'public_id' => (int) ($user->public_id + 1), + 'id' => (int) ($user->public_id + 1), 'first_name' => $user->first_name, 'last_name' => $user->last_name, 'email' => $user->email, diff --git a/app/Services/BaseService.php b/app/Services/BaseService.php index 77dbcc65421a..4705417e613e 100644 --- a/app/Services/BaseService.php +++ b/app/Services/BaseService.php @@ -29,7 +29,7 @@ class BaseService public function createDatatable($entityType, $query, $showCheckbox = true, $hideClient = false) { - $columns = $this->getDatatableColumns($entityType, $hideClient); + $columns = $this->getDatatableColumns($entityType, !$showCheckbox); $actions = $this->getDatatableActions($entityType); return $this->datatableService->createDatatable($entityType, $query, $columns, $actions, $showCheckbox); diff --git a/database/seeds/PaymentLibrariesSeeder.php b/database/seeds/PaymentLibrariesSeeder.php index b48d14689a72..7bc1ca878e58 100644 --- a/database/seeds/PaymentLibrariesSeeder.php +++ b/database/seeds/PaymentLibrariesSeeder.php @@ -101,7 +101,7 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'Norske Kroner', 'code' => 'NOK', 'symbol' => 'kr ', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], ['name' => 'New Zealand Dollar', 'code' => 'NZD', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Vietnamese Dong', 'code' => 'VND', 'symbol' => 'VND ', 'precision' => '0', 'thousand_separator' => '.', 'decimal_separator' => ','], - ['name' => 'Swiss Franc', 'code' => 'CHF', 'symbol' => 'CHF ', 'precision' => '2', 'thousand_separator' => '\'', 'decimal_separator' => ','], + ['name' => 'Swiss Franc', 'code' => 'CHF', 'symbol' => 'CHF ', 'precision' => '2', 'thousand_separator' => '\'', 'decimal_separator' => '.'], ['name' => 'Guatemalan Quetzal', 'code' => 'GTQ', 'symbol' => 'Q', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Malaysian Ringgit', 'code' => 'MYR', 'symbol' => 'RM', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Brazilian Real', 'code' => 'BRL', 'symbol' => 'R$', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], @@ -115,6 +115,7 @@ class PaymentLibrariesSeeder extends Seeder ['name' => 'Mexican Peso', 'code' => 'MXN', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Egyptian Pound', 'code' => 'EGP', 'symbol' => '£', 'precision' => '2', 'thousand_separator' => ',', 'decimal_separator' => '.'], ['name' => 'Colombian Peso', 'code' => 'COP', 'symbol' => '$', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], + ['name' => 'West African Franc', 'code' => 'XOF', 'symbol' => 'CFA ', 'precision' => '2', 'thousand_separator' => '.', 'decimal_separator' => ','], ]; foreach ($currencies as $currency) { diff --git a/readme.md b/readme.md index 20580dd77839..29abc1e737e6 100644 --- a/readme.md +++ b/readme.md @@ -18,7 +18,7 @@ If you'd like to use our code to sell your own invoicing app email us for detail ### Features * Built using Laravel 5 * Live PDF generation using [pdfmake](http://pdfmake.org/) -* Integrates with 30+ payment providers with [OmniPay](https://github.com/thephpleague/omnipay) +* Integrates with 50+ payment providers with [OmniPay](https://github.com/thephpleague/omnipay) * Recurring invoices with auto-billing * Tasks with time-tracking * Multi-user/multi-company support diff --git a/resources/lang/da/texts.php b/resources/lang/da/texts.php index 55af0a5ad7f5..6fa11cd5d2a6 100644 --- a/resources/lang/da/texts.php +++ b/resources/lang/da/texts.php @@ -909,5 +909,14 @@ 'archived' => 'Archived', 'untitled_account' => 'Untitled Company', + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', + ); diff --git a/resources/lang/de/texts.php b/resources/lang/de/texts.php index 26cea549d170..edce861002b3 100644 --- a/resources/lang/de/texts.php +++ b/resources/lang/de/texts.php @@ -841,7 +841,7 @@ return array( 'default_tax_rate_id' => 'Standard Steuersatz', 'tax_rate' => 'Steuersatz', - 'recurring_hour' => 'Recurring Hour', + 'recurring_hour' => 'Wiederholende Stunde', 'pattern' => 'Schema', 'pattern_help_title' => 'Schema-Hilfe', 'pattern_help_1' => 'Erstelle angepasste Rechnungs- und Angebotsnummern mittels Nummernschema', @@ -852,9 +852,9 @@ return array( 'quote_counter' => 'Angebotszähler', 'type' => 'Typ', - 'activity_1' => ':user erstellte Klient :client', - 'activity_2' => ':user archivierte Klient :client', - 'activity_3' => ':user löschte Klient :client', + 'activity_1' => ':user erstellte Kunde :client', + 'activity_2' => ':user archivierte Kunde :client', + 'activity_3' => ':user löschte Kunde :client', 'activity_4' => ':user erstellte Rechnung :invoice', 'activity_5' => ':user aktualisierte Rechnung :invoice', 'activity_6' => ':user mailte Rechnung :invoice an :contact', @@ -864,11 +864,11 @@ return array( 'activity_10' => ':contact gab Zahlungsinformation :payment für :invoice ein', 'activity_11' => ':user aktualisierte Zahlung :payment', 'activity_12' => ':user archivierte Zahlung :payment', - 'activity_13' => ':user deleted Zahlung :payment', - 'activity_14' => ':user entered :credit credit', - 'activity_15' => ':user updated :credit credit', - 'activity_16' => ':user archived :credit credit', - 'activity_17' => ':user deleted :credit credit', + 'activity_13' => ':user löschte Zahlung :payment', + 'activity_14' => ':user gab :credit Guthaben ein', + 'activity_15' => ':user aktualisierte :credit Guthaben', + 'activity_16' => ':user archivierte :credit Guthaben', + 'activity_17' => ':user löschte :credit Guthaben', 'activity_18' => ':user löschte Angebot :quote', 'activity_19' => ':user aktualisierte Angebot :quote', 'activity_20' => ':user mailte Angebot :quote an :contact', @@ -877,12 +877,12 @@ return array( 'activity_23' => ':user löschte Angebot :quote', 'activity_24' => ':user stellte Angebot :quote wieder her', 'activity_25' => ':user stellte Rechnung :invoice wieder her', - 'activity_26' => ':user stellte Klient :client wieder her', + 'activity_26' => ':user stellte Kunde :client wieder her', 'activity_27' => ':user stellte Zahlung :payment wieder her', - 'activity_28' => ':user restored :credit credit', - 'activity_29' => ':contact akzeptiert Angebot :quote', + 'activity_28' => ':user stellte Guthaben :credit wieder her', + 'activity_29' => ':contact akzeptierte Angebot :quote', - 'payment' => 'Payment', + 'payment' => 'Zahlung', 'system' => 'System', 'signature' => 'Email-Signatur', 'default_messages' => 'Standardnachrichten', @@ -895,7 +895,7 @@ return array( 'quote_is_approved' => 'This quote is approved', 'apply_credit' => 'Apply Credit', - 'system_settings' => 'System Settings', + 'system_settings' => 'Systemeinstellungen', 'archive_token' => 'Archive Token', 'archived_token' => 'Successfully archived token', 'archive_user' => 'Archive User', @@ -908,7 +908,16 @@ return array( 'deleted_recurring_invoice' => 'Successfully deleted recurring invoice', 'restore_recurring_invoice' => 'Restore Recurring Invoice', 'restored_recurring_invoice' => 'Successfully restored recurring invoice', - 'archived' => 'Archived', + 'archived' => 'Archiviert', 'untitled_account' => 'Untitled Company', + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', + ); diff --git a/resources/lang/es/texts.php b/resources/lang/es/texts.php index a9f91b1394b0..0fb7664d7d67 100644 --- a/resources/lang/es/texts.php +++ b/resources/lang/es/texts.php @@ -887,5 +887,14 @@ return array( 'archived' => 'Archived', 'untitled_account' => 'Untitled Company', + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', + ); diff --git a/resources/lang/es_ES/texts.php b/resources/lang/es_ES/texts.php index 74c16fb5e8ea..4a6214f10233 100644 --- a/resources/lang/es_ES/texts.php +++ b/resources/lang/es_ES/texts.php @@ -908,4 +908,13 @@ return array( 'archived' => 'Archived', 'untitled_account' => 'Untitled Company', + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', + ); diff --git a/resources/lang/fr/texts.php b/resources/lang/fr/texts.php index 6886d76d7a85..171b14c73ed7 100644 --- a/resources/lang/fr/texts.php +++ b/resources/lang/fr/texts.php @@ -69,7 +69,7 @@ return array( 'delete_invoice' => 'Supprimer la facture', 'email_invoice' => 'Envoyer la facture par courriel', 'enter_payment' => 'Saisissez un paiement', - 'tax_rates' => 'Taux de taxe', + 'tax_rates' => 'Taxes', 'rate' => 'Taux', 'settings' => 'Paramètres', 'enable_invoice_tax' => 'Spécifier une
taxe pour la facture', @@ -602,7 +602,7 @@ return array( 'logo' => 'Logo', 'subdomain' => 'Sous-domaine', 'provide_name_or_email' => 'Merci d\'indiquer un nom ou une adresse email', - 'charts_and_reports' => 'Charts & Reports', + 'charts_and_reports' => 'Graphiques & rapports', 'chart' => 'Graphique', 'report' => 'Rapport', 'group_by' => 'Grouper par', @@ -789,10 +789,10 @@ return array( 'sign_up_using' => 'Connexion avec', 'invalid_credentials' => 'These credentials do not match our records', 'show_all_options' => 'Show all options', - 'user_details' => 'User Details', - 'oneclick_login' => 'One-Click Login', - 'disable' => 'Disable', - 'invoice_quote_number' => 'Invoice and Quote Numbers', + 'user_details' => 'Utilisateur', + 'oneclick_login' => 'Connexion en 1 clic', + 'disable' => 'Désactiver', + 'invoice_quote_number' => 'Numéro des devis & factures', 'invoice_charges' => 'Invoice Charges', 'invitation_status' => [ @@ -884,22 +884,31 @@ return array( 'quote_footer' => 'Pied de page des devis', 'free' => 'Gratuit', - 'quote_is_approved' => 'This quote is approved', - 'apply_credit' => 'Apply Credit', + 'quote_is_approved' => 'Ce devis est approuvé', + 'apply_credit' => 'Appliquer crédit', 'system_settings' => 'Paramètres système', - 'archive_token' => 'Archive Token', - 'archived_token' => 'Successfully archived token', + 'archive_token' => 'Archiver jeton', + 'archived_token' => 'Jeton archivé avec succès', 'archive_user' => 'Archiver utilisateur', - 'archived_user' => 'Successfully archived user', - 'archive_account_gateway' => 'Archive Gateway', - 'archived_account_gateway' => 'Successfully archived gateway', - 'archive_recurring_invoice' => 'Archive Recurring Invoice', - 'archived_recurring_invoice' => 'Successfully archived recurring invoice', - 'delete_recurring_invoice' => 'Delete Recurring Invoice', - 'deleted_recurring_invoice' => 'Successfully deleted recurring invoice', - 'restore_recurring_invoice' => 'Restore Recurring Invoice', - 'restored_recurring_invoice' => 'Successfully restored recurring invoice', + 'archived_user' => 'Utilisateur archivé avec succès', + 'archive_account_gateway' => 'Archiver passerelle', + 'archived_account_gateway' => 'Passerelle archivée avec succès', + 'archive_recurring_invoice' => 'Archiver facture récurrente', + 'archived_recurring_invoice' => 'Facture récurrente archivée avec succès', + 'delete_recurring_invoice' => 'Supprimer archive récurrente', + 'deleted_recurring_invoice' => 'Facture récurrente supprimée avec succès', + 'restore_recurring_invoice' => 'Restaurer facture récurrence', + 'restored_recurring_invoice' => 'Facture récurrente restaurée avec succès', 'archived' => 'Archivé', 'untitled_account' => 'Société sans nom', + + 'before' => 'Avant', + 'after' => 'Après', + 'reset_terms_help' => 'Remettre les conditions par défaut', + 'reset_footer_help' => 'Remettre le pied de facture par défaut', + 'export_data' => 'Exporter données', + 'user' => 'Utilisateur', + 'country' => 'Pays', + 'include' => 'Inclure', ); diff --git a/resources/lang/fr_CA/texts.php b/resources/lang/fr_CA/texts.php index 0658ff11f552..13d3e367d999 100644 --- a/resources/lang/fr_CA/texts.php +++ b/resources/lang/fr_CA/texts.php @@ -902,4 +902,13 @@ return array( 'archived' => 'Archived', 'untitled_account' => 'Untitled Company', + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', + ); diff --git a/resources/lang/it/texts.php b/resources/lang/it/texts.php index 3f4d458f3412..a35a42cbb2ed 100644 --- a/resources/lang/it/texts.php +++ b/resources/lang/it/texts.php @@ -903,5 +903,14 @@ return array( 'restored_recurring_invoice' => 'Successfully restored recurring invoice', 'archived' => 'Archived', 'untitled_account' => 'Untitled Company', + + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', ); diff --git a/resources/lang/lt/texts.php b/resources/lang/lt/texts.php index 328a5058720c..9aee3cd86e2a 100644 --- a/resources/lang/lt/texts.php +++ b/resources/lang/lt/texts.php @@ -910,6 +910,15 @@ return array( 'restored_recurring_invoice' => 'Successfully restored recurring invoice', 'archived' => 'Archived', 'untitled_account' => 'Untitled Company', + + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', ); diff --git a/resources/lang/nb_NO/texts.php b/resources/lang/nb_NO/texts.php index 0db24adf37cd..3c50871fa650 100644 --- a/resources/lang/nb_NO/texts.php +++ b/resources/lang/nb_NO/texts.php @@ -908,5 +908,14 @@ return array( 'restored_recurring_invoice' => 'Suksessfullt gjenopprettet gjentakende faktura', 'archived' => 'Arkivert', 'untitled_account' => 'Selskap Uten Navn', + + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', ); diff --git a/resources/lang/nl/texts.php b/resources/lang/nl/texts.php index 6ab529243a44..7a14e15bce24 100644 --- a/resources/lang/nl/texts.php +++ b/resources/lang/nl/texts.php @@ -903,5 +903,14 @@ return array( 'restored_recurring_invoice' => 'Successfully restored recurring invoice', 'archived' => 'Archived', 'untitled_account' => 'Untitled Company', + + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', ); diff --git a/resources/lang/pt_BR/texts.php b/resources/lang/pt_BR/texts.php index ca410c7b8d02..455928e6b1f1 100644 --- a/resources/lang/pt_BR/texts.php +++ b/resources/lang/pt_BR/texts.php @@ -905,4 +905,10 @@ return array( 'after' => 'Depois', 'reset_terms_help' => 'Resetar para as condições padrões', 'reset_footer_help' => 'Resetar para o rodapé padrão', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Exportar Dados', + 'user' => 'Usuário', + 'country' => 'País', + 'include' => 'Incluir', ); diff --git a/resources/lang/sv/texts.php b/resources/lang/sv/texts.php index 44bd13b1e030..7401020eb6d7 100644 --- a/resources/lang/sv/texts.php +++ b/resources/lang/sv/texts.php @@ -906,5 +906,14 @@ return array( 'restored_recurring_invoice' => 'Successfully restored recurring invoice', 'archived' => 'Archived', 'untitled_account' => 'Untitled Company', + + 'before' => 'Before', + 'after' => 'After', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Export Data', + 'user' => 'User', + 'country' => 'Country', + 'include' => 'Include', ); diff --git a/resources/views/export/contacts.blade.php b/resources/views/export/contacts.blade.php index 30c7305cc1b2..b35f59045a26 100644 --- a/resources/views/export/contacts.blade.php +++ b/resources/views/export/contacts.blade.php @@ -10,16 +10,18 @@ @foreach ($contacts as $contact) - - {{ $contact->client->getDisplayName() }} - @if ($multiUser) - {{ $contact->user->getDisplayName() }} - @endif - {{ $contact->first_name }} - {{ $contact->last_name }} - {{ $contact->email }} - {{ $contact->phone }} - + @if (!$contact->client->is_deleted) + + {{ $contact->client->getDisplayName() }} + @if ($multiUser) + {{ $contact->user->getDisplayName() }} + @endif + {{ $contact->first_name }} + {{ $contact->last_name }} + {{ $contact->email }} + {{ $contact->phone }} + + @endif @endforeach \ No newline at end of file diff --git a/resources/views/export/credits.blade.php b/resources/views/export/credits.blade.php index 85fa24ba7947..28d53a5e7fc8 100644 --- a/resources/views/export/credits.blade.php +++ b/resources/views/export/credits.blade.php @@ -9,15 +9,17 @@ @foreach ($credits as $credit) - - {{ $credit->client->getDisplayName() }} - @if ($multiUser) - {{ $credit->user->getDisplayName() }} - @endif - {{ $credit->present()->amount }} - {{ $credit->present()->balance }} - {{ $credit->present()->credit_date }} - + @if (!$credit->client->is_deleted) + + {{ $credit->client->getDisplayName() }} + @if ($multiUser) + {{ $credit->user->getDisplayName() }} + @endif + {{ $credit->present()->amount }} + {{ $credit->present()->balance }} + {{ $credit->present()->credit_date }} + + @endif @endforeach \ No newline at end of file diff --git a/resources/views/reports/chart_builder.blade.php b/resources/views/reports/chart_builder.blade.php index 0b4e7fad9f00..159b71b177bd 100644 --- a/resources/views/reports/chart_builder.blade.php +++ b/resources/views/reports/chart_builder.blade.php @@ -161,27 +161,31 @@ $('#action').val(''); } - var ctx = document.getElementById('monthly-reports').getContext('2d'); - var chart = { - labels: {!! json_encode($labels) !!}, - datasets: [ - @foreach ($datasets as $dataset) - { - data: {!! json_encode($dataset['totals']) !!}, - fillColor : "rgba({!! $dataset['colors'] !!},0.5)", - strokeColor : "rgba({!! $dataset['colors'] !!},1)", - }, - @endforeach - ] - } + @if ($enableChart) + var ctx = document.getElementById('monthly-reports').getContext('2d'); + var chart = { + labels: {!! json_encode($labels) !!}, + datasets: [ + @foreach ($datasets as $dataset) + { + data: {!! json_encode($dataset['totals']) !!}, + fillColor : "rgba({!! $dataset['colors'] !!},0.5)", + strokeColor : "rgba({!! $dataset['colors'] !!},1)", + }, + @endforeach + ] + } - var options = { - scaleOverride: true, - scaleSteps: 10, - scaleStepWidth: {!! $scaleStepWidth !!}, - scaleStartValue: 0, - scaleLabel : "<%=value%>", - }; + var options = { + scaleOverride: true, + scaleSteps: 10, + scaleStepWidth: {!! $scaleStepWidth !!}, + scaleStartValue: 0, + scaleLabel : "<%=value%>", + }; + + new Chart(ctx).{!! $chartType !!}(chart, options); + @endif $(function() { $('.start_date .input-group-addon').click(function() { @@ -192,7 +196,6 @@ }); }) - new Chart(ctx).{!! $chartType !!}(chart, options); diff --git a/tests/_support/_generated/AcceptanceTesterActions.php b/tests/_support/_generated/AcceptanceTesterActions.php index 2adc19ca2c5a..94bb9b320601 100644 --- a/tests/_support/_generated/AcceptanceTesterActions.php +++ b/tests/_support/_generated/AcceptanceTesterActions.php @@ -1,4 +1,4 @@ -getScenario()->runStep(new \Codeception\Step\Action('debugWebDriverLogs', func_get_args())); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -249,7 +260,6 @@ trait AcceptanceTesterActions * $I->amOnPage('/'); * // opens /register page * $I->amOnPage('/register'); - * ?> * ``` * * @param $page @@ -263,16 +273,31 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page contains the given string. - * Specify a locator as the second parameter to match a specific region. + * Checks that the current page contains the given string (case insensitive). + * + * You can specify a specific HTML element (via CSS or XPath) as the second + * parameter to only search within that element. * * ``` php * see('Logout'); // I can suppose user is logged in - * $I->see('Sign Up','h1'); // I can suppose it's a signup page - * $I->see('Sign Up','//body/h1'); // with XPath - * ?> + * $I->see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up', 'h1'); // I can suppose it's a signup page + * $I->see('Sign Up', '//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->see('strong')` will return true for strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will *not* be true for strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -285,16 +310,31 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page contains the given string. - * Specify a locator as the second parameter to match a specific region. + * Checks that the current page contains the given string (case insensitive). + * + * You can specify a specific HTML element (via CSS or XPath) as the second + * parameter to only search within that element. * * ``` php * see('Logout'); // I can suppose user is logged in - * $I->see('Sign Up','h1'); // I can suppose it's a signup page - * $I->see('Sign Up','//body/h1'); // with XPath - * ?> + * $I->see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up', 'h1'); // I can suppose it's a signup page + * $I->see('Sign Up', '//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->see('strong')` will return true for strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will *not* be true for strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -308,16 +348,29 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page doesn't contain the text specified. + * Checks that the current page doesn't contain the text specified (case insensitive). * Give a locator as the second parameter to match a specific region. * * ```php * dontSee('Login'); // I can suppose user is already logged in - * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page - * $I->dontSee('Sign Up','//body/h1'); // with XPath - * ?> + * $I->dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->dontSee('strong')` will fail on strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will ignore strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -330,16 +383,29 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page doesn't contain the text specified. + * Checks that the current page doesn't contain the text specified (case insensitive). * Give a locator as the second parameter to match a specific region. * * ```php * dontSee('Login'); // I can suppose user is already logged in - * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page - * $I->dontSee('Sign Up','//body/h1'); // with XPath - * ?> + * $I->dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->dontSee('strong')` will fail on strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will ignore strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -350,6 +416,80 @@ trait AcceptanceTesterActions } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ``` php + * seeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\WebDriver::seeInSource() + */ + public function canSeeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeInSource', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ``` php + * seeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * @see \Codeception\Module\WebDriver::seeInSource() + */ + public function seeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeInSource', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ```php + * dontSeeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\WebDriver::dontSeeInSource() + */ + public function cantSeeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInSource', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ```php + * dontSeeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * @see \Codeception\Module\WebDriver::dontSeeInSource() + */ + public function dontSeeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeInSource', func_get_args())); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -1999,13 +2139,13 @@ trait AcceptanceTesterActions * ``` * Note that "2" will be the submitted value for the "plan" field, as it is * the selected option. - * + * * Also note that this differs from PhpBrowser, in that * ```'user' => [ 'login' => 'Davert' ]``` is not supported at the moment. * Named array keys *must* be included in the name as above. - * + * * Pair this with seeInFormFields for quick testing magic. - * + * * ``` php * submitForm('#my-form', [ * 'field[]' => 'value', * 'field[]' => 'another value', // 'field[]' is already a defined key * ]); * ``` - * + * * The solution is to pass an array value: - * + * * ```php * // this way both values are submitted * $I->submitForm('#my-form', [ @@ -2528,7 +2668,7 @@ trait AcceptanceTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Inserts SQL record into database. This record will be erased after the test. + * Inserts an SQL record into a database. This record will be erased after the test. * * ``` php * seeInDatabase * - * Checks if there is no record with such column values in database. + * Asserts that there is no record with the given column values in a database. * Provide table name and column values. * * Example: @@ -2680,7 +2820,7 @@ trait AcceptanceTesterActions * * Effect is opposite to ->seeInDatabase * - * Checks if there is no record with such column values in database. + * Asserts that there is no record with the given column values in a database. * Provide table name and column values. * * Example: diff --git a/tests/_support/_generated/FunctionalTesterActions.php b/tests/_support/_generated/FunctionalTesterActions.php index cffb7b2e0c8b..a3980a806784 100644 --- a/tests/_support/_generated/FunctionalTesterActions.php +++ b/tests/_support/_generated/FunctionalTesterActions.php @@ -1,4 +1,4 @@ -amOnPage('/'); * // opens /register page * $I->amOnPage('/register'); - * ?> * ``` * * @param $page @@ -217,16 +216,31 @@ trait FunctionalTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page contains the given string. - * Specify a locator as the second parameter to match a specific region. + * Checks that the current page contains the given string (case insensitive). + * + * You can specify a specific HTML element (via CSS or XPath) as the second + * parameter to only search within that element. * * ``` php * see('Logout'); // I can suppose user is logged in - * $I->see('Sign Up','h1'); // I can suppose it's a signup page - * $I->see('Sign Up','//body/h1'); // with XPath - * ?> + * $I->see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up', 'h1'); // I can suppose it's a signup page + * $I->see('Sign Up', '//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->see('strong')` will return true for strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will *not* be true for strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -239,16 +253,31 @@ trait FunctionalTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page contains the given string. - * Specify a locator as the second parameter to match a specific region. + * Checks that the current page contains the given string (case insensitive). + * + * You can specify a specific HTML element (via CSS or XPath) as the second + * parameter to only search within that element. * * ``` php * see('Logout'); // I can suppose user is logged in - * $I->see('Sign Up','h1'); // I can suppose it's a signup page - * $I->see('Sign Up','//body/h1'); // with XPath - * ?> + * $I->see('Logout'); // I can suppose user is logged in + * $I->see('Sign Up', 'h1'); // I can suppose it's a signup page + * $I->see('Sign Up', '//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->see('strong')` will return true for strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will *not* be true for strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -262,16 +291,29 @@ trait FunctionalTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page doesn't contain the text specified. + * Checks that the current page doesn't contain the text specified (case insensitive). * Give a locator as the second parameter to match a specific region. * * ```php * dontSee('Login'); // I can suppose user is already logged in - * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page - * $I->dontSee('Sign Up','//body/h1'); // with XPath - * ?> + * $I->dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->dontSee('strong')` will fail on strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will ignore strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -284,16 +326,29 @@ trait FunctionalTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Checks that the current page doesn't contain the text specified. + * Checks that the current page doesn't contain the text specified (case insensitive). * Give a locator as the second parameter to match a specific region. * * ```php * dontSee('Login'); // I can suppose user is already logged in - * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page - * $I->dontSee('Sign Up','//body/h1'); // with XPath - * ?> + * $I->dontSee('Login'); // I can suppose user is already logged in + * $I->dontSee('Sign Up','h1'); // I can suppose it's not a signup page + * $I->dontSee('Sign Up','//body/h1'); // with XPath * ``` + * + * Note that the search is done after stripping all HTML tags from the body, + * so `$I->dontSee('strong')` will fail on strings like: + * + * - `

I am Stronger than thou

` + * - `` + * + * But will ignore strings like: + * + * - `Home` + * - `
Home` + * - `` + * + * For checking the raw source code, use `seeInSource()`. * * @param $text * @param null $selector @@ -304,6 +359,80 @@ trait FunctionalTesterActions } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ``` php + * seeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::seeInSource() + */ + public function canSeeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeInSource', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ``` php + * seeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * @see \Codeception\Lib\InnerBrowser::seeInSource() + */ + public function seeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeInSource', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ```php + * dontSeeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Lib\InnerBrowser::dontSeeInSource() + */ + public function cantSeeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeInSource', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that the current page contains the given string in its + * raw source code. + * + * ```php + * dontSeeInSource('

Green eggs & ham

'); + * ``` + * + * @param $raw + * @see \Codeception\Lib\InnerBrowser::dontSeeInSource() + */ + public function dontSeeInSource($raw) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeInSource', func_get_args())); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -1076,13 +1205,25 @@ trait FunctionalTesterActions * Submits the given form on the page, optionally with the given form * values. Give the form fields values as an array. * - * Skipped fields will be filled by their values from the page. + * Although this function can be used as a short-hand version of + * `fillField()`, `selectOption()`, `click()` etc. it has some important + * differences: + * + * * Only field *names* may be used, not CSS/XPath selectors nor field labels + * * If a field is sent to this function that does *not* exist on the page, + * it will silently be added to the HTTP request. This is helpful for testing + * some types of forms, but be aware that you will *not* get an exception + * like you would if you called `fillField()` or `selectOption()` with + * a missing field. + * + * Fields that are not provided will be filled by their values from the page, + * or from any previous calls to `fillField()`, `selectOption()` etc. * You don't need to click the 'Submit' button afterwards. * This command itself triggers the request to form's action. * - * You can optionally specify what button's value to include - * in the request with the last parameter as an alternative to - * explicitly setting its value in the second parameter, as + * You can optionally specify which button's value to include + * in the request with the last parameter (as an alternative to + * explicitly setting its value in the second parameter), as * button values are not otherwise included in the request. * * Examples: @@ -1156,7 +1297,8 @@ trait FunctionalTesterActions * ); * ``` * - * Pair this with seeInFormFields for quick testing magic. + * This function works well when paired with `seeInFormFields()` + * for quickly testing CRUD interfaces and form validation logic. * * ``` php * true, * // ... * ]; - * $I->submitForm('//form[@id=my-form]', $form, 'submitButton'); + * $I->submitForm('#my-form', $form, 'submitButton'); * // $I->amOnPage('/path/to/form-page') may be needed - * $I->seeInFormFields('//form[@id=my-form]', $form); - * ?> + * $I->seeInFormFields('#my-form', $form); * ``` * * Parameter values can be set to arrays for multiple input fields * of the same name, or multi-select combo boxes. For checkboxes, - * either the string value can be used, or boolean values which will + * you can use either the string value or boolean `true`/`false` which will * be replaced by the checkbox's value in the DOM. * * ``` php @@ -1183,7 +1324,7 @@ trait FunctionalTesterActions * 'field1' => 'value', * 'checkbox' => [ * 'value of first checkbox', - * 'value of second checkbox, + * 'value of second checkbox', * ], * 'otherCheckboxes' => [ * true, @@ -1195,27 +1336,29 @@ trait FunctionalTesterActions * 'second option value' * ] * ]); - * ?> * ``` * * Mixing string and boolean values for a checkbox's value is not supported * and may produce unexpected results. * - * Field names ending in "[]" must be passed without the trailing square + * Field names ending in `[]` must be passed without the trailing square * bracket characters, and must contain an array for its value. This allows * submitting multiple values with the same name, consider: * * ```php + * submitForm('#my-form', [ * 'field[]' => 'value', - * 'field[]' => 'another value', // 'field[]' is already a defined key + * 'field[]' => 'another value', // 'field[]' is already a defined key * ]); * ``` * * The solution is to pass an array value: * * ```php - * // this way both values are submitted + * submitForm('#my-form', [ * 'field' => [ * 'value', @@ -2017,6 +2160,19 @@ trait FunctionalTesterActions } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Moves back in history. + * + * @param int $numberOfSteps (default value 1) + * @see \Codeception\Lib\InnerBrowser::moveBack() + */ + public function moveBack($numberOfSteps = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('moveBack', func_get_args())); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -2116,16 +2272,78 @@ trait FunctionalTesterActions * * ``` php * expectEvents('App\MyEvent'); - * $I->expectEvents('App\MyEvent', 'App\MyOtherEvent'); - * $I->expectEvents(['App\MyEvent', 'App\MyOtherEvent']); + * $I->seeEventTriggered('App\MyEvent'); + * $I->seeEventTriggered(new App\Events\MyEvent()); + * $I->seeEventTriggered('App\MyEvent', 'App\MyOtherEvent'); + * $I->seeEventTriggered(['App\MyEvent', 'App\MyOtherEvent']); * ?> * ``` * @param $events - * @see \Codeception\Module\Laravel5::expectEvents() + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\Laravel5::seeEventTriggered() */ - public function expectEvents($events) { - return $this->getScenario()->runStep(new \Codeception\Step\Action('expectEvents', func_get_args())); + public function canSeeEventTriggered($events) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeEventTriggered', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Make sure events fired during the test. + * + * ``` php + * seeEventTriggered('App\MyEvent'); + * $I->seeEventTriggered(new App\Events\MyEvent()); + * $I->seeEventTriggered('App\MyEvent', 'App\MyOtherEvent'); + * $I->seeEventTriggered(['App\MyEvent', 'App\MyOtherEvent']); + * ?> + * ``` + * @param $events + * @see \Codeception\Module\Laravel5::seeEventTriggered() + */ + public function seeEventTriggered($events) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeEventTriggered', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Make sure events did not fire during the test. + * + * ``` php + * dontSeeEventTriggered('App\MyEvent'); + * $I->dontSeeEventTriggered(new App\Events\MyEvent()); + * $I->dontSeeEventTriggered('App\MyEvent', 'App\MyOtherEvent'); + * $I->dontSeeEventTriggered(['App\MyEvent', 'App\MyOtherEvent']); + * ?> + * ``` + * @param $events + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\Laravel5::dontSeeEventTriggered() + */ + public function cantSeeEventTriggered($events) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('dontSeeEventTriggered', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Make sure events did not fire during the test. + * + * ``` php + * dontSeeEventTriggered('App\MyEvent'); + * $I->dontSeeEventTriggered(new App\Events\MyEvent()); + * $I->dontSeeEventTriggered('App\MyEvent', 'App\MyOtherEvent'); + * $I->dontSeeEventTriggered(['App\MyEvent', 'App\MyOtherEvent']); + * ?> + * ``` + * @param $events + * @see \Codeception\Module\Laravel5::dontSeeEventTriggered() + */ + public function dontSeeEventTriggered($events) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('dontSeeEventTriggered', func_get_args())); } @@ -2149,6 +2367,41 @@ trait FunctionalTesterActions } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url matches route + * + * ``` php + * seeCurrentRouteIs('posts.index'); + * ?> + * ``` + * @param $routeName + * Conditional Assertion: Test won't be stopped on fail + * @see \Codeception\Module\Laravel5::seeCurrentRouteIs() + */ + public function canSeeCurrentRouteIs($routeName) { + return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentRouteIs', func_get_args())); + } + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Checks that current url matches route + * + * ``` php + * seeCurrentRouteIs('posts.index'); + * ?> + * ``` + * @param $routeName + * @see \Codeception\Module\Laravel5::seeCurrentRouteIs() + */ + public function seeCurrentRouteIs($routeName) { + return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeCurrentRouteIs', func_get_args())); + } + + /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -2169,43 +2422,6 @@ trait FunctionalTesterActions } - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Checks that current url matches route - * - * ``` php - * seeCurrentRouteIs('posts.index'); - * ?> - * ``` - * @param $route - * @param array $params - * Conditional Assertion: Test won't be stopped on fail - * @see \Codeception\Module\Laravel5::seeCurrentRouteIs() - */ - public function canSeeCurrentRouteIs($route, $params = null) { - return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentRouteIs', func_get_args())); - } - /** - * [!] Method is generated. Documentation taken from corresponding module. - * - * Checks that current url matches route - * - * ``` php - * seeCurrentRouteIs('posts.index'); - * ?> - * ``` - * @param $route - * @param array $params - * @see \Codeception\Module\Laravel5::seeCurrentRouteIs() - */ - public function seeCurrentRouteIs($route, $params = null) { - return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeCurrentRouteIs', func_get_args())); - } - - /** * [!] Method is generated. Documentation taken from corresponding module. * @@ -2218,11 +2434,10 @@ trait FunctionalTesterActions * ``` * * @param $action - * @param array $params * Conditional Assertion: Test won't be stopped on fail * @see \Codeception\Module\Laravel5::seeCurrentActionIs() */ - public function canSeeCurrentActionIs($action, $params = null) { + public function canSeeCurrentActionIs($action) { return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeCurrentActionIs', func_get_args())); } /** @@ -2237,10 +2452,9 @@ trait FunctionalTesterActions * ``` * * @param $action - * @param array $params * @see \Codeception\Module\Laravel5::seeCurrentActionIs() */ - public function seeCurrentActionIs($action, $params = null) { + public function seeCurrentActionIs($action) { return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeCurrentActionIs', func_get_args())); } @@ -2408,14 +2622,14 @@ trait FunctionalTesterActions * * Assert that specific form error messages are set in the view. * - * Useful for validation messages e.g. - * return `Redirect::to('register')->withErrors($validator);` - * - * Example of Usage + * This method calls `seeFormErrorMessage` for each entry in the `$bindings` array. * * ``` php * seeFormErrorMessages(array('username'=>'Invalid Username')); + * $I->seeFormErrorMessages([ + * 'username' => 'Invalid Username', + * 'password' => null, + * ]); * ?> * ``` * @param array $bindings @@ -2430,14 +2644,14 @@ trait FunctionalTesterActions * * Assert that specific form error messages are set in the view. * - * Useful for validation messages e.g. - * return `Redirect::to('register')->withErrors($validator);` - * - * Example of Usage + * This method calls `seeFormErrorMessage` for each entry in the `$bindings` array. * * ``` php * seeFormErrorMessages(array('username'=>'Invalid Username')); + * $I->seeFormErrorMessages([ + * 'username' => 'Invalid Username', + * 'password' => null, + * ]); * ?> * ``` * @param array $bindings @@ -2451,48 +2665,50 @@ trait FunctionalTesterActions /** * [!] Method is generated. Documentation taken from corresponding module. * - * Assert that specific form error message is set in the view. + * Assert that a specific form error message is set in the view. * - * Useful for validation messages and generally messages array - * e.g. - * return `Redirect::to('register')->withErrors($validator);` + * If you want to assert that there is a form error message for a specific key + * but don't care about the actual error message you can omit `$expectedErrorMessage`. * - * Example of Usage + * If you do pass `$expectedErrorMessage`, this method checks if the actual error message for a key + * contains `$expectedErrorMessage`. * * ``` php * seeFormErrorMessage('username'); * $I->seeFormErrorMessage('username', 'Invalid Username'); * ?> * ``` * @param string $key - * @param string $errorMessage + * @param string|null $expectedErrorMessage * Conditional Assertion: Test won't be stopped on fail * @see \Codeception\Module\Laravel5::seeFormErrorMessage() */ - public function canSeeFormErrorMessage($key, $errorMessage) { + public function canSeeFormErrorMessage($key, $expectedErrorMessage = null) { return $this->getScenario()->runStep(new \Codeception\Step\ConditionalAssertion('seeFormErrorMessage', func_get_args())); } /** * [!] Method is generated. Documentation taken from corresponding module. * - * Assert that specific form error message is set in the view. + * Assert that a specific form error message is set in the view. * - * Useful for validation messages and generally messages array - * e.g. - * return `Redirect::to('register')->withErrors($validator);` + * If you want to assert that there is a form error message for a specific key + * but don't care about the actual error message you can omit `$expectedErrorMessage`. * - * Example of Usage + * If you do pass `$expectedErrorMessage`, this method checks if the actual error message for a key + * contains `$expectedErrorMessage`. * * ``` php * seeFormErrorMessage('username'); * $I->seeFormErrorMessage('username', 'Invalid Username'); * ?> * ``` * @param string $key - * @param string $errorMessage + * @param string|null $expectedErrorMessage * @see \Codeception\Module\Laravel5::seeFormErrorMessage() */ - public function seeFormErrorMessage($key, $errorMessage) { + public function seeFormErrorMessage($key, $expectedErrorMessage = null) { return $this->getScenario()->runStep(new \Codeception\Step\Assertion('seeFormErrorMessage', func_get_args())); } @@ -2504,8 +2720,6 @@ trait FunctionalTesterActions * Takes either an object that implements the User interface or * an array of credentials. * - * Example of Usage - * * ``` php * getScenario()->runStep(new \Codeception\Step\Action('grabRecord', func_get_args())); } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Use Laravel's model factory to create a model. + * Can only be used with Laravel 5.1 and later. + * + * ``` php + * haveModel('App\User'); + * $I->haveModel('App\User', ['name' => 'John Doe']); + * $I->haveModel('App\User', [], 'admin'); + * $I->haveModel('App\User', [], 'admin', 3); + * ?> + * ``` + * + * @see http://laravel.com/docs/5.1/testing#model-factories + * @param string $model + * @param array $attributes + * @param string $name + * @param int $times + * @return mixed + * @see \Codeception\Module\Laravel5::haveModel() + */ + public function haveModel($model, $attributes = null, $name = null, $times = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('haveModel', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Use Laravel's model factory to create a model. + * Can only be used with Laravel 5.1 and later. + * + * ``` php + * createModel('App\User'); + * $I->createModel('App\User', ['name' => 'John Doe']); + * $I->createModel('App\User', [], 'admin'); + * $I->createModel('App\User', [], 'admin', 3); + * ?> + * ``` + * + * @see http://laravel.com/docs/5.1/testing#model-factories + * @param string $model + * @param array $attributes + * @param string $name + * @param int $times + * @return mixed + * @see \Codeception\Module\Laravel5::createModel() + */ + public function createModel($model, $attributes = null, $name = null, $times = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('createModel', func_get_args())); + } + + + /** + * [!] Method is generated. Documentation taken from corresponding module. + * + * Use Laravel's model factory to make a model. + * Can only be used with Laravel 5.1 and later. + * + * ``` php + * makeModel('App\User'); + * $I->makeModel('App\User', ['name' => 'John Doe']); + * $I->makeModel('App\User', [], 'admin'); + * $I->makeModel('App\User', [], 'admin', 3); + * ?> + * ``` + * + * @see http://laravel.com/docs/5.1/testing#model-factories + * @param string $model + * @param array $attributes + * @param string $name + * @param int $times + * @return mixed + * @see \Codeception\Module\Laravel5::makeModel() + */ + public function makeModel($model, $attributes = null, $name = null, $times = null) { + return $this->getScenario()->runStep(new \Codeception\Step\Action('makeModel', func_get_args())); + } } diff --git a/vendor.zip b/vendor.zip new file mode 100644 index 000000000000..c04dc601a68c Binary files /dev/null and b/vendor.zip differ