From bf4c4d0ce556f504f49ca81cc1fcb63070b9d8e1 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Tue, 3 May 2016 11:53:00 +0300 Subject: [PATCH 01/16] Add user permissions to API delete --- app/Http/Controllers/BaseAPIController.php | 3 +++ app/Http/Controllers/ClientApiController.php | 17 +++++------------ app/Http/Controllers/InvoiceApiController.php | 13 ++++--------- app/Http/Controllers/PaymentApiController.php | 18 +++++++----------- 4 files changed, 19 insertions(+), 32 deletions(-) diff --git a/app/Http/Controllers/BaseAPIController.php b/app/Http/Controllers/BaseAPIController.php index a1983ed2b5f0..db99a3beaf1d 100644 --- a/app/Http/Controllers/BaseAPIController.php +++ b/app/Http/Controllers/BaseAPIController.php @@ -202,6 +202,9 @@ class BaseAPIController extends Controller if ($include == 'invoices') { $data[] = 'invoices.invoice_items'; $data[] = 'invoices.user'; + } elseif ($include == 'client') { + $data[] = 'client.contacts'; + $data[] = 'client.user'; } elseif ($include == 'clients') { $data[] = 'clients.contacts'; $data[] = 'clients.user'; diff --git a/app/Http/Controllers/ClientApiController.php b/app/Http/Controllers/ClientApiController.php index 557daa29fff6..dd82e9116131 100644 --- a/app/Http/Controllers/ClientApiController.php +++ b/app/Http/Controllers/ClientApiController.php @@ -143,20 +143,13 @@ class ClientApiController extends BaseAPIController * ) */ - public function destroy($publicId) + public function destroy(UpdateClientRequest $request) { - $client = Client::scope($publicId)->withTrashed()->first(); + $client = $request->entity(); + $this->clientRepo->delete($client); - $client = Client::scope($publicId) - ->with('country', 'contacts', 'industry', 'size', 'currency') - ->withTrashed() - ->first(); - - $transformer = new ClientTransformer(Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($client, $transformer, ENTITY_CLIENT); - - return $this->response($data); + return $this->itemResponse($client); } - + } \ No newline at end of file diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php index da8bc2b7a6cf..1361aad9e9a3 100644 --- a/app/Http/Controllers/InvoiceApiController.php +++ b/app/Http/Controllers/InvoiceApiController.php @@ -349,18 +349,13 @@ class InvoiceApiController extends BaseAPIController * ) */ - public function destroy($publicId) + public function destroy(UpdateInvoiceAPIRequest $request) { - $data['public_id'] = $publicId; - $invoice = Invoice::scope($publicId)->firstOrFail(); - + $invoice = $request->entity(); + $this->invoiceRepo->delete($invoice); - $transformer = new InvoiceTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($invoice, $transformer, 'invoice'); - - return $this->response($data); - + return $this->itemResponse($invoice); } } diff --git a/app/Http/Controllers/PaymentApiController.php b/app/Http/Controllers/PaymentApiController.php index b41100acfad9..0dd8de50803b 100644 --- a/app/Http/Controllers/PaymentApiController.php +++ b/app/Http/Controllers/PaymentApiController.php @@ -49,7 +49,7 @@ class PaymentApiController extends BaseAPIController { $payments = Payment::scope() ->withTrashed() - ->with(['client.contacts', 'invitation', 'user', 'invoice']) + ->with(['invoice']) ->orderBy('created_at', 'desc'); return $this->listResponse($payments); @@ -145,17 +145,13 @@ class PaymentApiController extends BaseAPIController * ) */ - public function destroy($publicId) + public function destroy(UpdatePaymentRequest $request) { + $payment = $request->entity(); + + $this->clientRepo->delete($payment); - $payment = Payment::scope($publicId)->withTrashed()->first(); - $invoiceId = $payment->invoice->public_id; - - $this->paymentRepo->delete($payment); - - $transformer = new PaymentTransformer(\Auth::user()->account, Input::get('serializer')); - $data = $this->createItem($payment, $transformer, 'invoice'); - - return $this->response($data); + return $this->itemResponse($payment); } + } From 75ee124626bece7516de5a4bf952ae78713d7aaa Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Tue, 3 May 2016 14:05:35 +0300 Subject: [PATCH 02/16] Fix for TD Bank w/OFX --- app/Libraries/OFX.php | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/app/Libraries/OFX.php b/app/Libraries/OFX.php index 5563e917acf7..721c9f529f85 100644 --- a/app/Libraries/OFX.php +++ b/app/Libraries/OFX.php @@ -2,6 +2,8 @@ // https://github.com/denvertimothy/OFX +use Utils; +use Log; use SimpleXMLElement; class OFX @@ -21,13 +23,19 @@ class OFX $c = curl_init(); curl_setopt($c, CURLOPT_URL, $this->bank->url); curl_setopt($c, CURLOPT_POST, 1); - curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-Type: application/x-ofx')); + // User-Agent: http://www.ofxhome.com/ofxforum/viewtopic.php?pid=108091#p108091 + curl_setopt($c, CURLOPT_HTTPHEADER, array('Content-Type: application/x-ofx', 'User-Agent: httpclient')); curl_setopt($c, CURLOPT_POSTFIELDS, $this->request); curl_setopt($c, CURLOPT_RETURNTRANSFER, 1); + $this->response = curl_exec($c); - //print_r($this->response); - //\Log::info(print_r($this->response, true)); + + if (Utils::isNinjaDev()) { + Log::info(print_r($this->response, true)); + } + curl_close($c); + $tmp = explode('', $this->response); $this->responseHeader = $tmp[0]; $this->responseBody = ''.$tmp[1]; @@ -35,14 +43,15 @@ class OFX public function xml() { $xml = $this->responseBody; - self::closeTags($xml); + $xml = self::closeTags($xml); $x = new SimpleXMLElement($xml); return $x; } - public static function closeTags(&$x) + public static function closeTags($x) { - $x = preg_replace('/(<([^<\/]+)>)(?!.*?<\/\2>)([^<]+)/', '\1\3', $x); + $x = preg_replace('/\s+/', '', $x); + return preg_replace('/(<([^<\/]+)>)(?!.*?<\/\2>)([^<]+)/', '\1\3', $x); } } @@ -224,3 +233,4 @@ class Account } } } + From 39141d469f5f69ec9eb1923e6a7968fe2430c346 Mon Sep 17 00:00:00 2001 From: Bartlomiej Szala Date: Tue, 3 May 2016 12:47:26 +0000 Subject: [PATCH 03/16] Add polish translations --- ...16_05_02_071859_add_polish_translation.php | 29 + resources/lang/pl/pagination.php | 20 + resources/lang/pl/passwords.php | 22 + resources/lang/pl/reminders.php | 24 + resources/lang/pl/texts.php | 1184 +++++++++++++++++ resources/lang/pl/validation.php | 106 ++ 6 files changed, 1385 insertions(+) create mode 100644 database/migrations/2016_05_02_071859_add_polish_translation.php create mode 100644 resources/lang/pl/pagination.php create mode 100644 resources/lang/pl/passwords.php create mode 100644 resources/lang/pl/reminders.php create mode 100644 resources/lang/pl/texts.php create mode 100644 resources/lang/pl/validation.php diff --git a/database/migrations/2016_05_02_071859_add_polish_translation.php b/database/migrations/2016_05_02_071859_add_polish_translation.php new file mode 100644 index 000000000000..b78969cfbbde --- /dev/null +++ b/database/migrations/2016_05_02_071859_add_polish_translation.php @@ -0,0 +1,29 @@ +insert(['name' => 'Polish', 'locale' => self::LANGUAGE_LOCALE]); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + $language = \App\Models\Language::whereLocale(self::LANGUAGE_LOCALE)->first(); + $language->delete(); + } +} diff --git a/resources/lang/pl/pagination.php b/resources/lang/pl/pagination.php new file mode 100644 index 000000000000..950c5e96cc41 --- /dev/null +++ b/resources/lang/pl/pagination.php @@ -0,0 +1,20 @@ + '« Poprzedni', + + 'next' => 'Następny »', + +); diff --git a/resources/lang/pl/passwords.php b/resources/lang/pl/passwords.php new file mode 100644 index 000000000000..28ccb957b349 --- /dev/null +++ b/resources/lang/pl/passwords.php @@ -0,0 +1,22 @@ + "Hasło musi mieć conajmniej sześć znaków i być takie samo jak potwierdzające.", + "user" => "Użytkownik o podanym adresie e-mail nie istnieje.", + "token" => "Wprowadzony token jest nieprawidłowy.", + "sent" => "Link do resetowania hasła został wysłany.", + "reset" => "Twoje hasło zostało zresetowane!", + +]; \ No newline at end of file diff --git a/resources/lang/pl/reminders.php b/resources/lang/pl/reminders.php new file mode 100644 index 000000000000..25824a7f285a --- /dev/null +++ b/resources/lang/pl/reminders.php @@ -0,0 +1,24 @@ + "Hasło musi mieć conajmniej sześć znaków i być takie samo jak potwierdzające.", + + "user" => "Użytkownik o podanym adresie e-mail nie istnieje.", + + "token" => "Wprowadzony token jest nieprawidłowy.", + + "sent" => "Przypomnienie hasła zostało wysłane!", + +); \ No newline at end of file diff --git a/resources/lang/pl/texts.php b/resources/lang/pl/texts.php new file mode 100644 index 000000000000..19b0253937db --- /dev/null +++ b/resources/lang/pl/texts.php @@ -0,0 +1,1184 @@ + 'Organizacja', + 'name' => 'Nazwa', + 'website' => 'Strona internetowa', + 'work_phone' => 'Telefon służbowy', + 'address' => 'Adres', + 'address1' => 'Ulica', + 'address2' => 'Nr', + 'city' => 'Miasto', + 'state' => 'Województwo', + 'postal_code' => 'Kod pocztowy', + 'country_id' => 'Kraj', + 'contacts' => 'Kontakty', + 'first_name' => 'Imię', + 'last_name' => 'Nazwisko', + 'phone' => 'Telefon', + 'email' => 'Email', + 'additional_info' => 'Dodatkowe informacje', + 'payment_terms' => 'Warunki płatnicze', + 'currency_id' => 'Waluta', + 'size_id' => 'Wielkość firmy', + 'industry_id' => 'Branża', + 'private_notes' => 'Prywatne notatki', + 'invoice' => 'Faktura', + 'client' => 'Klient', + 'invoice_date' => 'Data Faktury', + 'due_date' => 'Termin', + 'invoice_number' => 'Numer Faktury', + 'invoice_number_short' => 'Faktura #', + 'po_number' => 'PO Number', + 'po_number_short' => 'PO #', + 'frequency_id' => 'Jak często', + 'discount' => 'Przecena', + 'taxes' => 'Podatki', + 'tax' => 'Podatek', + 'item' => 'Pozycja', + 'description' => 'Opis', + 'unit_cost' => 'Cena jednostkowa', + 'quantity' => 'Ilość', + 'line_total' => 'Wartość całkowita', + 'subtotal' => 'Suma częściowa', + 'paid_to_date' => 'Wypłacono do tej pory', + 'balance_due' => 'Balance Due', + 'invoice_design_id' => 'Szablon', + 'terms' => 'Warunki', + 'your_invoice' => 'Twoja faktura', + 'remove_contact' => 'Usuń kontakt', + 'add_contact' => 'Dodaj kontakt', + 'create_new_client' => 'Dodaj nowego klienta', + 'edit_client_details' => 'Edytuj dane klienta', + 'enable' => 'Aktywuj', + 'learn_more' => 'Więcej informacji', + 'manage_rates' => 'Zarządzaj stawkami', + 'note_to_client' => 'Informacja dla klienta', + 'invoice_terms' => 'Warunki do faktury', + 'save_as_default_terms' => 'Zapisz jako domyślne warunki', + 'download_pdf' => 'Pobierz PDF', + 'pay_now' => 'Zapłać teraz', + 'save_invoice' => 'Zapisz Fakturę', + 'clone_invoice' => 'Skopiuj Fakturę', + 'archive_invoice' => 'Zarchiwizuj Fakturę', + 'delete_invoice' => 'Usuń Fakturę', + 'email_invoice' => 'Wyślij Fakturę', + 'enter_payment' => 'Wprowadź Płatność', + 'tax_rates' => 'Stawki podatkowe', + 'rate' => 'Stawka', + 'settings' => 'Ustawienia', + 'enable_invoice_tax' => 'Aktywuj możliwość ustawienia podatku do faktury', + 'enable_line_item_tax' => 'Aktywuj możliwość ustawienia podatku do pozycji na fakturze', + 'dashboard' => 'Pulpit', + 'clients' => 'Klienci', + 'invoices' => 'Faktury', + 'payments' => 'Płatności', + 'credits' => 'Kredyty', + 'history' => 'Historia', + 'search' => 'Szukaj', + 'sign_up' => 'Zapisz się', + 'guest' => 'Gość', + 'company_details' => 'Dane Firmy', + 'online_payments' => 'Płatności Online', + 'notifications' => 'Powiadomienia E-mail', + 'import_export' => 'Import | Export', + 'done' => 'Gotowe', + 'save' => 'Zapisz', + 'create' => 'Dodaj', + 'upload' => 'Prześlij', + 'import' => 'Import', + 'download' => 'Pobierz', + 'cancel' => 'Anuluj', + 'close' => 'Zamknij', + 'provide_email' => 'Wprowadź poprawny e-mail.', + 'powered_by' => 'Oparte na', + 'no_items' => 'Brak pozycji', + 'recurring_invoices' => 'Faktury okresowe', + 'recurring_help' => '

Wysyła automatycznie te same faktury klientom tygodniowo, miesięcznie, kwartałowo lub rocznie.

+

Użyj :MONTH, :QUARTER lub :YEAR dla dynamicznych dat. Podstawowa arytmetyka działa również, np: :MONTH-1.

+

Przykłady dynamicznych zmiennych na fakturze:

+
    +
  • "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"
  • +
', + 'in_total_revenue' => 'całkowity przychód', + 'billed_client' => 'Obciążony klient', + 'billed_clients' => 'Obciążeni klienci', + 'active_client' => 'Aktywny klient', + 'active_clients' => 'Aktywni klienci', + 'invoices_past_due' => 'Opóźnione faktury', + 'upcoming_invoices' => 'Nadchodzące Faktury', + 'average_invoice' => 'Średnia wartość Faktury', + 'archive' => 'Archiwum', + 'delete' => 'Usuń', + 'archive_client' => 'Zarchiwizuj klienta', + 'delete_client' => 'Usuń klienta', + 'archive_payment' => 'Zarchiwizuj płatność', + 'delete_payment' => 'Usuń płatność', + 'archive_credit' => 'Zarchiwizuj kredyt', + 'delete_credit' => 'Usuń kredyt', + 'show_archived_deleted' => 'Pokaż zarchiwizowane/usunięte', + 'filter' => 'Filtruj', + 'new_client' => 'Nowy klient', + 'new_invoice' => 'Nowa Faktura', + 'new_payment' => 'Nowa Płatność', + 'new_credit' => 'Nowy Kredyt', + 'contact' => 'Kontakt', + 'date_created' => 'Data utworzenia', + 'last_login' => 'Ostatnie logowanie', + 'balance' => 'Saldo', + 'action' => 'Akcja', + 'status' => 'Status', + 'invoice_total' => 'Faktura ogółem', + 'frequency' => 'Częstotliwość', + 'start_date' => 'Początkowa data', + 'end_date' => 'Końcowa data', + 'transaction_reference' => 'Referencja transakcji', + 'method' => 'Metoda', + 'payment_amount' => 'Kwota płatności', + 'payment_date' => 'Data płatności', + 'credit_amount' => 'Kwota kredytu', + 'credit_balance' => 'Saldo kredytowe', + 'credit_date' => 'Data kredytu', + 'empty_table' => 'Brak danych w tabeli', + 'select' => 'Wybierz', + 'edit_client' => 'Edytuj klienta', + 'edit_invoice' => 'Edytuj fakturę', + 'create_invoice' => 'Utwórz Fakturę', + 'enter_credit' => 'Wprowadź kredyt', + 'last_logged_in' => 'Ostatnie logowanie w', + 'details' => 'Szczegóły', + 'standing' => 'Standing', + 'credit' => 'Kredyt', + 'activity' => 'Czynność', + 'date' => 'Data', + 'message' => 'Wiadomość', + 'adjustment' => 'Dostosowanie', + 'are_you_sure' => 'Jesteś pewny?', + 'payment_type_id' => 'Typ płatności', + 'amount' => 'Kwota', + 'work_email' => 'Email', + 'language_id' => 'Język', + 'timezone_id' => 'Strefa czasowa', + 'date_format_id' => 'Format daty', + 'datetime_format_id' => 'Format Data/Godzina', + 'users' => 'Użytkownicy', + 'localization' => 'Lokalizacja', + 'remove_logo' => 'Usuń logo', + 'logo_help' => 'Obsługiwane: JPEG, GIF i PNG', + 'payment_gateway' => 'Bramka płatnicza', + 'gateway_id' => 'Bramka płatnicza', + 'email_notifications' => 'Email powiadomienia', + 'email_sent' => 'Powiadom mnie kiedy faktura jest wysłana', + 'email_viewed' => 'Powiadom mnie kiedy faktura jest otworzona', + 'email_paid' => 'Powiadom mnie kiedy faktura jest zapłacona', + 'site_updates' => 'Aktualizacje strony', + 'custom_messages' => 'Niestandardowe komunikaty', + 'default_email_footer' => 'Ustaw domyślny podpis email', + 'select_file' => 'Wybierz plik', + 'first_row_headers' => 'Użyj pierwszego wiersza jako nagłówek', + 'column' => 'Kolumna', + 'sample' => 'Przykład', + 'import_to' => 'Zaimportuj do', + 'client_will_create' => 'klient będzie utworzony', + 'clients_will_create' => 'klienci będą utworzeni', + 'email_settings' => 'Ustawienia e-mail', + 'client_view_styling' => 'Client View Styling', + 'pdf_email_attachment' => 'Attach PDFs', + 'custom_css' => 'Custom CSS', + 'import_clients' => 'Import Client Data', + 'csv_file' => 'CSV file', + 'export_clients' => 'Export Client Data', + 'created_client' => 'Successfully created client', + 'created_clients' => 'Successfully created :count client(s)', + 'updated_settings' => 'Successfully updated settings', + 'removed_logo' => 'Successfully removed logo', + 'sent_message' => 'Successfully sent message', + 'invoice_error' => 'Please make sure to select a client and correct any errors', + 'limit_clients' => 'Sorry, this will exceed the limit of :count clients', + 'payment_error' => 'There was an error processing your payment. Please try again later.', + 'registration_required' => 'Please sign up to email an invoice', + 'confirmation_required' => 'Please confirm your email address', + 'updated_client' => 'Successfully updated client', + 'created_client' => 'Successfully created client', + 'archived_client' => 'Successfully archived client', + 'archived_clients' => 'Successfully archived :count clients', + 'deleted_client' => 'Successfully deleted client', + 'deleted_clients' => 'Successfully deleted :count clients', + 'updated_invoice' => 'Successfully updated invoice', + 'created_invoice' => 'Successfully created invoice', + 'cloned_invoice' => 'Successfully cloned invoice', + 'emailed_invoice' => 'Successfully emailed invoice', + 'and_created_client' => 'and created client', + 'archived_invoice' => 'Successfully archived invoice', + 'archived_invoices' => 'Successfully archived :count invoices', + 'deleted_invoice' => 'Successfully deleted invoice', + 'deleted_invoices' => 'Successfully deleted :count invoices', + 'created_payment' => 'Successfully created payment', + 'created_payments' => 'Successfully created :count payment(s)', + 'archived_payment' => 'Successfully archived payment', + 'archived_payments' => 'Successfully archived :count payments', + 'deleted_payment' => 'Successfully deleted payment', + 'deleted_payments' => 'Successfully deleted :count payments', + 'applied_payment' => 'Successfully applied payment', + 'created_credit' => 'Successfully created credit', + 'archived_credit' => 'Successfully archived credit', + 'archived_credits' => 'Successfully archived :count credits', + 'deleted_credit' => 'Successfully deleted credit', + 'deleted_credits' => 'Successfully deleted :count credits', + 'imported_file' => 'Successfully imported file', + 'updated_vendor' => 'Successfully updated vendor', + 'created_vendor' => 'Successfully created vendor', + 'archived_vendor' => 'Successfully archived vendor', + 'archived_vendors' => 'Successfully archived :count vendors', + 'deleted_vendor' => 'Successfully deleted vendor', + 'deleted_vendors' => 'Successfully deleted :count vendors', + 'confirmation_subject' => 'Invoice Ninja Account Confirmation', + 'confirmation_header' => 'Account Confirmation', + 'confirmation_message' => 'Please access the link below to confirm your account.', + 'invoice_subject' => 'New invoice :invoice from :account', + 'invoice_message' => 'To view your invoice for :amount, click the link below.', + 'payment_subject' => 'Payment Received', + 'payment_message' => 'Thank you for your payment of :amount.', + 'email_salutation' => 'Drogi :name,', + 'email_signature' => 'Pozdrowienia,', + 'email_from' => 'Zespół The Invoice Ninja', + 'invoice_link_message' => 'To view the invoice click the link below:', + 'notification_invoice_paid_subject' => 'Invoice :invoice was paid by :client', + 'notification_invoice_sent_subject' => 'Invoice :invoice was sent to :client', + 'notification_invoice_viewed_subject' => 'Invoice :invoice was viewed by :client', + 'notification_invoice_paid' => 'A payment of :amount was made by client :client towards Invoice :invoice.', + 'notification_invoice_sent' => 'The following client :client was emailed Invoice :invoice for :amount.', + 'notification_invoice_viewed' => 'The following client :client viewed Invoice :invoice for :amount.', + 'reset_password' => 'You can reset your account password by clicking the following button:', + 'secure_payment' => 'Bezpieczna płatność', + 'card_number' => 'Numer karty', + 'expiration_month' => 'Expiration Month', + 'expiration_year' => 'Expiration Year', + 'cvv' => 'CVV', + 'logout' => 'Wyloguj się', + 'sign_up_to_save' => 'Sign up to save your work', + 'agree_to_terms' => 'I agree to the Invoice Ninja :terms', + 'terms_of_service' => 'Terms of Service', + 'email_taken' => 'The email address is already registered', + 'working' => 'Working', + 'success' => 'Success', + 'success_message' => 'You have successfully registered! Please visit the link in the account confirmation email to verify your email address.', + 'erase_data' => 'This will permanently erase your data.', + 'password' => 'Hasło', + 'pro_plan_product' => 'Pro Plan', + 'pro_plan_success' => 'Thanks for choosing Invoice Ninja\'s Pro plan!

 
+ Next Steps

A payable invoice has been sent to the email + address associated with your account. To unlock all of the awesome + Pro features, please follow the instructions on the invoice to pay + for a year of Pro-level invoicing.

+ Can\'t find the invoice? Need further assistance? We\'re happy to help + -- email us at contact@invoiceninja.com', + 'unsaved_changes' => 'You have unsaved changes', + 'custom_fields' => 'Custom Fields', + 'company_fields' => 'Company Fields', + 'client_fields' => 'Client Fields', + 'field_label' => 'Field Label', + 'field_value' => 'Field Value', + 'edit' => 'Edytuj', + 'set_name' => 'Set your company name', + 'view_as_recipient' => 'View as recipient', + 'product_library' => 'Product Library', + 'product' => 'Produkt', + 'products' => 'Produkty', + 'fill_products' => 'Auto-fill products', + 'fill_products_help' => 'Selecting a product will automatically fill in the description and cost', + 'update_products' => 'Auto-update products', + 'update_products_help' => 'Updating an invoice will automatically update the product library', + 'create_product' => 'Add Product', + 'edit_product' => 'Edit Product', + 'archive_product' => 'Archive Product', + 'updated_product' => 'Successfully updated product', + 'created_product' => 'Successfully created product', + 'archived_product' => 'Successfully archived product', + 'pro_plan_custom_fields' => ':link to enable custom fields by joining the Pro Plan', + 'advanced_settings' => 'Advanced Settings', + 'pro_plan_advanced_settings' => ':link to enable the advanced settings by joining the Pro Plan', + 'invoice_design' => 'Invoice Design', + 'specify_colors' => 'Specify colors', + 'specify_colors_label' => 'Select the colors used in the invoice', + 'chart_builder' => 'Chart Builder', + 'ninja_email_footer' => 'Use :site to invoice your clients and get paid online for free!', + 'go_pro' => 'Go Pro', + 'quote' => 'Oferta', + 'quotes' => 'Oferty', + 'quote_number' => 'Numer oferty', + 'quote_number_short' => 'Oferta #', + 'quote_date' => 'Data oferty', + 'quote_total' => 'Suma oferty', + 'your_quote' => 'Twoja oferta', + 'total' => 'Suma', + 'clone' => 'Clone', + 'new_quote' => 'Nowa oferta', + 'create_quote' => 'Stwórz ofertę', + 'edit_quote' => 'Edytuj ofertę', + 'archive_quote' => 'Archiwizuj ofertę', + 'delete_quote' => 'Usuń ofertę', + 'save_quote' => 'Zapisz ofertę', + 'email_quote' => 'Wyślij ofertę', + 'clone_quote' => 'Clone Quote', + 'convert_to_invoice' => 'Konwertuj do faktury', + 'view_invoice' => 'Zobacz fakturę', + 'view_client' => 'Zobacz klienta', + 'view_quote' => 'Zobacz ofertę', + 'updated_quote' => 'Successfully updated quote', + 'created_quote' => 'Successfully created quote', + 'cloned_quote' => 'Successfully cloned quote', + 'emailed_quote' => 'Successfully emailed quote', + 'archived_quote' => 'Successfully archived quote', + 'archived_quotes' => 'Successfully archived :count quotes', + 'deleted_quote' => 'Successfully deleted quote', + 'deleted_quotes' => 'Successfully deleted :count quotes', + 'converted_to_invoice' => 'Successfully converted quote to invoice', + 'quote_subject' => 'New quote $quote from :account', + 'quote_message' => 'To view your quote for :amount, click the link below.', + 'quote_link_message' => 'To view your client quote click the link below:', + 'notification_quote_sent_subject' => 'Quote :invoice was sent to :client', + 'notification_quote_viewed_subject' => 'Quote :invoice was viewed by :client', + 'notification_quote_sent' => 'The following client :client was emailed Quote :invoice for :amount.', + 'notification_quote_viewed' => 'The following client :client viewed Quote :invoice for :amount.', + 'session_expired' => 'Your session has expired.', + 'invoice_fields' => 'Invoice Fields', + 'invoice_options' => 'Invoice Options', + 'hide_quantity' => 'Hide Quantity', + 'hide_quantity_help' => 'If your line items quantities are always 1, then you can declutter invoices by no longer displaying this field.', + 'hide_paid_to_date' => 'Hide Paid to Date', + 'hide_paid_to_date_help' => 'Only display the "Paid to Date" area on your invoices once a payment has been received.', + 'charge_taxes' => 'Charge taxes', + 'user_management' => 'User Management', + 'add_user' => 'Add User', + 'send_invite' => 'Send invitation', + 'sent_invite' => 'Successfully sent invitation', + 'updated_user' => 'Successfully updated user', + 'invitation_message' => 'You\'ve been invited by :invitor. ', + 'register_to_add_user' => 'Please sign up to add a user', + 'user_state' => 'State', + 'edit_user' => 'Edit User', + 'delete_user' => 'Delete User', + 'active' => 'Active', + 'pending' => 'Pending', + 'deleted_user' => 'Successfully deleted user', + 'confirm_email_invoice' => 'Are you sure you want to email this invoice?', + 'confirm_email_quote' => 'Are you sure you want to email this quote?', + 'confirm_recurring_email_invoice' => 'Are you sure you want this invoice emailed?', + 'cancel_account' => 'Usuń konto', + 'cancel_account_message' => 'Warning: This will permanently erase all of your data, there is no undo.', + 'go_back' => 'Go Back', + 'data_visualizations' => 'Data Visualizations', + 'sample_data' => 'Sample data shown', + 'hide' => 'Hide', + 'new_version_available' => 'A new version of :releases_link is available. You\'re running v:user_version, the latest is v:latest_version', + 'invoice_settings' => 'Invoice Settings', + 'invoice_number_prefix' => 'Invoice Number Prefix', + 'invoice_number_counter' => 'Invoice Number Counter', + 'quote_number_prefix' => 'Quote Number Prefix', + 'quote_number_counter' => 'Quote Number Counter', + 'share_invoice_counter' => 'Share invoice counter', + 'invoice_issued_to' => 'Invoice issued to', + 'invalid_counter' => 'To prevent a possible conflict please set either an invoice or quote number prefix', + 'mark_sent' => 'Mark Sent', + 'gateway_help_1' => ':link to sign up for Authorize.net.', + 'gateway_help_2' => ':link to sign up for Authorize.net.', + 'gateway_help_17' => ':link to get your PayPal API signature.', + 'gateway_help_27' => ':link to sign up for TwoCheckout.', + 'more_designs' => 'More designs', + 'more_designs_title' => 'Additional Invoice Designs', + 'more_designs_cloud_header' => 'Go Pro for more invoice designs', + 'more_designs_cloud_text' => '', + 'more_designs_self_host_text' => '', + 'buy' => 'Buy', + 'bought_designs' => 'Successfully added additional invoice designs', + 'sent' => 'sent', + 'vat_number' => 'VAT Number', + 'timesheets' => 'Timesheets', + 'payment_title' => 'Enter Your Billing Address and Credit Card information', + '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.', + 'id_number' => 'ID Number', + 'white_label_link' => 'White label', + 'white_label_header' => 'White Label', + 'bought_white_label' => 'Successfully enabled white label license', + 'white_labeled' => 'White labeled', + 'restore' => 'Przywróć', + 'restore_invoice' => 'Przywróć fakturę', + 'restore_quote' => 'Przywróć ofertę', + 'restore_client' => 'Przywróć klienta', + 'restore_credit' => 'Przywróć kredyt', + 'restore_payment' => 'Przywróć płatność', + 'restored_invoice' => 'Faktura została przywrócona', + 'restored_quote' => 'Oferta została przywrócona', + 'restored_client' => 'Klient został przywrócony', + 'restored_payment' => 'Płatność została przywrócona', + 'restored_credit' => 'Kredyt został przywrócony', + 'reason_for_canceling' => 'Help us improve our site by telling us why you\'re leaving.', + 'discount_percent' => 'Procent', + 'discount_amount' => 'Kwota', + 'invoice_history' => 'Historia faktury', + 'quote_history' => 'Historia oferty', + 'current_version' => 'Aktualna wersja', + 'select_version' => 'Wybierz wersję', + 'view_history' => 'Zobacz historię', + 'edit_payment' => 'Edytuj płatność', + 'updated_payment' => 'Successfully updated payment', + 'deleted' => 'Usunięte', + 'restore_user' => 'Przywróć użytkownika', + 'restored_user' => 'Użytkownik został przywrócony', + 'show_deleted_users' => 'Pokaż usuniętych użytkowników', + 'email_templates' => 'Szablony e-mail', + 'invoice_email' => 'Email faktury', + 'payment_email' => 'Email płatności', + 'quote_email' => 'Email oferty', + 'reset_all' => 'Resetuj wszystko', + 'approve' => 'Zatwierdź', + 'token_billing_type_id' => 'Token Billing', + 'token_billing_help' => 'Enables you to store credit cards with your gateway, and charge them at a later date.', + 'token_billing_1' => 'Wyłączone', + 'token_billing_2' => 'Opt-in - checkbox is shown but not selected', + 'token_billing_3' => 'Opt-out - checkbox is shown and selected', + 'token_billing_4' => 'Zawsze', + 'token_billing_checkbox' => 'Store credit card details', + 'view_in_stripe' => 'View in Stripe', + 'use_card_on_file' => 'Use card on file', + 'edit_payment_details' => 'Edit payment details', + 'token_billing' => 'Save card details', + 'token_billing_secure' => 'The data is stored securely by :stripe_link', + 'support' => 'Support', + 'contact_information' => 'Contact Information', + '256_encryption' => '256-Bit Encryption', + 'amount_due' => 'Amount due', + 'billing_address' => 'Adres billingowy (rozliczeniowy)', + 'billing_method' => 'Billing Method', + '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.', + 'invoice_footer' => 'Stopka faktury', + 'save_as_default_footer' => 'Save as default footer', + 'token_management' => 'Token Management', + 'tokens' => 'Tokens', + 'add_token' => 'Add Token', + 'show_deleted_tokens' => 'Show deleted tokens', + 'deleted_token' => 'Successfully deleted token', + 'created_token' => 'Successfully created token', + 'updated_token' => 'Successfully updated token', + 'edit_token' => 'Edit Token', + 'delete_token' => 'Delete Token', + 'token' => 'Token', + 'add_gateway' => 'Add Gateway', + 'delete_gateway' => 'Delete Gateway', + 'edit_gateway' => 'Edit Gateway', + 'updated_gateway' => 'Successfully updated gateway', + 'created_gateway' => 'Successfully created gateway', + 'deleted_gateway' => 'Successfully deleted gateway', + 'pay_with_paypal' => 'PayPal', + 'pay_with_card' => 'Credit Card', + 'change_password' => 'Zmień hasło', + 'current_password' => 'Aktualne hasło', + 'new_password' => 'Nowe hasło', + 'confirm_password' => 'Potwierdź hasło', + 'password_error_incorrect' => 'The current password is incorrect.', + 'password_error_invalid' => 'The new password is invalid.', + 'updated_password' => 'Successfully updated password', + 'api_tokens' => 'API Tokens', + 'users_and_tokens' => 'Users & Tokens', + 'account_login' => 'Account Login', + 'recover_password' => 'Recover your password', + 'forgot_password' => 'Forgot your password?', + 'email_address' => 'Email address', + 'lets_go' => 'Let\'s go', + 'password_recovery' => 'Password Recovery', + 'send_email' => 'Wyślij email', + 'set_password' => 'Ustaw hasło', + 'converted' => 'Converted', + 'email_approved' => 'Email me when a quote is approved', + '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.
Note: use a Legacy API Key, not an API token.', + 'payment_type_credit_card' => 'Karta kredytowa', + 'payment_type_paypal' => 'PayPal', + 'payment_type_bitcoin' => 'Bitcoin', + 'knowledge_base' => 'Baza wiedzy', + 'partial' => 'Partial', + 'partial_remaining' => ':partial of :balance', + 'more_fields' => 'More Fields', + 'less_fields' => 'Less Fields', + 'client_name' => 'Nazwa klienta', + 'pdf_settings' => 'Ustawienia PDF', + 'product_settings' => 'Ustawienia produktu', + 'auto_wrap' => 'Auto Line Wrap', + 'duplicate_post' => 'Warning: the previous page was submitted twice. The second submission had been ignored.', + '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' => 'wierszy', + 'www' => 'www', + 'logo' => 'Logo', + 'subdomain' => 'Subdomain', + 'provide_name_or_email' => 'Proszę podać imię i nazwisko lub adres e-mail', + 'charts_and_reports' => 'Raporty i wykresy', + 'chart' => 'Wykres', + 'report' => 'Raport', + 'group_by' => 'Grupuj według', + 'paid' => 'Zapłacone', + 'enable_report' => 'Raport', + 'enable_chart' => 'Wykres', + 'totals' => 'Suma', + 'run' => 'Run', + 'export' => 'Export', + 'documentation' => 'Documentation', + 'zapier' => 'Zapier', + 'recurring' => 'Okresowe', + 'last_invoice_sent' => 'Last invoice sent :date', + 'processed_updates' => 'Pomyślnie zakończona aktualizacja', + 'tasks' => 'Zadania', + 'new_task' => 'Nowe zadanie', + 'start_time' => 'Czas rozpoczęcia', + 'created_task' => 'Pomyślnie utworzono zadanie', + 'updated_task' => 'Pomyślnie zaktualizowano zadanie', + 'edit_task' => 'Edytuj zadanie', + 'archive_task' => 'Archiwizuj zadanie', + 'restore_task' => 'Przywróć zadanie', + 'delete_task' => 'Usuń zadanie', + 'stop_task' => 'Zatrzymaj zadanie', + 'time' => 'Czas', + 'start' => 'Rozpocznij', + 'stop' => 'Zatrzymaj', + 'now' => 'Teraz', + 'timer' => 'Czasomierz', + 'manual' => 'Manualnie', + 'date_and_time' => 'Data i czas', + 'second' => 'sekunda', + 'seconds' => 'sekund', + 'minute' => 'minuta', + 'minutes' => 'minut', + 'hour' => 'godzina', + 'hours' => 'godzin', + 'task_details' => 'Szczegóły zadania', + 'duration' => 'Czas trwania', + 'end_time' => 'Czas zakończenia', + 'end' => 'Koniec', + 'invoiced' => 'Invoiced', + 'logged' => 'Zalogowany', + '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', + 'invoice_labels' => 'Invoice Labels', + 'prefix' => 'Prefix', + 'counter' => 'Counter', + 'payment_type_dwolla' => 'Dwolla', + 'gateway_help_43' => ':link to sign up for Dwolla', + 'partial_value' => 'Must be greater than zero and less than the total', + 'more_actions' => 'More Actions', + 'pro_plan_title' => 'NINJA PRO', + 'pro_plan_call_to_action' => 'Upgrade Now!', + 'pro_plan_feature1' => 'Create Unlimited Clients', + 'pro_plan_feature2' => 'Access to 10 Beautiful Invoice Designs', + 'pro_plan_feature3' => 'Custom URLs - "YourBrand.InvoiceNinja.com"', + 'pro_plan_feature4' => 'Remove "Created by Invoice Ninja"', + 'pro_plan_feature5' => 'Multi-user Access & Activity Tracking', + 'pro_plan_feature6' => 'Create Quotes & Pro-forma Invoices', + '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', + 'timezone_unset' => 'Please :link to set your timezone', + 'click_here' => 'click here', + 'email_receipt' => 'Wyślij potwierdzenie zapłaty do klienta', + 'created_payment_emailed_client' => 'Successfully created payment and emailed client', + 'add_company' => 'Add Company', + 'untitled' => 'Untitled', + 'new_company' => 'New Company', + 'associated_accounts' => 'Successfully linked accounts', + 'unlinked_account' => 'Successfully unlinked accounts', + 'login' => 'Login', + 'or' => 'or', + 'email_error' => 'There was a problem sending the email', + 'confirm_recurring_timing' => 'Note: emails are sent at the start of the hour.', + 'payment_terms_help' => 'Sets the default invoice due date', + 'unlink_account' => 'Unlink Account', + 'unlink' => 'Unlink', + 'show_address' => 'Show Address', + 'show_address_help' => 'Require client to provide their billing address', + 'update_address' => 'Update Address', + 'update_address_help' => 'Update client\'s address with provided details', + 'times' => 'krotnie', + 'set_now' => 'Ustaw na teraz', + 'dark_mode' => 'Tryb ciemny', + 'dark_mode_help' => 'Show white text on black background', + 'add_to_invoice' => 'Add to invoice :invoice', + 'create_new_invoice' => 'Create new invoice', + 'task_errors' => 'Please correct any overlapping times', + 'from' => 'From', + 'to' => 'To', + 'font_size' => 'Font Size', + 'primary_color' => 'Primary Color', + 'secondary_color' => 'Secondary Color', + 'customize_design' => 'Customize Design', + 'content' => 'Content', + 'styles' => 'Styles', + 'defaults' => 'Defaults', + 'margins' => 'Margins', + 'header' => 'Header', + 'footer' => 'Footer', + 'custom' => 'Custom', + 'invoice_to' => 'Invoice to', + 'invoice_no' => 'Invoice No.', + 'recent_payments' => 'Ostatnie płatności', + 'outstanding' => 'Zaległe', + 'manage_companies' => 'Manage Companies', + 'total_revenue' => 'Całkowity dochód', + 'current_user' => 'Aktualny użytkownik', + 'new_recurring_invoice' => 'Nowa faktura okresowa', + 'recurring_invoice' => 'Okresowa faktura', + 'recurring_too_soon' => 'It\'s too soon to create the next recurring invoice, it\'s scheduled for :date', + 'created_by_invoice' => 'Utworzona przez :invoice', + 'primary_user' => 'Główny Użytkownik', + 'help' => 'Pomoc', + 'customize_help' => '

We use pdfmake to define the invoice designs declaratively. The pdfmake playground provide\'s a great way to see the library in action.

+

To access a child property using dot notation. For example to show the client name you could use $client.name.

+

If you need help figuring something out post a question to our support forum.

', + 'invoice_due_date' => 'Termin', + 'quote_due_date' => 'Valid Until', + 'valid_until' => 'Valid Until', + 'reset_terms' => 'Resetuj warunki', + 'reset_footer' => 'Resetuj stópkę', + 'invoices_sent' => ':count faktura wysłana|:count faktury wysłane', + 'status_draft' => 'Wersja robocza', + 'status_sent' => 'Wysłane', + 'status_viewed' => 'Przeglądnięte', + 'status_partial' => 'Częściowo', + 'status_paid' => 'Zapłacone', + 'show_line_item_tax' => 'Wyświetl podatki pozycji w tej samej linii', + 'iframe_url' => 'Website', + 'iframe_url_help1' => 'Copy the following code to a page on your site.', + 'iframe_url_help2' => 'You can test the feature by clicking \'View as recipient\' for an invoice.', + 'auto_bill' => 'Automatyczny Rachunek', + 'military_time' => '24 godzinny czas', + 'last_sent' => 'Ostatnio wysłany', + 'reminder_emails' => 'Reminder Emails', + 'templates_and_reminders' => 'Szablony i przypomnienia', + 'subject' => 'Temat', + 'body' => 'Treść', + 'first_reminder' => 'Pierwsze przypomnienie', + 'second_reminder' => 'Drugie przypomnienie', + 'third_reminder' => 'Trzecie przypomnienie', + 'num_days_reminder' => 'Dni po terminie', + 'reminder_subject' => 'Reminder: Invoice :invoice from :account', + 'reset' => 'Reset', + 'invoice_not_found' => 'The requested invoice is not available', + 'referral_program' => 'Program referencyjny', + 'referral_code' => 'Referencyjny URL', + 'last_sent_on' => 'Ostatnio wysłany: :date', + 'page_expire' => 'This page will expire soon, :click_here to keep working', + 'upcoming_quotes' => 'Nadchodzące oferty', + 'expired_quotes' => 'Wygaśnięte oferty', + 'sign_up_using' => 'Zarejestruj się przy użyciu', + 'invalid_credentials' => 'These credentials do not match our records', + 'show_all_options' => 'Pokaż wszystkie opcje', + 'user_details' => 'Dane użytkownika', + 'oneclick_login' => 'One-Click Logowanie', + 'disable' => 'Wyłącz', + 'invoice_quote_number' => 'Numery faktur i ofert', + 'invoice_charges' => 'Opłaty faktury', + 'notification_invoice_bounced' => 'We were unable to deliver Invoice :invoice to :contact.', + 'notification_invoice_bounced_subject' => 'Unable to deliver Invoice :invoice', + 'notification_quote_bounced' => 'We were unable to deliver Quote :invoice to :contact.', + 'notification_quote_bounced_subject' => 'Unable to deliver Quote :invoice', + 'custom_invoice_link' => 'Custom Invoice Link', + 'total_invoiced' => 'Total Invoiced', + 'open_balance' => 'Open Balance', + 'verify_email' => 'Please visit the link in the account confirmation email to verify your email address.', + 'basic_settings' => 'Ustawienia podstawowe', + 'pro' => 'Pro', + 'gateways' => 'Payment Gateways', + 'next_send_on' => 'Send Next: :date', + 'no_longer_running' => 'This invoice is not scheduled to run', + 'general_settings' => 'General Settings', + 'customize' => 'Customize', + 'oneclick_login_help' => 'Connect an account to login without a password', + 'referral_code_help' => 'Earn money by sharing our app online', + 'enable_with_stripe' => 'Aktywuj | Wymaga Stripe', + 'tax_settings' => 'Tax Settings', + 'create_tax_rate' => 'Dodaj stawkę podatkową', + 'updated_tax_rate' => 'Successfully updated tax rate', + 'created_tax_rate' => 'Successfully created tax rate', + 'edit_tax_rate' => 'Edit tax rate', + 'archive_tax_rate' => 'Archive Tax Rate', + 'archived_tax_rate' => 'Successfully archived the tax rate', + 'default_tax_rate_id' => 'Domyśłna stawka podatkowa', + 'tax_rate' => 'Stawka podatkowa', + 'recurring_hour' => 'Okresowa godzina', + 'pattern' => 'Pattern', + 'pattern_help_title' => 'Pattern Help', + 'pattern_help_1' => 'Create custom invoice and quote numbers by specifying a pattern', + 'pattern_help_2' => 'Available variables:', + 'pattern_help_3' => 'For example, :example would be converted to :value', + 'see_options' => 'See options', + 'invoice_counter' => 'Invoice Counter', + 'quote_counter' => 'Quote Counter', + 'type' => 'Type', + 'activity_1' => ':user created client :client', + 'activity_2' => ':user archived client :client', + 'activity_3' => ':user deleted client :client', + 'activity_4' => ':user created invoice :invoice', + 'activity_5' => ':user updated invoice :invoice', + 'activity_6' => ':user emailed invoice :invoice to :contact', + 'activity_7' => ':contact viewed invoice :invoice', + 'activity_8' => ':user archived invoice :invoice', + 'activity_9' => ':user deleted invoice :invoice', + 'activity_10' => ':contact entered payment :payment for :invoice', + 'activity_11' => ':user updated payment :payment', + 'activity_12' => ':user archived payment :payment', + 'activity_13' => ':user deleted payment :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_18' => ':user created quote :quote', + 'activity_19' => ':user updated quote :quote', + 'activity_20' => ':user emailed quote :quote to :contact', + 'activity_21' => ':contact viewed quote :quote', + 'activity_22' => ':user archived quote :quote', + 'activity_23' => ':user deleted quote :quote', + 'activity_24' => ':user restored quote :quote', + 'activity_25' => ':user restored invoice :invoice', + 'activity_26' => ':user restored client :client', + 'activity_27' => ':user restored payment :payment', + 'activity_28' => ':user restored :credit credit', + 'activity_29' => ':contact approved quote :quote', + 'activity_30' => ':user created :vendor', + 'activity_31' => ':user created :vendor', + 'activity_32' => ':user created :vendor', + 'activity_33' => ':user created :vendor', + 'activity_34' => ':user created expense :expense', + 'activity_35' => ':user created :vendor', + 'activity_36' => ':user created :vendor', + 'activity_37' => ':user created :vendor', + 'payment' => 'Payment', + 'system' => 'System', + 'signature' => 'Podpis e-mail', + 'default_messages' => 'Default Messages', + 'quote_terms' => 'Warunki oferty', + 'default_quote_terms' => 'Domyślne warunki oferty', + 'default_invoice_terms' => 'Domyślne warunki faktury', + 'default_invoice_footer' => 'Domyślna stopka faktury', + 'quote_footer' => 'Quote Footer', + 'free' => 'Free', + 'quote_is_approved' => 'This quote is approved', + 'apply_credit' => 'Apply Credit', + 'system_settings' => 'System Settings', + 'archive_token' => 'Archive Token', + 'archived_token' => 'Successfully archived token', + 'archive_user' => 'Archive User', + 'archived_user' => 'Successfully archived user', + 'archive_account_gateway' => 'Archive Gateway', + 'archived_account_gateway' => 'Successfully archived gateway', + 'archive_recurring_invoice' => 'Archiwizuj okresową fakturę', + 'archived_recurring_invoice' => 'Okresowa faktura została zarchiwizowana', + 'delete_recurring_invoice' => 'Usuń okresową fakturę', + 'deleted_recurring_invoice' => 'Okresowa faktura została usunięta.', + 'restore_recurring_invoice' => 'Przywróć okresową fakturę', + 'restored_recurring_invoice' => 'Okresowa faktura została przywrócona', + 'archived' => 'Zarchiwizowany', + 'untitled_account' => 'Firma bez nazwy', + 'before' => 'Przed', + 'after' => 'Po', + 'reset_terms_help' => 'Reset to the default account terms', + 'reset_footer_help' => 'Reset to the default account footer', + 'export_data' => 'Exportuj dane', + 'user' => 'Użytkownik', + 'country' => 'Kraj', + 'include' => 'Include', + 'logo_too_large' => 'Your logo is :size, for better PDF performance we suggest uploading an image file less than 200KB', + 'import_freshbooks' => 'Import From FreshBooks', + 'import_data' => 'Import Data', + 'source' => 'Źródło', + 'csv' => 'CSV', + 'client_file' => 'Plik klienta', + 'invoice_file' => 'Plik faktury', + 'task_file' => 'Plik zadania', + 'no_mapper' => 'No valid mapping for file', + 'invalid_csv_header' => 'Invalid CSV Header', + 'client_portal' => 'Portal klienta', + 'admin' => 'Administrator', + 'disabled' => 'Wyłączony', + 'show_archived_users' => 'Pokaż zarchiwizowanych użytkowników', + 'notes' => 'Notatki', + 'invoice_will_create' => 'client will be created', + 'invoices_will_create' => 'invoices will be created', + 'failed_to_import' => 'The following records failed to import, they either already exist or are missing required fields.', + 'publishable_key' => 'Publishable Key', + 'secret_key' => 'Sekretny klucz', + 'missing_publishable_key' => 'Set your Stripe publishable key for an improved checkout process', + 'email_design' => 'Email Design', + 'due_by' => 'Płatny do :date', + 'enable_email_markup' => 'Enable Markup', + 'enable_email_markup_help' => 'Make it easier for your clients to pay you by adding schema.org markup to your emails.', + 'template_help_title' => 'Templates Help', + 'template_help_1' => 'Available variables:', + 'email_design_id' => 'Email Style', + 'email_design_help' => 'Make your emails look more professional with HTML layouts', + 'plain' => 'Plain', + 'light' => 'Light', + 'dark' => 'Dark', + 'industry_help' => 'Used to provide comparisons against the averages of companies of similar size and industry.', + 'subdomain_help' => 'Customize the invoice link subdomain or display the invoice on your own website.', + 'invoice_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the invoice number.', + 'quote_number_help' => 'Specify a prefix or use a custom pattern to dynamically set the quote number.', + 'custom_client_fields_helps' => 'Add a field when creating a client and display the label and value on the PDF.', + 'custom_account_fields_helps' => 'Add a label and value to the company details section of the PDF.', + 'custom_invoice_fields_helps' => 'Add a field when creating an invoice and display the label and value on the PDF.', + 'custom_invoice_charges_helps' => 'Add a field when creating an invoice and include the charge in the invoice subtotals.', + 'token_expired' => 'Validation token was expired. Please try again.', + 'invoice_link' => 'Invoice Link', + 'button_confirmation_message' => 'Click to confirm your email address.', + 'confirm' => 'Confirm', + 'email_preferences' => 'Email Preferences', + 'created_invoices' => 'Successfully created :count invoice(s)', + 'next_invoice_number' => 'The next invoice number is :number.', + 'next_quote_number' => 'The next quote number is :number.', + 'days_before' => 'days before', + 'days_after' => 'days after', + 'field_due_date' => 'termin', + 'field_invoice_date' => 'invoice date', + 'schedule' => 'Schedule', + 'email_designs' => 'Email Designs', + 'assigned_when_sent' => 'Assigned when sent', + 'white_label_purchase_link' => 'Purchase a white label license', + 'expense' => 'Wydatek', + 'expenses' => 'Wydatki', + 'new_expense' => 'Nowy wydatek', + 'enter_expense' => 'Dodaj wydatek', + 'vendors' => 'Vendors', + 'new_vendor' => 'New Vendor', + 'payment_terms_net' => 'Net', + 'vendor' => 'Vendor', + 'edit_vendor' => 'Edit Vendor', + 'archive_vendor' => 'Archive Vendor', + 'delete_vendor' => 'Delete Vendor', + 'view_vendor' => 'View Vendor', + 'deleted_expense' => 'Successfully deleted expense', + 'archived_expense' => 'Successfully archived expense', + 'deleted_expenses' => 'Successfully deleted expenses', + 'archived_expenses' => 'Successfully archived expenses', + 'expense_amount' => 'Expense Amount', + 'expense_balance' => 'Expense Balance', + 'expense_date' => 'Expense Date', + 'expense_should_be_invoiced' => 'Should this expense be invoiced?', + 'public_notes' => 'Public Notes', + 'invoice_amount' => 'Invoice Amount', + 'exchange_rate' => 'Exchange Rate', + 'yes' => 'Yes', + 'no' => 'No', + 'should_be_invoiced' => 'Should be invoiced', + 'view_expense' => 'View expense # :expense', + 'edit_expense' => 'Edit Expense', + 'archive_expense' => 'Archive Expense', + 'delete_expense' => 'Delete Expense', + 'view_expense_num' => 'Expense # :expense', + 'updated_expense' => 'Successfully updated expense', + 'created_expense' => 'Successfully created expense', + 'enter_expense' => 'Dodaj wydatek', + 'view' => 'View', + 'restore_expense' => 'Przywróć wydatek', + 'invoice_expense' => 'Faktura na wydatek', + 'expense_error_multiple_clients' => 'The expenses can\'t belong to different clients', + 'expense_error_invoiced' => 'Expense has already been invoiced', + 'convert_currency' => 'Konwersja waluty', + 'num_days' => 'Liczba dni', + 'create_payment_term' => 'Utwórz warunki płatności', + 'edit_payment_terms' => 'Edytuj warunki płatności', + 'edit_payment_term' => 'Edytuj warunki płatności', + 'archive_payment_term' => 'Zarchiwizuj warunki płatności', + 'recurring_due_dates' => 'Terminy faktur okresowych', + 'recurring_due_date_help' => '

Automatycznie ustawia termin faktury.

+

Invoices on a monthly or yearly cycle set to be due on or before the day they are created will be due the next month. Invoices set to be due on the 29th or 30th in months that don\'t have that day will be due the last day of the month.

+

Invoices on a weekly cycle set to be due on the day of the week they are created will be due the next week.

+

For example:

+
    +
  • Today is the 15th, due date is 1st of the month. The due date should likely be the 1st of the next month.
  • +
  • Today is the 15th, due date is the last day of the month. The due date will be the last day of the this month. +
  • +
  • Today is the 15th, due date is the 15th day of the month. The due date will be the 15th day of next month. +
  • +
  • Today is the Friday, due date is the 1st Friday after. The due date will be next Friday, not today. +
  • +
', + 'due' => 'Opłata', + 'next_due_on' => 'Następna opłata: :date', + 'use_client_terms' => 'Use client terms', + 'day_of_month' => ':ordinal day of month', + 'last_day_of_month' => 'Last day of month', + 'day_of_week_after' => ':ordinal :day after', + 'sunday' => 'Niedziela', + 'monday' => 'Poniedziałek', + 'tuesday' => 'Wtorek', + 'wednesday' => 'Środa', + 'thursday' => 'Czwartek', + 'friday' => 'Piątek', + 'saturday' => 'Sobota', + 'header_font_id' => 'Czcionka nagłówka', + 'body_font_id' => 'Czcionka', + 'color_font_help' => 'Notatka: Podstawowe kolory i czcionki są wykorzystywane na portalu klienta i w niestandardowych szablonach email-owych.', + 'live_preview' => 'Podgląd', + 'invalid_mail_config' => 'E-mail nie został wysłany. Sprawdź czy ustawienia mailowe są poprawne.', + 'invoice_message_button' => 'Aby wyświetlić fakturę za :amount, kliknij przycisk poniżej.', + 'quote_message_button' => 'Aby wyświetlić swoją ofertę na :amount, kliknij przycisk poniżej.', + 'payment_message_button' => 'Dziekuję za wpłatę :amount.', + 'payment_type_direct_debit' => 'Polecenie zapłaty', + 'bank_accounts' => 'Karty kredytowe i banki', + 'add_bank_account' => 'Dodaj konto bankowe', + 'setup_account' => 'Ustawienia konta', + 'import_expenses' => 'Koszty importu', + 'bank_id' => 'Bank', + 'integration_type' => 'Rodzaj integracji', + 'updated_bank_account' => 'Konto bankowe zostało zaktualizowane', + 'edit_bank_account' => 'Edytuj konto bankowe', + 'archive_bank_account' => 'Archiwizuj konto bankowe', + 'archived_bank_account' => 'Konto bankowe zostało zarchiwizowane.', + 'created_bank_account' => 'Konto bankowe zostało utworzone', + 'validate_bank_account' => 'Zatwierdź konto bankowe', + 'bank_password_help' => 'Notatka: Twoje hasło zostało wysłane bezpiecznie i nie jest przechowywane na naszych serwerach.', + 'bank_password_warning' => 'Ostrzeżenie: Twoje hasło może być wysłane w postaci zwykłego tekstu, rozwaź aktywację protokołu HTTPS.', + 'username' => 'Użytkownik', + 'account_number' => 'Numer konta', + 'account_name' => 'Nazwa konta', + 'bank_account_error' => 'Nie można pobrać danych konta, sprawdź uprawnienia.', + 'status_approved' => 'Zatwierdzono', + 'quote_settings' => 'Ustawienia oferty', + 'auto_convert_quote' => 'Automatycznie konwertuj ofertę', + 'auto_convert_quote_help' => 'Utwórz automatycznie fakturę z oferty zaakceptowanej przez klienta.', + 'validate' => 'Zatwierdź', + 'info' => 'Informacja', + 'imported_expenses' => 'Successfully created :count_vendors vendor(s) and :count_expenses expense(s)', + 'iframe_url_help3' => 'Note: if you plan on accepting credit cards details we strongly recommend enabling HTTPS on your site.', + 'expense_error_multiple_currencies' => 'The expenses can\'t have different currencies.', + 'expense_error_mismatch_currencies' => 'The client\'s currency does not match the expense currency.', + 'trello_roadmap' => 'Trello Roadmap', + 'header_footer' => 'Header/Footer', + 'first_page' => 'Pierwsza strona', + 'all_pages' => 'Wszystkie strony', + 'last_page' => 'Ostatnia strona', + 'all_pages_header' => 'Pokaż nagłówek na', + 'all_pages_footer' => 'Pokaż stopkę na', + 'invoice_currency' => 'Waluta faktury', + 'enable_https' => 'Zalecamy korzystanie z protokołu HTTPS, aby zaakceptować dane karty kredytowej online.', + 'quote_issued_to' => 'Oferta wydana do', + 'show_currency_code' => 'Kod waluty', + 'trial_message' => 'Twoje konto otrzyma bezpłatny dwutygodniowy okres próbny naszego pro planu.', + 'trial_footer' => 'Bezpłatny okres próbny ważny tylko :count dni, aby aktualizować kliknij: :link.', + 'trial_footer_last_day' => 'To ostatni dzień twojego bezpłatnego okresu próbnego, aby zaktualizować kliknij: :link.', + 'trial_call_to_action' => 'Rozpocznij darmowy okres próbny', + 'trial_success' => 'Darmowy okres próbny został włączony', + 'overdue' => 'Zaległy', + + + 'white_label_text' => 'Kup white label licencję na JEDEN ROK za $'.WHITE_LABEL_PRICE.' aby usunąć z portalu klienta logo Invoice Ninja i wesprzeć nasz projekt.', + 'user_email_footer' => 'Aby dostosować ustawienia powiadomień email, zobacz '.SITE_URL.'/settings/notifications', + 'reset_password_footer' => 'If you did not request this password reset please email our support: '.CONTACT_EMAIL, + 'limit_users' => 'Sorry, this will exceed the limit of '.MAX_NUM_USERS.' users', + 'more_designs_self_host_header' => 'Kup 6 szablonów faktur za jedyne $'.INVOICE_DESIGNS_PRICE, + 'old_browser' => 'Proszę użyć nowszej przeglądarki', + 'white_label_custom_css' => ':link for $'.WHITE_LABEL_PRICE.' to enable custom styling and help support our project.', + 'bank_accounts_help' => 'Connect a bank account to automatically import expenses and create vendors. Supports American Express and 400+ US banks.', + 'security' => [ + 'too_many_attempts' => 'Zbyt wiele prób. Spróbuj ponownie za kilka minut.', + 'wrong_credentials' => 'Nieprawidłowy e-mail lub hasło.', + 'confirmation' => 'Twoje konto zostało potwierdzone!', + 'wrong_confirmation' => 'Błędny kod potwierdzający.', + 'password_forgot' => 'Informacje dotyczące resetowania hasła zostały wysłane na Twój adres e-mail.', + 'password_reset' => 'Twoje hasło zostało zmienione.', + 'wrong_password_reset' => 'Nieprawidłowe hasło. Spróbuj ponownie', + ], + 'pro_plan' => [ + 'remove_logo' => ':link to remove the Invoice Ninja logo by joining the Pro Plan', + 'remove_logo_link' => 'Kliknij tutaj', + ], + 'invitation_status' => [ + 'sent' => 'E-mail wysłany', + 'opened' => 'Email otwarty', + 'viewed' => 'Przeglądana faktura', + ], + 'email_errors' => [ + 'inactive_client' => 'E-maile nie mogą być wysyłane do klientów nieaktywnych', + 'inactive_contact' => 'E-mail nie może zostać wysłany do nieaktywnych kontaktów', + 'inactive_invoice' => 'E-mail nie może zostać wysłany do nieaktywnych faktur', + 'user_unregistered' => 'Proszę zarejestrować swoje konto, aby wysyłać e-maile', + 'user_unconfirmed' => 'Proszę potwierdzić swoje konto do wysyłania e-maili', + 'invalid_contact_email' => 'Nieprawidłowy e-mail kontaktowy', + ], + + 'navigation' => 'Nawigacja', + 'list_invoices' => 'Lista faktur', + 'list_clients' => 'Lista klientów', + 'list_quotes' => 'Lista ofert', + 'list_tasks' => 'Lista zadań', + 'list_expenses' => 'Lista wydatków', + 'list_recurring_invoices' => 'Lista faktur okresowych', + 'list_payments' => 'Lista wpłat', + 'list_credits' => 'Lista kredytów', + 'tax_name' => 'Nazwa podatku', + 'report_settings' => 'Ustawienia raportu', + 'search_hotkey' => 'skrót to /', + + 'new_user' => 'Nowy użytkownik', + 'new_product' => 'Nowy produkt', + 'new_tax_rate' => 'Nowa stawka podatkowa', + 'invoiced_amount' => 'Fakturowana kwota', + 'invoice_item_fields' => 'Invoice Item Fields', + 'custom_invoice_item_fields_help' => 'Add a field when creating an invoice item and display the label and value on the PDF.', + 'recurring_invoice_number' => 'Numer faktury okresowej', + 'recurring_invoice_number_prefix_help' => 'Dodaj własny prefix do numeru faktury okresowej. Wartość domyślna to \'R\'.', + + // Client Passwords + 'enable_portal_password'=>'Hasło ochrony faktur', + 'enable_portal_password_help'=>'Allows you to set a password for each contact. If a password is set, the contact will be required to enter a password before viewing invoices.', + 'send_portal_password'=>'Generate password automatically', + 'send_portal_password_help'=>'If no password is set, one will be generated and sent with the first invoice.', + + 'expired' => 'Wygasło', + 'invalid_card_number' => 'Numer karty kredytowej jest nieprawidłowy.', + 'invalid_expiry' => 'Data ważności jest nieprawidłowa.', + 'invalid_cvv' => 'Kod CVV jest nieprawidłowy.', + 'cost' => 'Koszt', + 'create_invoice_for_sample' => 'Notatka: aby zobaczyć podgląd, utwórz fakturę.', + + // User Permissions + 'owner' => 'Właściciel', + 'administrator' => 'Administrator', + 'administrator_help' => 'Allow user to manage users, change settings and modify all records', + 'user_create_all' => 'Create clients, invoices, etc.', + 'user_view_all' => 'View all clients, invoices, etc.', + 'user_edit_all' => 'Edit all clients, invoices, etc.', + 'gateway_help_20' => ':link to sign up for Sage Pay.', + 'gateway_help_21' => ':link to sign up for Sage Pay.', + 'partial_due' => 'Partial Due', + 'restore_vendor' => 'Restore Vendor', + 'restored_vendor' => 'Successfully restored vendor', + 'restored_expense' => 'Successfully restored expense', + 'permissions' => 'Permissions', + 'create_all_help' => 'Allow user to create and modify records', + 'view_all_help' => 'Allow user to view records they didn\'t create', + 'edit_all_help' => 'Allow user to modify records they didn\'t create', + 'view_payment' => 'Zobacz wpłatę', + + 'january' => 'Styczeń', + 'february' => 'Luty', + 'march' => 'Marzec', + 'april' => 'Kwiecień', + 'may' => 'Maj', + 'june' => 'Czerwiec', + 'july' => 'Lipiec', + 'august' => 'Sierpień', + 'september' => 'Wrzesień', + 'october' => 'Październik', + 'november' => 'Listopad', + 'december' => 'Grudzień', + + // Documents + 'documents_header' => 'Dokumenty:', + 'email_documents_header' => 'Dokumenty:', + 'email_documents_example_1' => 'Widgets Receipt.pdf', + 'email_documents_example_2' => 'Final Deliverable.zip', + 'invoice_documents' => 'Dokumenty', + 'expense_documents' => 'Załączone dokumenty', + 'invoice_embed_documents' => 'Embed Documents', + 'invoice_embed_documents_help' => 'Include attached images in the invoice.', + 'document_email_attachment' => 'Załącz dokumenty', + 'download_documents' => 'Ściągnij dokumenty (:size)', + 'documents_from_expenses' => 'From Expenses:', + 'dropzone' => array(// See http://www.dropzonejs.com/#config-dictDefaultMessage + 'DefaultMessage' => 'Upuść pliki lub kliknij, aby przesłać', + 'FallbackMessage' => 'Your browser does not support drag\'n\'drop file uploads.', + 'FallbackText' => 'Please use the fallback form below to upload your files like in the olden days.', + 'FileTooBig' => 'Plik jest zbyt duży ({{filesize}}MiB). Max rozmiar pliku: {{maxFilesize}}MiB.', + 'InvalidFileType' => 'Nie możesz przesłać plików tego typu.', + 'ResponseError' => 'Serwer zwraca {{statusCode}} kod.', + 'CancelUpload' => 'Anuluj przesyłanie', + 'CancelUploadConfirmation' => 'Czy na pewno chcesz anulować przesyłanie pliku?', + 'RemoveFile' => 'Usuń plik', + ), + 'documents' => 'Dokumenty', + 'document_date' => 'Data dokumentu', + 'document_size' => 'Rozmiar', + + 'enable_client_portal' => 'Portal Klienta', + 'enable_client_portal_help' => 'Pokaż/ukryj portal klienta.', + 'enable_client_portal_dashboard' => 'Pulpit', + 'enable_client_portal_dashboard_help' => 'Pokaż/ukryj pulpit w panelu klienta.', + + // Plans + 'account_management' => 'Zarządzanie kontem', + 'plan_status' => 'Plan Status', + + 'plan_upgrade' => 'Aktualizuj', + 'plan_change' => 'Zmień plan', + 'pending_change_to' => 'Zmienia się na', + 'plan_changes_to' => ':plan on :date', + 'plan_term_changes_to' => ':plan (:term) on :date', + 'cancel_plan_change' => 'Anuluj zmianę', + 'plan' => 'Plan', + 'expires' => 'Wygasa', + 'renews' => 'Odnawia', + 'plan_expired' => ':plan Plan Expired', + 'trial_expired' => ':plan Plan Trial Ended', + 'never' => 'Nigdy', + 'plan_free' => 'Darmowy', + 'plan_pro' => 'Pro', + 'plan_enterprise' => 'Enterprise', + 'plan_white_label' => 'Self Hosted (White labeled)', + 'plan_free_self_hosted' => 'Self Hosted (Free)', + 'plan_trial' => 'Trial', + 'plan_term' => 'Term', + 'plan_term_monthly' => 'Miesięcznie', + 'plan_term_yearly' => 'Rocznie', + 'plan_term_month' => 'Miesiąc', + 'plan_term_year' => 'Rok', + 'plan_price_monthly' => '$:price/miesiąc', + 'plan_price_yearly' => '$:price/rok', + 'updated_plan' => 'Ustawienia planu zaktualizowane', + 'plan_paid' => 'Termin rozpoczął', + 'plan_started' => 'Plan rozpoczął', + 'plan_expires' => 'Plan Wygasa', + + 'white_label_button' => 'Biała etykieta', + + 'pro_plan_year_description' => 'One year enrollment in the Invoice Ninja Pro Plan.', + 'pro_plan_month_description' => 'One month enrollment in the Invoice Ninja Pro Plan.', + 'enterprise_plan_product' => 'Plan Enterprise', + 'enterprise_plan_year_description' => 'One year enrollment in the Invoice Ninja Enterprise Plan.', + 'enterprise_plan_month_description' => 'One month enrollment in the Invoice Ninja Enterprise Plan.', + 'plan_credit_product' => 'Kredyt', + 'plan_credit_description' => 'Kredyt za niewykorzystany czas', + 'plan_pending_monthly' => 'Will switch to monthly on :date', + 'plan_refunded' => 'Zwrot został wystawiony.', + + 'live_preview' => 'Podgląd', + 'page_size' => 'Rozmiar strony', + 'live_preview_disabled' => 'Podgląd obrazu na żywo został wyłączony w celu wsparcia wybranej czcionki', + 'invoice_number_padding' => 'Padding', + +); + +return $LANG; + +?>. \ No newline at end of file diff --git a/resources/lang/pl/validation.php b/resources/lang/pl/validation.php new file mode 100644 index 000000000000..d3ffdb6a8155 --- /dev/null +++ b/resources/lang/pl/validation.php @@ -0,0 +1,106 @@ + ":attribute musi być zaakceptowany.", + "active_url" => ":attribute nie jest poprawnym URL-em.", + "after" => ":attribute musi być datą za :date.", + "alpha" => ":attribute może zawierać tylko litery.", + "alpha_dash" => ":attribute może zawierać tylko litery, liczby i myślniki.", + "alpha_num" => ":attribute może zawierać tylko litery i liczby.", + "array" => ":attribute musi być tablicą.", + "before" => ":attribute musi być datą przed :date.", + "between" => array( + "numeric" => ":attribute musi być pomiędzy :min - :max.", + "file" => ":attribute musi mieć rozmiar pomiędzy :min - :max kilobajtów.", + "string" => ":attribute musi mieć pomiędzy :min - :max znaków.", + "array" => ":attribute musi zawierać :min - :max pozycji.", + ), + "confirmed" => ":attribute potwierdzenie nie jest zgodne.", + "date" => ":attribute nie jest prawidłową datą.", + "date_format" => ":attribute nie jest zgodne z formatem :format.", + "different" => ":attribute i :other muszą być różne.", + "digits" => ":attribute musi mieć :digits cyfr.", + "digits_between" => ":attribute musi być w przedziale od :min do :max cyfr.", + "email" => ":attribute format jest nieprawidłowy.", + "exists" => "Zaznaczony :attribute jest niepoprawny.", + "image" => ":attribute musi być zdjęciem.", + "in" => "Zaznaczony :attribute jest niepoprawny.", + "integer" => ":attribute musi być liczbą całkowitą.", + "ip" => ":attribute musi być poprawnym adresem IP.", + "max" => array( + "numeric" => ":attribute nie może być większy niż :max.", + "file" => ":attribute nie może być większy niż :max kilobajtów.", + "string" => ":attribute nie może być dłuższy niż :max znaków.", + "array" => ":attribute nie może zawierać więcej niż :max pozycji.", + ), + "mimes" => ":attribute musi być plikiem o typie: :values.", + "min" => array( + "numeric" => ":attribute musi być przynajmniej :min.", + "file" => ":attribute musi mieć przynajmniej :min kilobajtów.", + "string" => ":attribute musi mieć przynajmniej :min znaków.", + "array" => ":attribute musi zawierać przynajmniej :min pozycji.", + ), + "not_in" => "Zaznaczony :attribute jest niepoprawny.", + "numeric" => ":attribute musi być cyfrą.", + "regex" => ":attribute format jest niepoprawny.", + "required" => ":attribute pole jest wymagane.", + "required_if" => ":attribute pole jest wymagane jeśli :other ma :value.", + "required_with" => ":attribute pole jest wymagane kiedy :values jest obecne.", + "required_without" => ":attribute pole jest wymagane kiedy :values nie występuje.", + "same" => ":attribute i :other muszą być takie same.", + "size" => array( + "numeric" => ":attribute musi mieć :size.", + "file" => ":attribute musi mieć :size kilobajtów.", + "string" => ":attribute musi mieć :size znaków.", + "array" => ":attribute musi zawierać :size pozycji.", + ), + "unique" => ":attribute już istnieje.", + "url" => ":attribute format jest nieprawidłowy.", + + "positive" => ":attribute musi być większe niż zero.", + "has_credit" => "Klient ma niewystarczająco kredytu.", + "notmasked" => "Wartości są maskowane", + "less_than" => ":attribute musi być mniejsze od :value", + "has_counter" => "Wartość musi zawierać {\$counter}", + "valid_contacts" => "Kontakt musi posiadać e-mail lub nazwę", + "valid_invoice_items" => "Faktura przekracza maksymalną kwotę", + + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute.rule" to name the lines. This makes it quick to + | specify a specific custom language line for a given attribute rule. + | + */ + + 'custom' => array(), + + /* + |-------------------------------------------------------------------------- + | Custom Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap attribute place-holders + | with something more reader friendly such as E-Mail Address instead + | of "email". This simply helps us make messages a little cleaner. + | + */ + + 'attributes' => array(), + +); \ No newline at end of file From fb473eeb3b35af80d253af98ded4c82250049787 Mon Sep 17 00:00:00 2001 From: emiliolodigiani Date: Tue, 3 May 2016 15:09:13 +0200 Subject: [PATCH 04/16] Update italian translation --- resources/lang/it/texts.php | 140 ++++++++++++++++++------------------ 1 file changed, 70 insertions(+), 70 deletions(-) diff --git a/resources/lang/it/texts.php b/resources/lang/it/texts.php index 17d77d5d4881..b4fb1dc2b00d 100644 --- a/resources/lang/it/texts.php +++ b/resources/lang/it/texts.php @@ -382,11 +382,11 @@ return array( 'converted_to_invoice' => 'Il preventivo è stato convertito a fattura con successo', 'quote_subject' => 'Nuovo preventivo da :account', - 'quote_message' => 'Per visualizzare il vostro preventivo per :amount, cliccare il collegamento sotto.', - 'quote_link_message' => 'Per visualizzare il preventivo del vostro cliante cliccate il collegamento sotto:', + 'quote_message' => 'Per visualizzare il vostro preventivo di :amount, cliccate il collegamento sotto.', + 'quote_link_message' => 'Per visualizzare il preventivo del vostro cliente cliccate il collegamento sotto:', 'notification_quote_sent_subject' => 'Il preventivo :invoice è stato inviato a :client', 'notification_quote_viewed_subject' => 'Il preventivo :invoice è stato visualizzato da :client', - 'notification_quote_sent' => 'Al seguente cliente :client è stata inviata la fattura :invoice per :amount.', + 'notification_quote_sent' => 'Al seguente cliente :client è stata inviato il preventivo :invoice per un importo di :amount.', 'notification_quote_viewed' => 'Il seguente cliente :client ha visualizzato il preventivo :invoice di :amount.', 'session_expired' => 'La vostra sessione è scaduta.', @@ -489,7 +489,7 @@ return array( 'invoice_history' => 'Invoice History', 'quote_history' => 'Quote History', 'current_version' => 'Current version', - 'select_version' => 'Select version', + 'select_versiony' => 'Select version', 'view_history' => 'View History', 'edit_payment' => 'Edit Payment', @@ -728,12 +728,12 @@ return array( 'header' => 'Header', 'footer' => 'Footer', 'custom' => 'Custom', - 'invoice_to' => 'Invoice to', - 'invoice_no' => 'Invoice No.', - 'recent_payments' => 'Recent Payments', - 'outstanding' => 'Outstanding', - 'manage_companies' => 'Manage Companies', - 'total_revenue' => 'Total Revenue', + 'invoice_to' => 'Fattura a', + 'invoice_no' => 'Fattura N.', + 'recent_payments' => 'Pagamenti recenti', + 'outstanding' => 'Inevaso', + 'manage_companies' => 'Gestisci aziende', + 'total_revenue' => 'Ricavo totale', 'current_user' => 'Current User', 'new_recurring_invoice' => 'Nuova Fattura Ricorrente', @@ -784,7 +784,7 @@ return array( 'last_sent_on' => 'Last sent on :date', 'page_expire' => 'This page will expire soon, :click_here to keep working', - 'upcoming_quotes' => 'Upcoming Quotes', + 'upcoming_quotes' => 'Preventivi in scadenza', 'expired_quotes' => 'Preventivi Scaduti', 'sign_up_using' => 'Sign up using', @@ -842,19 +842,19 @@ return array( 'quote_counter' => 'Quote Counter', 'type' => 'Type', - 'activity_1' => ':user created client :client', - 'activity_2' => ':user archived client :client', + 'activity_1' => ':user ha creato il cliente :client', + 'activity_2' => ':user ha archiviato il cliente :client', 'activity_3' => ':user deleted client :client', 'activity_4' => ':user ha creato la fattura :invoice', 'activity_5' => ':user ha aggiornato la fattura :invoice', - 'activity_6' => ':user emailed invoice :invoice to :contact', - 'activity_7' => ':contact viewed invoice :invoice', - 'activity_8' => ':user archived invoice :invoice', - 'activity_9' => ':user deleted invoice :invoice', - 'activity_10' => ':contact entered payment :payment for :invoice', - 'activity_11' => ':user updated payment :payment', - 'activity_12' => ':user archived payment :payment', - 'activity_13' => ':user deleted payment :payment', + 'activity_6' => ':user ha inviato per email la fattura :invoice a :contact', + 'activity_7' => ':contact ha visto la fattura :invoice', + 'activity_8' => ':user ha archiviato la fattura :invoice', + 'activity_9' => ':user ha cancellato la fattura :invoice', + 'activity_10' => ':contact ha inserito il pagamento :payment per :invoice', + 'activity_11' => ':user ha aggiornato il pagamento :payment', + 'activity_12' => ':user ha archiviato il pagamento :payment', + 'activity_13' => ':user ha cancellato il pagamento :payment', 'activity_14' => ':user entered :credit credit', 'activity_15' => ':user updated :credit credit', 'activity_16' => ':user archived :credit credit', @@ -862,7 +862,7 @@ return array( 'activity_18' => ':user created quote :quote', 'activity_19' => ':user updated quote :quote', 'activity_20' => ':user emailed quote :quote to :contact', - 'activity_21' => ':contact viewed quote :quote', + 'activity_21' => ':contact ha visto il preventivo :quote', 'activity_22' => ':user archived quote :quote', 'activity_23' => ':user deleted quote :quote', 'activity_24' => ':user restored quote :quote', @@ -870,7 +870,7 @@ return array( 'activity_26' => ':user restored client :client', 'activity_27' => ':user restored payment :payment', 'activity_28' => ':user restored :credit credit', - 'activity_29' => ':contact approved quote :quote', + 'activity_29' => ':contact ha approvato la fattura :quote', 'payment' => 'Payment', 'system' => 'System', @@ -1004,33 +1004,33 @@ return array( 'archived_expenses' => 'Successfully archived expenses', // Expenses - 'expense_amount' => 'Expense Amount', - 'expense_balance' => 'Expense Balance', - 'expense_date' => 'Expense Date', - 'expense_should_be_invoiced' => 'Should this expense be invoiced?', - 'public_notes' => 'Public Notes', - 'invoice_amount' => 'Invoice Amount', - 'exchange_rate' => 'Exchange Rate', - 'yes' => 'Yes', + 'expense_amount' => 'Importo Spesa', + 'expense_balance' => 'Bilancio Spesa', + 'expense_date' => 'Data Spesa', + 'expense_should_be_invoiced' => 'Questa spesa deve essere fatturata?', + 'public_notes' => 'Note Pubbliche (Descrizione in fattura)', + 'invoice_amount' => 'Importo Fattura', + 'exchange_rate' => 'Tasso di Cambio', + 'yes' => 'Si', 'no' => 'No', - 'should_be_invoiced' => 'Should be invoiced', - 'view_expense' => 'View expense # :expense', - 'edit_expense' => 'Edit Expense', - 'archive_expense' => 'Archive Expense', - 'delete_expense' => 'Delete Expense', - 'view_expense_num' => 'Expense # :expense', - 'updated_expense' => 'Successfully updated expense', - 'created_expense' => 'Successfully created expense', - 'enter_expense' => 'Enter Expense', - 'view' => 'View', - 'restore_expense' => 'Restore Expense', - 'invoice_expense' => 'Invoice Expense', - 'expense_error_multiple_clients' =>'The expenses can\'t belong to different clients', - 'expense_error_invoiced' => 'Expense has already been invoiced', - 'convert_currency' => 'Convert currency', + 'should_be_invoiced' => 'Deve essere fatturata', + 'view_expense' => 'Vedi spesa # :expense', + 'edit_expense' => 'Modifica Spesa', + 'archive_expense' => 'Archivia Spesa', + 'delete_expense' => 'Cancella Spesa', + 'view_expense_num' => 'Spesa # :expense', + 'updated_expense' => 'Spesa aggiornata con successo', + 'created_expense' => 'Spesa creata con successo', + 'enter_expense' => 'Inserisci Spesa', + 'view' => 'Vedi', + 'restore_expense' => 'Ripristina Spesa', + 'invoice_expense' => 'Fattura Spesa', + 'expense_error_multiple_clients' =>'Le spese non possono appartenere a clienti differenti', + 'expense_error_invoiced' => 'La spesa è stata già fatturata', + 'convert_currency' => 'Converti valuta', // Payment terms - 'num_days' => 'Number of days', + 'num_days' => 'Numero di giorni', 'create_payment_term' => 'Create Payment Term', 'edit_payment_terms' => 'Edit Payment Term', 'edit_payment_term' => 'Edit Payment Term', @@ -1053,17 +1053,17 @@ return array( ', 'due' => 'Due', 'next_due_on' => 'Due Next: :date', - 'use_client_terms' => 'Use client terms', - 'day_of_month' => ':ordinal day of month', - 'last_day_of_month' => 'Last day of month', - 'day_of_week_after' => ':ordinal :day after', - 'sunday' => 'Sunday', - 'monday' => 'Monday', - 'tuesday' => 'Tuesday', - 'wednesday' => 'Wednesday', - 'thursday' => 'Thursday', - 'friday' => 'Friday', - 'saturday' => 'Saturday', + 'use_client_terms' => 'Usa i termini del cliente', + 'day_of_month' => ':ordinal giorno del mese', + 'last_day_of_month' => 'L\'ultimo giorno del mese', + 'day_of_week_after' => ':ordinal :day dopo', + 'sunday' => 'Domenica', + 'monday' => 'Lunedì', + 'tuesday' => 'Martedì', + 'wednesday' => 'Mercoledì', + 'thursday' => 'Giovedì', + 'friday' => 'Venerdì', + 'saturday' => 'Sabato', // Fonts 'header_font_id' => 'Header Font', @@ -1182,17 +1182,17 @@ return array( 'edit_all_help' => 'Allow user to modify records they didn\'t create', 'view_payment' => 'View Payment', - 'january' => 'January', - 'february' => 'February', - 'march' => 'March', - 'april' => 'April', - 'may' => 'May', - 'june' => 'June', - 'july' => 'July', - 'august' => 'August', - 'september' => 'September', - 'october' => 'October', - 'november' => 'November', - 'december' => 'December', + 'january' => 'Gennaio', + 'february' => 'Febbraio', + 'march' => 'Marzo', + 'april' => 'Aprile', + 'may' => 'Maggio', + 'june' => 'Giugno', + 'july' => 'Luglio', + 'august' => 'Agosto', + 'september' => 'Settembre', + 'october' => 'Ottobre', + 'november' => 'Novembre', + 'december' => 'Dicembre', ); From 5295bf30fc56d3f31149bc3b40b0098b4cfbed98 Mon Sep 17 00:00:00 2001 From: emiliolodigiani Date: Tue, 3 May 2016 15:11:34 +0200 Subject: [PATCH 05/16] Revert typo fix --- resources/lang/it/texts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/lang/it/texts.php b/resources/lang/it/texts.php index b4fb1dc2b00d..526ce14013ba 100644 --- a/resources/lang/it/texts.php +++ b/resources/lang/it/texts.php @@ -489,7 +489,7 @@ return array( 'invoice_history' => 'Invoice History', 'quote_history' => 'Quote History', 'current_version' => 'Current version', - 'select_versiony' => 'Select version', + 'select_version' => 'Select version', 'view_history' => 'View History', 'edit_payment' => 'Edit Payment', From c0a5084282e039f7375d27bb5464b9734c1cb34d Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Tue, 3 May 2016 19:06:38 +0300 Subject: [PATCH 06/16] Added details to cybersource error --- app/Http/Controllers/PaymentController.php | 3 ++- app/Ninja/Transformers/AccountTransformer.php | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/Http/Controllers/PaymentController.php b/app/Http/Controllers/PaymentController.php index 12537dbebaa1..165f54ef9ed0 100644 --- a/app/Http/Controllers/PaymentController.php +++ b/app/Http/Controllers/PaymentController.php @@ -551,7 +551,8 @@ class PaymentController extends BaseController $payment = $this->paymentService->createPayment($invitation, $accountGateway, $token, $payerId); Session::flash('message', trans('texts.applied_payment')); } else { - Session::flash('error', Input::get('message')); + $message = Input::get('message') . ': ' . Input::get('invalid_fields'); + Session::flash('error', $message); } return Redirect::to($invitation->getLink()); } elseif (method_exists($gateway, 'completePurchase') diff --git a/app/Ninja/Transformers/AccountTransformer.php b/app/Ninja/Transformers/AccountTransformer.php index 6a1c32f30e09..f56635bad2b1 100644 --- a/app/Ninja/Transformers/AccountTransformer.php +++ b/app/Ninja/Transformers/AccountTransformer.php @@ -14,12 +14,12 @@ class AccountTransformer extends EntityTransformer 'users', 'products', 'taxRates', - 'payments' ]; protected $availableIncludes = [ 'clients', 'invoices', + 'payments', ]; public function includeUsers(Account $account) From 5218568c918900bc3010745a69c4af47df9824a5 Mon Sep 17 00:00:00 2001 From: Bartlomiej Szala Date: Tue, 3 May 2016 18:40:21 +0200 Subject: [PATCH 07/16] Remove transaction migration --- ...16_05_02_071859_add_polish_translation.php | 29 ------------------- 1 file changed, 29 deletions(-) delete mode 100644 database/migrations/2016_05_02_071859_add_polish_translation.php diff --git a/database/migrations/2016_05_02_071859_add_polish_translation.php b/database/migrations/2016_05_02_071859_add_polish_translation.php deleted file mode 100644 index b78969cfbbde..000000000000 --- a/database/migrations/2016_05_02_071859_add_polish_translation.php +++ /dev/null @@ -1,29 +0,0 @@ -insert(['name' => 'Polish', 'locale' => self::LANGUAGE_LOCALE]); - } - - /** - * Reverse the migrations. - * - * @return void - */ - public function down() - { - $language = \App\Models\Language::whereLocale(self::LANGUAGE_LOCALE)->first(); - $language->delete(); - } -} From 2d878b6480f674bc99f5d80bb91e9d79ff796347 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Tue, 3 May 2016 23:02:29 +0300 Subject: [PATCH 08/16] API optimizations --- app/Http/Controllers/BaseAPIController.php | 9 +-------- app/Http/Controllers/PaymentApiController.php | 2 +- app/Models/InvoiceItem.php | 5 +++++ app/Models/Product.php | 5 +++++ app/Models/TaxRate.php | 5 +++++ app/Ninja/Transformers/ClientTransformer.php | 6 ++---- app/Ninja/Transformers/ContactTransformer.php | 5 ++--- app/Ninja/Transformers/CreditTransformer.php | 5 ++--- app/Ninja/Transformers/DocumentTransformer.php | 6 ++---- app/Ninja/Transformers/EntityTransformer.php | 15 +++++++++++++++ app/Ninja/Transformers/ExpenseTransformer.php | 5 ++--- app/Ninja/Transformers/InvoiceItemTransformer.php | 6 ++---- app/Ninja/Transformers/InvoiceTransformer.php | 6 ++---- app/Ninja/Transformers/PaymentTransformer.php | 6 ++---- app/Ninja/Transformers/ProductTransformer.php | 5 ++--- app/Ninja/Transformers/TaskTransformer.php | 6 ++---- app/Ninja/Transformers/TaxRateTransformer.php | 5 ++--- .../Transformers/VendorContactTransformer.php | 5 ++--- app/Ninja/Transformers/VendorTransformer.php | 6 ++---- 19 files changed, 58 insertions(+), 55 deletions(-) diff --git a/app/Http/Controllers/BaseAPIController.php b/app/Http/Controllers/BaseAPIController.php index db99a3beaf1d..8e48f3bff878 100644 --- a/app/Http/Controllers/BaseAPIController.php +++ b/app/Http/Controllers/BaseAPIController.php @@ -193,26 +193,19 @@ class BaseAPIController extends Controller protected function getRequestIncludes($data) { - $data[] = 'user'; - $included = Request::get('include'); $included = explode(',', $included); foreach ($included as $include) { if ($include == 'invoices') { $data[] = 'invoices.invoice_items'; - $data[] = 'invoices.user'; } elseif ($include == 'client') { $data[] = 'client.contacts'; - $data[] = 'client.user'; } elseif ($include == 'clients') { $data[] = 'clients.contacts'; - $data[] = 'clients.user'; } elseif ($include == 'vendors') { $data[] = 'vendors.vendorcontacts'; - $data[] = 'vendors.user'; - } - elseif ($include) { + } elseif ($include) { $data[] = $include; } } diff --git a/app/Http/Controllers/PaymentApiController.php b/app/Http/Controllers/PaymentApiController.php index 0dd8de50803b..3355b6bff8f4 100644 --- a/app/Http/Controllers/PaymentApiController.php +++ b/app/Http/Controllers/PaymentApiController.php @@ -49,7 +49,7 @@ class PaymentApiController extends BaseAPIController { $payments = Payment::scope() ->withTrashed() - ->with(['invoice']) + ->with(['invoice']) ->orderBy('created_at', 'desc'); return $this->listResponse($payments); diff --git a/app/Models/InvoiceItem.php b/app/Models/InvoiceItem.php index d3981c931c62..e80482bafdb8 100644 --- a/app/Models/InvoiceItem.php +++ b/app/Models/InvoiceItem.php @@ -19,6 +19,11 @@ class InvoiceItem extends EntityModel return $this->belongsTo('App\Models\Invoice'); } + public function user() + { + return $this->belongsTo('App\Models\User')->withTrashed(); + } + public function product() { return $this->belongsTo('App\Models\Product'); diff --git a/app/Models/Product.php b/app/Models/Product.php index 0d3221f2a1ea..05944c9fff94 100644 --- a/app/Models/Product.php +++ b/app/Models/Product.php @@ -26,6 +26,11 @@ class Product extends EntityModel return Product::scope()->where('product_key', '=', $key)->first(); } + public function user() + { + return $this->belongsTo('App\Models\User')->withTrashed(); + } + public function default_tax_rate() { return $this->belongsTo('App\Models\TaxRate'); diff --git a/app/Models/TaxRate.php b/app/Models/TaxRate.php index 72ad266b07d8..384ccf933b36 100644 --- a/app/Models/TaxRate.php +++ b/app/Models/TaxRate.php @@ -17,4 +17,9 @@ class TaxRate extends EntityModel { return ENTITY_TAX_RATE; } + + public function user() + { + return $this->belongsTo('App\Models\User')->withTrashed(); + } } diff --git a/app/Ninja/Transformers/ClientTransformer.php b/app/Ninja/Transformers/ClientTransformer.php index e9a63e07d693..63f0baa0c871 100644 --- a/app/Ninja/Transformers/ClientTransformer.php +++ b/app/Ninja/Transformers/ClientTransformer.php @@ -77,13 +77,11 @@ class ClientTransformer extends EntityTransformer public function transform(Client $client) { - return [ + return array_merge($this->getDefaults($client), [ 'id' => (int) $client->public_id, 'name' => $client->name, 'balance' => (float) $client->balance, 'paid_to_date' => (float) $client->paid_to_date, - 'user_id' => (int) $client->user->public_id + 1, - 'account_key' => $this->account->account_key, 'updated_at' => $this->getTimestamp($client->updated_at), 'archived_at' => $this->getTimestamp($client->deleted_at), 'address1' => $client->address1, @@ -106,6 +104,6 @@ class ClientTransformer extends EntityTransformer 'currency_id' => (int) $client->currency_id, 'custom_value1' => $client->custom_value1, 'custom_value2' => $client->custom_value2, - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/ContactTransformer.php b/app/Ninja/Transformers/ContactTransformer.php index e404b73660d4..68172e156c60 100644 --- a/app/Ninja/Transformers/ContactTransformer.php +++ b/app/Ninja/Transformers/ContactTransformer.php @@ -8,7 +8,7 @@ class ContactTransformer extends EntityTransformer { public function transform(Contact $contact) { - return [ + return array_merge($this->getDefaults($contact), [ 'id' => (int) $contact->public_id, 'first_name' => $contact->first_name, 'last_name' => $contact->last_name, @@ -18,8 +18,7 @@ class ContactTransformer extends EntityTransformer 'is_primary' => (bool) $contact->is_primary, 'phone' => $contact->phone, 'last_login' => $contact->last_login, - 'account_key' => $this->account->account_key, 'send_invoice' => (bool) $contact->send_invoice, - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/CreditTransformer.php b/app/Ninja/Transformers/CreditTransformer.php index a33185d2ff39..39ce5ff1d8f3 100644 --- a/app/Ninja/Transformers/CreditTransformer.php +++ b/app/Ninja/Transformers/CreditTransformer.php @@ -8,17 +8,16 @@ class CreditTransformer extends EntityTransformer { public function transform(Credit $credit) { - return [ + return array_merge($this->getDefaults($credit), [ 'id' => (int) $credit->public_id, 'amount' => (float) $credit->amount, 'balance' => (float) $credit->balance, 'updated_at' => $this->getTimestamp($credit->updated_at), 'archived_at' => $this->getTimestamp($credit->deleted_at), 'is_deleted' => (bool) $credit->is_deleted, - 'account_key' => $this->account->account_key, 'credit_date' => $credit->credit_date, 'credit_number' => $credit->credit_number, 'private_notes' => $credit->private_notes, - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/DocumentTransformer.php b/app/Ninja/Transformers/DocumentTransformer.php index 61d18506eba1..4cbfa0619193 100644 --- a/app/Ninja/Transformers/DocumentTransformer.php +++ b/app/Ninja/Transformers/DocumentTransformer.php @@ -8,14 +8,12 @@ class DocumentTransformer extends EntityTransformer { public function transform(Document $document) { - - return [ + return array_merge($this->getDefaults($document), [ 'id' => (int) $document->public_id, 'name' => $document->name, - 'account_key' => $this->account->account_key, 'type' => $document->type, 'invoice_id' => isset($document->invoice->public_id) ? (int) $document->invoice->public_id : null, 'expense_id' => isset($document->expense->public_id) ? (int) $document->expense->public_id : null, - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/EntityTransformer.php b/app/Ninja/Transformers/EntityTransformer.php index af1304acd67f..d2d02bd0b6ee 100644 --- a/app/Ninja/Transformers/EntityTransformer.php +++ b/app/Ninja/Transformers/EntityTransformer.php @@ -1,5 +1,6 @@ defaultIncludes; } + + protected function getDefaults($entity) + { + $data = [ + 'account_key' => $this->account->account_key, + 'is_owner' => (bool) Auth::user()->owns($entity), + ]; + + if ($entity->relationLoaded('user')) { + $data['user_id'] = (int) $entity->user->public_id + 1; + } + + return $data; + } } diff --git a/app/Ninja/Transformers/ExpenseTransformer.php b/app/Ninja/Transformers/ExpenseTransformer.php index 8f2e02c0a88f..46c334cb3e55 100644 --- a/app/Ninja/Transformers/ExpenseTransformer.php +++ b/app/Ninja/Transformers/ExpenseTransformer.php @@ -15,7 +15,7 @@ class ExpenseTransformer extends EntityTransformer public function transform(Expense $expense) { - return [ + return array_merge($this->getDefaults($expense), [ 'id' => (int) $expense->public_id, 'private_notes' => $expense->private_notes, 'public_notes' => $expense->public_notes, @@ -25,7 +25,6 @@ class ExpenseTransformer extends EntityTransformer 'transaction_id' => $expense->transaction_id, 'bank_id' => $expense->bank_id, 'expense_currency_id' => (int) $expense->expense_currency_id, - 'account_key' => $this->account->account_key, 'amount' => (float) $expense->amount, 'expense_date' => $expense->expense_date, 'exchange_rate' => (float) $expense->exchange_rate, @@ -34,6 +33,6 @@ class ExpenseTransformer extends EntityTransformer 'client_id' => $this->client ? $this->client->public_id : (isset($expense->client->public_id) ? (int) $expense->client->public_id : null), 'invoice_id' => isset($expense->invoice->public_id) ? (int) $expense->invoice->public_id : null, 'vendor_id' => isset($expense->vendor->public_id) ? (int) $expense->vendor->public_id : null, - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/InvoiceItemTransformer.php b/app/Ninja/Transformers/InvoiceItemTransformer.php index 895d8e8d2f4a..080234f35e1b 100644 --- a/app/Ninja/Transformers/InvoiceItemTransformer.php +++ b/app/Ninja/Transformers/InvoiceItemTransformer.php @@ -8,11 +8,9 @@ class InvoiceItemTransformer extends EntityTransformer { public function transform(InvoiceItem $item) { - return [ + return array_merge($this->getDefaults($item), [ 'id' => (int) $item->public_id, 'product_key' => $item->product_key, - 'account_key' => $this->account->account_key, - 'user_id' => (int) $item->user_id, 'updated_at' => $this->getTimestamp($item->updated_at), 'archived_at' => $this->getTimestamp($item->deleted_at), 'product_key' => $item->product_key, @@ -23,6 +21,6 @@ class InvoiceItemTransformer extends EntityTransformer 'tax_rate1' => (float) $item->tax_rate1, 'tax_name2' => $item->tax_name2 ? $item->tax_name1 : '', 'tax_rate2' => (float) $item->tax_rate2, - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/InvoiceTransformer.php b/app/Ninja/Transformers/InvoiceTransformer.php index 51af3d029936..0933422875c2 100644 --- a/app/Ninja/Transformers/InvoiceTransformer.php +++ b/app/Ninja/Transformers/InvoiceTransformer.php @@ -71,7 +71,7 @@ class InvoiceTransformer extends EntityTransformer public function transform(Invoice $invoice) { - return [ + return array_merge($this->getDefaults($invoice), [ 'id' => (int) $invoice->public_id, 'amount' => (float) $invoice->amount, 'balance' => (float) $invoice->balance, @@ -105,8 +105,6 @@ class InvoiceTransformer extends EntityTransformer 'partial' => (float) $invoice->partial, 'has_tasks' => (bool) $invoice->has_tasks, 'auto_bill' => (bool) $invoice->auto_bill, - 'account_key' => $this->account->account_key, - 'user_id' => (int) $invoice->user->public_id + 1, 'custom_value1' => (float) $invoice->custom_value1, 'custom_value2' => (float) $invoice->custom_value2, 'custom_taxes1' => (bool) $invoice->custom_taxes1, @@ -115,6 +113,6 @@ class InvoiceTransformer extends EntityTransformer 'quote_invoice_id' => (int) $invoice->quote_invoice_id, 'custom_text_value1' => $invoice->custom_text_value1, 'custom_text_value2' => $invoice->custom_text_value2, - ]; + ]); } } diff --git a/app/Ninja/Transformers/PaymentTransformer.php b/app/Ninja/Transformers/PaymentTransformer.php index 8ea2dcbae051..c4e4328cb845 100644 --- a/app/Ninja/Transformers/PaymentTransformer.php +++ b/app/Ninja/Transformers/PaymentTransformer.php @@ -47,11 +47,9 @@ class PaymentTransformer extends EntityTransformer public function transform(Payment $payment) { - return [ + return array_merge($this->getDefaults($payment), [ 'id' => (int) $payment->public_id, 'amount' => (float) $payment->amount, - 'account_key' => $this->account->account_key, - 'user_id' => (int) $payment->user->public_id + 1, 'transaction_reference' => $payment->transaction_reference, 'payment_date' => $payment->payment_date, 'updated_at' => $this->getTimestamp($payment->updated_at), @@ -59,6 +57,6 @@ class PaymentTransformer extends EntityTransformer 'is_deleted' => (bool) $payment->is_deleted, 'payment_type_id' => (int) $payment->payment_type_id, 'invoice_id' => (int) ($this->invoice ? $this->invoice->public_id : $payment->invoice->public_id), - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/ProductTransformer.php b/app/Ninja/Transformers/ProductTransformer.php index 34fbcf7f18ff..8331d7666154 100644 --- a/app/Ninja/Transformers/ProductTransformer.php +++ b/app/Ninja/Transformers/ProductTransformer.php @@ -7,16 +7,15 @@ class ProductTransformer extends EntityTransformer { public function transform(Product $product) { - return [ + return array_merge($this->getDefaults(), [ 'id' => (int) $product->public_id, 'product_key' => $product->product_key, 'notes' => $product->notes, 'cost' => $product->cost, 'qty' => $product->qty, - 'account_key' =>$this->account->account_key, 'default_tax_rate_id' =>$product->default_tax_rate_id, 'updated_at' =>$this->getTimestamp($product->updated_at), 'archived_at' => $this->getTimestamp($product->deleted_at), - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/TaskTransformer.php b/app/Ninja/Transformers/TaskTransformer.php index 908a8118aaea..7bfc474a72f2 100644 --- a/app/Ninja/Transformers/TaskTransformer.php +++ b/app/Ninja/Transformers/TaskTransformer.php @@ -39,12 +39,10 @@ class TaskTransformer extends EntityTransformer public function transform(Task $task) { - return [ + return array_merge($this->getDefaults($task), [ 'id' => (int) $task->public_id, - 'account_key' => $this->account->account_key, - 'user_id' => (int) $task->user->public_id + 1, 'description' => $task->description, 'duration' => $task->getDuration() - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/TaxRateTransformer.php b/app/Ninja/Transformers/TaxRateTransformer.php index f7d307bf7bb4..a0c5aab539a0 100644 --- a/app/Ninja/Transformers/TaxRateTransformer.php +++ b/app/Ninja/Transformers/TaxRateTransformer.php @@ -21,13 +21,12 @@ class TaxRateTransformer extends EntityTransformer public function transform(TaxRate $taxRate) { - return [ + return array_merge($this->getDefaults($taxRate), [ 'id' => (int) $taxRate->public_id, 'name' => $taxRate->name, 'rate' => (float) $taxRate->rate, 'updated_at' => $this->getTimestamp($taxRate->updated_at), 'archived_at' => $this->getTimestamp($taxRate->deleted_at), - 'account_key' => $this->account->account_key, - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/VendorContactTransformer.php b/app/Ninja/Transformers/VendorContactTransformer.php index 3b75aee53a28..f277964cec28 100644 --- a/app/Ninja/Transformers/VendorContactTransformer.php +++ b/app/Ninja/Transformers/VendorContactTransformer.php @@ -8,7 +8,7 @@ class VendorContactTransformer extends EntityTransformer { public function transform(VendorContact $contact) { - return [ + return array_merge($this->getDefaults($contact), [ 'id' => (int) $contact->public_id, 'first_name' => $contact->first_name, 'last_name' => $contact->last_name, @@ -17,7 +17,6 @@ class VendorContactTransformer extends EntityTransformer 'archived_at' => $this->getTimestamp($contact->deleted_at), 'is_primary' => (bool) $contact->is_primary, 'phone' => $contact->phone, - 'account_key' => $this->account->account_key, - ]; + ]); } } \ No newline at end of file diff --git a/app/Ninja/Transformers/VendorTransformer.php b/app/Ninja/Transformers/VendorTransformer.php index f0b8fd0415f0..f9c37ac44200 100644 --- a/app/Ninja/Transformers/VendorTransformer.php +++ b/app/Ninja/Transformers/VendorTransformer.php @@ -61,13 +61,11 @@ class VendorTransformer extends EntityTransformer public function transform(Vendor $vendor) { - return [ + return array_merge($this->getDefaults($vendor), [ 'id' => (int) $vendor->public_id, 'name' => $vendor->name, 'balance' => (float) $vendor->balance, 'paid_to_date' => (float) $vendor->paid_to_date, - 'user_id' => (int) $vendor->user->public_id + 1, - 'account_key' => $this->account->account_key, 'updated_at' => $this->getTimestamp($vendor->updated_at), 'archived_at' => $this->getTimestamp($vendor->deleted_at), 'address1' => $vendor->address1, @@ -84,6 +82,6 @@ class VendorTransformer extends EntityTransformer 'vat_number' => $vendor->vat_number, 'id_number' => $vendor->id_number, 'currency_id' => (int) $vendor->currency_id - ]; + ]); } } \ No newline at end of file From dfa6c518abb8529e8f55b38e5ef0f42e80b4a4a9 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Tue, 3 May 2016 23:15:41 +0300 Subject: [PATCH 09/16] Fix for travis test --- tests/acceptance/ExpenseCest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/acceptance/ExpenseCest.php b/tests/acceptance/ExpenseCest.php index e22bebac3b7f..770125574d9e 100644 --- a/tests/acceptance/ExpenseCest.php +++ b/tests/acceptance/ExpenseCest.php @@ -44,13 +44,14 @@ class ExpenseCest $I->selectDropdown($I, $vendorName, '.vendor-select .dropdown-toggle'); $I->selectDropdown($I, $clientEmail, '.client-select .dropdown-toggle'); $I->click('Save'); + $I->wait(2); $I->seeInDatabase('expenses', ['vendor_id' => $vendorId]); // invoice expense $I->executeJS('submitAction(\'invoice\')'); - $I->wait(3); + $I->wait(2); $I->click('Save'); - $I->wait(3); + $I->wait(2); $I->see($clientEmail); $I->see($amount); } From 2fcb1d66a5ec9230e197abde576517441a9deeca Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 4 May 2016 09:53:43 +0300 Subject: [PATCH 10/16] Fix for travis tests --- .travis.yml | 3 ++- app/Exceptions/Handler.php | 2 +- app/Libraries/Utils.php | 5 +++++ app/Ninja/Transformers/ProductTransformer.php | 2 +- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 083bbe4f2583..1f66f7aa29f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -45,7 +45,8 @@ before_script: - php artisan key:generate --no-interaction - sed -i 's/APP_ENV=production/APP_ENV=development/g' .env - sed -i 's/APP_DEBUG=false/APP_DEBUG=true/g' .env - - sed -i 's/REQUIRE_HTTPS=false/NINJA_DEV=true/g' .env + - sed -i '$a NINJA_DEV=true' .env + - sed -i '$a TRAVIS=true' .env # create the database and user - mysql -u root -e "create database IF NOT EXISTS ninja;" - mysql -u root -e "GRANT ALL PRIVILEGES ON ninja.* To 'ninja'@'localhost' IDENTIFIED BY 'ninja'; FLUSH PRIVILEGES;" diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 5333d90f9e3b..2a8b0d305277 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -39,7 +39,7 @@ class Handler extends ExceptionHandler { return false; } - if (Utils::isNinja()) { + if (Utils::isNinja() && ! Utils::isTravis()) { Utils::logError(Utils::getErrorString($e)); return false; } else { diff --git a/app/Libraries/Utils.php b/app/Libraries/Utils.php index 141eacfc3058..7c1b11dfd84b 100644 --- a/app/Libraries/Utils.php +++ b/app/Libraries/Utils.php @@ -51,6 +51,11 @@ class Utils return php_sapi_name() == 'cli'; } + public static function isTravis() + { + return env('TRAVIS') == 'true'; + } + public static function isNinja() { return self::isNinjaProd() || self::isNinjaDev(); diff --git a/app/Ninja/Transformers/ProductTransformer.php b/app/Ninja/Transformers/ProductTransformer.php index 8331d7666154..309305815fb0 100644 --- a/app/Ninja/Transformers/ProductTransformer.php +++ b/app/Ninja/Transformers/ProductTransformer.php @@ -7,7 +7,7 @@ class ProductTransformer extends EntityTransformer { public function transform(Product $product) { - return array_merge($this->getDefaults(), [ + return array_merge($this->getDefaults($product), [ 'id' => (int) $product->public_id, 'product_key' => $product->product_key, 'notes' => $product->notes, From 2a6876a902fceeab4a7e13bb41d771bd1ecd9258 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 4 May 2016 11:14:20 +0300 Subject: [PATCH 11/16] Fix for travis tests --- .../Requests/CreatePaymentTermRequest.php | 30 ------------------- .../Requests/UpdatePaymentTermRequest.php | 30 ------------------- 2 files changed, 60 deletions(-) delete mode 100644 app/Http/Requests/CreatePaymentTermRequest.php delete mode 100644 app/Http/Requests/UpdatePaymentTermRequest.php diff --git a/app/Http/Requests/CreatePaymentTermRequest.php b/app/Http/Requests/CreatePaymentTermRequest.php deleted file mode 100644 index 23bf3151d096..000000000000 --- a/app/Http/Requests/CreatePaymentTermRequest.php +++ /dev/null @@ -1,30 +0,0 @@ - 'required', - 'name' => 'required', - ]; - } -} diff --git a/app/Http/Requests/UpdatePaymentTermRequest.php b/app/Http/Requests/UpdatePaymentTermRequest.php deleted file mode 100644 index ea9ff80e9772..000000000000 --- a/app/Http/Requests/UpdatePaymentTermRequest.php +++ /dev/null @@ -1,30 +0,0 @@ - 'required|positive', - ]; - - } -} From 9ebb539cce7d81b6334bfbdd833d58f9380be006 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 4 May 2016 14:53:27 +0300 Subject: [PATCH 12/16] API optimizations --- app/Console/Commands/CreateTestData.php | 172 ++++++++++++++++++ app/Console/Kernel.php | 1 + app/Http/Controllers/ExpenseApiController.php | 1 + app/Http/Controllers/InvoiceApiController.php | 2 +- app/Ninja/Transformers/ClientTransformer.php | 2 +- app/Ninja/Transformers/InvoiceTransformer.php | 2 +- app/Ninja/Transformers/VendorTransformer.php | 7 +- database/factories/ModelFactory.php | 48 +++++ 8 files changed, 230 insertions(+), 5 deletions(-) create mode 100644 app/Console/Commands/CreateTestData.php create mode 100644 database/factories/ModelFactory.php diff --git a/app/Console/Commands/CreateTestData.php b/app/Console/Commands/CreateTestData.php new file mode 100644 index 000000000000..4499e1cc09c4 --- /dev/null +++ b/app/Console/Commands/CreateTestData.php @@ -0,0 +1,172 @@ +faker = Factory::create(); + + $this->clientRepo = $clientRepo; + $this->invoiceRepo = $invoiceRepo; + $this->paymentRepo = $paymentRepo; + $this->vendorRepo = $vendorRepo; + $this->expenseRepo = $expenseRepo; + } + + public function fire() + { + if (Utils::isNinjaProd()) { + return false; + } + + $this->info(date('Y-m-d').' Running CreateTestData...'); + + Auth::loginUsingId(1); + $this->count = $this->argument('count'); + + $this->createClients(); + $this->createVendors(); + + $this->info('Done'); + } + + private function createClients() + { + for ($i=0; $i<$this->count; $i++) { + $data = [ + 'name' => $this->faker->name, + 'address1' => $this->faker->streetAddress, + 'address2' => $this->faker->secondaryAddress, + 'city' => $this->faker->city, + 'state' => $this->faker->state, + 'postal_code' => $this->faker->postcode, + 'contacts' => [[ + 'first_name' => $this->faker->firstName, + 'last_name' => $this->faker->lastName, + 'email' => $this->faker->safeEmail, + 'phone' => $this->faker->phoneNumber, + ]] + ]; + + $client = $this->clientRepo->save($data); + $this->info('Client: ' . $client->name); + + $this->createInvoices($client); + } + } + + private function createInvoices($client) + { + for ($i=0; $i<$this->count; $i++) { + $data = [ + 'client_id' => $client->id, + 'invoice_items' => [[ + 'product_key' => $this->faker->word, + 'qty' => $this->faker->randomDigit + 1, + 'cost' => $this->faker->randomFloat(2, 1, 10), + 'notes' => $this->faker->text($this->faker->numberBetween(50, 300)) + ]] + ]; + + $invoice = $this->invoiceRepo->save($data); + $this->info('Invoice: ' . $invoice->invoice_number); + + $this->createPayment($client, $invoice); + } + } + + private function createPayment($client, $invoice) + { + $data = [ + 'invoice_id' => $invoice->id, + 'client_id' => $client->id, + 'amount' => $this->faker->randomFloat(2, 0, $invoice->amount) + ]; + + $payment = $this->paymentRepo->save($data); + + $this->info('Payment: ' . $payment->amount); + } + + private function createVendors() + { + for ($i=0; $i<$this->count; $i++) { + $data = [ + 'name' => $this->faker->name, + 'address1' => $this->faker->streetAddress, + 'address2' => $this->faker->secondaryAddress, + 'city' => $this->faker->city, + 'state' => $this->faker->state, + 'postal_code' => $this->faker->postcode, + 'vendorcontacts' => [[ + 'first_name' => $this->faker->firstName, + 'last_name' => $this->faker->lastName, + 'email' => $this->faker->safeEmail, + 'phone' => $this->faker->phoneNumber, + ]] + ]; + + $vendor = $this->vendorRepo->save($data); + $this->info('Vendor: ' . $vendor->name); + + $this->createExpense($vendor); + } + } + + private function createExpense($vendor) + { + for ($i=0; $i<$this->count; $i++) { + $data = [ + 'vendor_id' => $vendor->id, + 'amount' => $this->faker->randomFloat(2, 1, 10), + 'expense_date' => null, + 'public_notes' => null, + ]; + + $expense = $this->expenseRepo->save($data); + $this->info('Expense: ' . $expense->amount); + } + } + + protected function getArguments() + { + return array( + //array('example', InputArgument::REQUIRED, 'An example argument.'), + ); + } + + protected function getOptions() + { + return array( + //array('example', null, InputOption::VALUE_OPTIONAL, 'An example option.', null), + ); + } +} diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index 2bc2b1b20787..179e423388f1 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -17,6 +17,7 @@ class Kernel extends ConsoleKernel 'App\Console\Commands\ResetData', 'App\Console\Commands\CheckData', 'App\Console\Commands\PruneData', + 'App\Console\Commands\CreateTestData', 'App\Console\Commands\SendRenewalInvoices', 'App\Console\Commands\ChargeRenewalInvoices', 'App\Console\Commands\SendReminders', diff --git a/app/Http/Controllers/ExpenseApiController.php b/app/Http/Controllers/ExpenseApiController.php index 44722f2a18ce..725067aa1f2c 100644 --- a/app/Http/Controllers/ExpenseApiController.php +++ b/app/Http/Controllers/ExpenseApiController.php @@ -30,6 +30,7 @@ class ExpenseApiController extends BaseAPIController { $expenses = Expense::scope() ->withTrashed() + ->with('client', 'invoice', 'vendor') ->orderBy('created_at','desc'); return $this->listResponse($expenses); diff --git a/app/Http/Controllers/InvoiceApiController.php b/app/Http/Controllers/InvoiceApiController.php index 1361aad9e9a3..667690395eb2 100644 --- a/app/Http/Controllers/InvoiceApiController.php +++ b/app/Http/Controllers/InvoiceApiController.php @@ -60,7 +60,7 @@ class InvoiceApiController extends BaseAPIController { $invoices = Invoice::scope() ->withTrashed() - ->with('invoice_items') + ->with('invoice_items', 'client') ->orderBy('created_at', 'desc'); return $this->listResponse($invoices); diff --git a/app/Ninja/Transformers/ClientTransformer.php b/app/Ninja/Transformers/ClientTransformer.php index 63f0baa0c871..ea282f74ceca 100644 --- a/app/Ninja/Transformers/ClientTransformer.php +++ b/app/Ninja/Transformers/ClientTransformer.php @@ -47,7 +47,7 @@ class ClientTransformer extends EntityTransformer protected $availableIncludes = [ 'invoices', 'credits', - 'expenses', + //'expenses', ]; public function includeContacts(Client $client) diff --git a/app/Ninja/Transformers/InvoiceTransformer.php b/app/Ninja/Transformers/InvoiceTransformer.php index 0933422875c2..c866f1213540 100644 --- a/app/Ninja/Transformers/InvoiceTransformer.php +++ b/app/Ninja/Transformers/InvoiceTransformer.php @@ -28,7 +28,7 @@ class InvoiceTransformer extends EntityTransformer 'invitations', 'payments', 'client', - 'expenses', + //'expenses', ]; public function __construct($account = null, $serializer = null, $client = null) diff --git a/app/Ninja/Transformers/VendorTransformer.php b/app/Ninja/Transformers/VendorTransformer.php index f9c37ac44200..2af79422fde8 100644 --- a/app/Ninja/Transformers/VendorTransformer.php +++ b/app/Ninja/Transformers/VendorTransformer.php @@ -35,10 +35,13 @@ class VendorTransformer extends EntityTransformer * @SWG\Property(property="id_number", type="string", example="123456") */ - protected $availableIncludes = [ + protected $defaultIncludes = [ 'vendorContacts', + ]; + + protected $availableIncludes = [ 'invoices', - 'expenses', + //'expenses', ]; public function includeVendorContacts(Vendor $vendor) diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php new file mode 100644 index 000000000000..018da7b2357b --- /dev/null +++ b/database/factories/ModelFactory.php @@ -0,0 +1,48 @@ +define(Contact::class, function (Faker\Generator $faker) { + return [ + 'client_id' => function() { + return factory(Client::class)->create()->id; + }, + 'user_id' => 1, + 'account_id' => 1, + 'public_id' => Contact::count() + 1, + 'is_primary' => true, + 'send_invoice' => true, + 'first_name' => $faker->firstName, + 'last_name' => $faker->lastName, + 'email' => $faker->safeEmail, + 'phone' => $faker->phoneNumber, + ]; +}); + +$factory->define(Client::class, function (Faker\Generator $faker) { + return [ + 'user_id' => 1, + 'account_id' => 1, + 'public_id' => Client::count() + 1, + 'name' => $faker->name, + 'address1' => $faker->streetAddress, + 'address2' => $faker->secondaryAddress, + 'city' => $faker->city, + 'state' => $faker->state, + 'postal_code' => $faker->postcode, + 'country_id' => Country::all()->random()->id, + ]; +}); \ No newline at end of file From db9d75ceffb143e71f71c9444b65a928edcb9da9 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 4 May 2016 15:16:49 +0300 Subject: [PATCH 13/16] Changed vendorcontacts to vendor_contacts --- app/Console/Commands/CreateTestData.php | 2 +- app/Http/Controllers/BaseAPIController.php | 2 +- app/Http/Controllers/ExpenseController.php | 6 ++-- app/Http/Controllers/ExportController.php | 4 +-- app/Http/Controllers/VendorApiController.php | 2 +- app/Http/Requests/VendorRequest.php | 4 +-- app/Models/Vendor.php | 4 +-- app/Ninja/Repositories/VendorRepository.php | 6 ++-- app/Ninja/Transformers/VendorTransformer.php | 4 +-- resources/views/vendors/edit.blade.php | 34 ++++++++++---------- resources/views/vendors/show.blade.php | 2 +- tests/acceptance/APICest.php | 2 +- 12 files changed, 36 insertions(+), 36 deletions(-) diff --git a/app/Console/Commands/CreateTestData.php b/app/Console/Commands/CreateTestData.php index 4499e1cc09c4..6a0643e46c5a 100644 --- a/app/Console/Commands/CreateTestData.php +++ b/app/Console/Commands/CreateTestData.php @@ -126,7 +126,7 @@ class CreateTestData extends Command 'city' => $this->faker->city, 'state' => $this->faker->state, 'postal_code' => $this->faker->postcode, - 'vendorcontacts' => [[ + 'vendor_contacts' => [[ 'first_name' => $this->faker->firstName, 'last_name' => $this->faker->lastName, 'email' => $this->faker->safeEmail, diff --git a/app/Http/Controllers/BaseAPIController.php b/app/Http/Controllers/BaseAPIController.php index 8e48f3bff878..8ffc45ffcf51 100644 --- a/app/Http/Controllers/BaseAPIController.php +++ b/app/Http/Controllers/BaseAPIController.php @@ -204,7 +204,7 @@ class BaseAPIController extends Controller } elseif ($include == 'clients') { $data[] = 'clients.contacts'; } elseif ($include == 'vendors') { - $data[] = 'vendors.vendorcontacts'; + $data[] = 'vendors.vendor_contacts'; } elseif ($include) { $data[] = $include; } diff --git a/app/Http/Controllers/ExpenseController.php b/app/Http/Controllers/ExpenseController.php index 3da123c2d972..d4184abf3fca 100644 --- a/app/Http/Controllers/ExpenseController.php +++ b/app/Http/Controllers/ExpenseController.php @@ -74,7 +74,7 @@ class ExpenseController extends BaseController public function create(ExpenseRequest $request) { if ($request->vendor_id != 0) { - $vendor = Vendor::scope($request->vendor_id)->with('vendorcontacts')->firstOrFail(); + $vendor = Vendor::scope($request->vendor_id)->with('vendor_contacts')->firstOrFail(); } else { $vendor = null; } @@ -85,7 +85,7 @@ class ExpenseController extends BaseController 'method' => 'POST', 'url' => 'expenses', 'title' => trans('texts.new_expense'), - 'vendors' => Vendor::scope()->with('vendorcontacts')->orderBy('name')->get(), + 'vendors' => Vendor::scope()->with('vendor_contacts')->orderBy('name')->get(), 'vendor' => $vendor, 'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), 'clientPublicId' => $request->client_id, @@ -124,7 +124,7 @@ class ExpenseController extends BaseController 'url' => 'expenses/'.$expense->public_id, 'title' => 'Edit Expense', 'actions' => $actions, - 'vendors' => Vendor::scope()->with('vendorcontacts')->orderBy('name')->get(), + 'vendors' => Vendor::scope()->with('vendor_contacts')->orderBy('name')->get(), 'vendorPublicId' => $expense->vendor ? $expense->vendor->public_id : null, 'clients' => Client::scope()->with('contacts')->orderBy('name')->get(), 'clientPublicId' => $expense->client ? $expense->client->public_id : null, diff --git a/app/Http/Controllers/ExportController.php b/app/Http/Controllers/ExportController.php index db74adb89cee..ebaaa1f6c306 100644 --- a/app/Http/Controllers/ExportController.php +++ b/app/Http/Controllers/ExportController.php @@ -164,12 +164,12 @@ class ExportController extends BaseController if ($request->input(ENTITY_VENDOR)) { $data['clients'] = Vendor::scope() - ->with('user', 'vendorcontacts', 'country') + ->with('user', 'vendor_contacts', 'country') ->withArchived() ->get(); $data['vendor_contacts'] = VendorContact::scope() - ->with('user', 'vendor.contacts') + ->with('user', 'vendor.vendor_contacts') ->withTrashed() ->get(); diff --git a/app/Http/Controllers/VendorApiController.php b/app/Http/Controllers/VendorApiController.php index 2995e5c5e5f2..e15207934cd8 100644 --- a/app/Http/Controllers/VendorApiController.php +++ b/app/Http/Controllers/VendorApiController.php @@ -81,7 +81,7 @@ class VendorApiController extends BaseAPIController $vendor = $this->vendorRepo->save($request->input()); $vendor = Vendor::scope($vendor->public_id) - ->with('country', 'vendorcontacts', 'industry', 'size', 'currency') + ->with('country', 'vendor_contacts', 'industry', 'size', 'currency') ->first(); return $this->itemResponse($vendor); diff --git a/app/Http/Requests/VendorRequest.php b/app/Http/Requests/VendorRequest.php index 600678686c0e..a06e5ad808e6 100644 --- a/app/Http/Requests/VendorRequest.php +++ b/app/Http/Requests/VendorRequest.php @@ -9,8 +9,8 @@ class VendorRequest extends EntityRequest { $vendor = parent::entity(); // eager load the contacts - if ($vendor && ! count($vendor->vendorcontacts)) { - $vendor->load('vendorcontacts'); + if ($vendor && ! count($vendor->vendor_contacts)) { + $vendor->load('vendor_contacts'); } return $vendor; diff --git a/app/Models/Vendor.php b/app/Models/Vendor.php index 573a581e4774..6fcd10f14092 100644 --- a/app/Models/Vendor.php +++ b/app/Models/Vendor.php @@ -95,7 +95,7 @@ class Vendor extends EntityModel return $this->hasMany('App\Models\Payment'); } - public function vendorContacts() + public function vendor_contacts() { return $this->hasMany('App\Models\VendorContact'); } @@ -143,7 +143,7 @@ class Vendor extends EntityModel $contact->fill($data); $contact->is_primary = $isPrimary; - return $this->vendorContacts()->save($contact); + return $this->vendor_contacts()->save($contact); } public function getRoute() diff --git a/app/Ninja/Repositories/VendorRepository.php b/app/Ninja/Repositories/VendorRepository.php index ef5648f47d81..82e1bfdd18f1 100644 --- a/app/Ninja/Repositories/VendorRepository.php +++ b/app/Ninja/Repositories/VendorRepository.php @@ -16,7 +16,7 @@ class VendorRepository extends BaseRepository public function all() { return Vendor::scope() - ->with('user', 'vendorcontacts', 'country') + ->with('user', 'vendor_contacts', 'country') ->withTrashed() ->where('is_deleted', '=', false) ->get(); @@ -71,7 +71,7 @@ class VendorRepository extends BaseRepository } elseif (!$publicId || $publicId == '-1') { $vendor = Vendor::createNew(); } else { - $vendor = Vendor::scope($publicId)->with('vendorcontacts')->firstOrFail(); + $vendor = Vendor::scope($publicId)->with('vendor_contacts')->firstOrFail(); \Log::warning('Entity not set in vendor repo save'); } @@ -79,7 +79,7 @@ class VendorRepository extends BaseRepository $vendor->save(); $first = true; - $vendorcontacts = isset($data['vendorcontact']) ? [$data['vendorcontact']] : $data['vendorcontacts']; + $vendorcontacts = isset($data['vendor_contact']) ? [$data['vendor_contact']] : $data['vendor_contacts']; foreach ($vendorcontacts as $vendorcontact) { $vendorcontact = $vendor->addVendorContact($vendorcontact, $first); diff --git a/app/Ninja/Transformers/VendorTransformer.php b/app/Ninja/Transformers/VendorTransformer.php index 2af79422fde8..df8dc5ea3461 100644 --- a/app/Ninja/Transformers/VendorTransformer.php +++ b/app/Ninja/Transformers/VendorTransformer.php @@ -36,7 +36,7 @@ class VendorTransformer extends EntityTransformer */ protected $defaultIncludes = [ - 'vendorContacts', + 'vendor_contacts', ]; protected $availableIncludes = [ @@ -47,7 +47,7 @@ class VendorTransformer extends EntityTransformer public function includeVendorContacts(Vendor $vendor) { $transformer = new VendorContactTransformer($this->account, $this->serializer); - return $this->includeCollection($vendor->vendorContacts, $transformer, ENTITY_CONTACT); + return $this->includeCollection($vendor->vendor_contacts, $transformer, ENTITY_CONTACT); } public function includeInvoices(Vendor $vendor) diff --git a/resources/views/vendors/edit.blade.php b/resources/views/vendors/edit.blade.php index 5a61287b2ba3..82a619281513 100644 --- a/resources/views/vendors/edit.blade.php +++ b/resources/views/vendors/edit.blade.php @@ -7,8 +7,8 @@ @section('content') -@if ($errors->first('vendorcontacts')) -
{{ trans($errors->first('vendorcontacts')) }}
+@if ($errors->first('vendor_contacts')) +
{{ trans($errors->first('vendor_contacts')) }}
@endif
@@ -73,26 +73,26 @@
-
{!! Former::hidden('public_id')->data_bind("value: public_id, valueUpdate: 'afterkeydown', - attr: {name: 'vendorcontacts[' + \$index() + '][public_id]'}") !!} + attr: {name: 'vendor_contacts[' + \$index() + '][public_id]'}") !!} {!! Former::text('first_name')->data_bind("value: first_name, valueUpdate: 'afterkeydown', - attr: {name: 'vendorcontacts[' + \$index() + '][first_name]'}") !!} + attr: {name: 'vendor_contacts[' + \$index() + '][first_name]'}") !!} {!! Former::text('last_name')->data_bind("value: last_name, valueUpdate: 'afterkeydown', - attr: {name: 'vendorcontacts[' + \$index() + '][last_name]'}") !!} + attr: {name: 'vendor_contacts[' + \$index() + '][last_name]'}") !!} {!! Former::text('email')->data_bind("value: email, valueUpdate: 'afterkeydown', - attr: {name: 'vendorcontacts[' + \$index() + '][email]', id:'email'+\$index()}") !!} + attr: {name: 'vendor_contacts[' + \$index() + '][email]', id:'email'+\$index()}") !!} {!! Former::text('phone')->data_bind("value: phone, valueUpdate: 'afterkeydown', - attr: {name: 'vendorcontacts[' + \$index() + '][phone]'}") !!} + attr: {name: 'vendor_contacts[' + \$index() + '][phone]'}") !!}
- + {!! link_to('#', trans('texts.remove_contact').' -', array('data-bind'=>'click: $parent.removeContact')) !!} - + {!! link_to('#', trans('texts.add_contact').' +', array('onclick'=>'return addContact()')) !!}
@@ -186,10 +186,10 @@ function VendorModel(data) { var self = this; - self.vendorcontacts = ko.observableArray(); + self.vendor_contacts = ko.observableArray(); self.mapping = { - 'vendorcontacts': { + 'vendor_contacts': { create: function(options) { return new VendorContactModel(options.data); } @@ -199,12 +199,12 @@ if (data) { ko.mapping.fromJS(data, self.mapping, this); } else { - self.vendorcontacts.push(new VendorContactModel()); + self.vendor_contacts.push(new VendorContactModel()); } self.placeholderName = ko.computed(function() { - if (self.vendorcontacts().length == 0) return ''; - var contact = self.vendorcontacts()[0]; + if (self.vendor_contacts().length == 0) return ''; + var contact = self.vendor_contacts()[0]; if (contact.first_name() || contact.last_name()) { return contact.first_name() + ' ' + contact.last_name(); } else { @@ -226,12 +226,12 @@ ko.applyBindings(model); function addContact() { - model.vendorcontacts.push(new VendorContactModel()); + model.vendor_contacts.push(new VendorContactModel()); return false; } model.removeContact = function() { - model.vendorcontacts.remove(this); + model.vendor_contacts.remove(this); } diff --git a/resources/views/vendors/show.blade.php b/resources/views/vendors/show.blade.php index 62037179e741..37572ee4c5bc 100644 --- a/resources/views/vendors/show.blade.php +++ b/resources/views/vendors/show.blade.php @@ -109,7 +109,7 @@

{{ trans('texts.contacts') }}

- @foreach ($vendor->vendorcontacts as $contact) + @foreach ($vendor->vendor_contacts as $contact) @if ($contact->first_name || $contact->last_name) {{ $contact->first_name.' '.$contact->last_name }}
@endif diff --git a/tests/acceptance/APICest.php b/tests/acceptance/APICest.php index ee36c6265e5c..41e922539677 100644 --- a/tests/acceptance/APICest.php +++ b/tests/acceptance/APICest.php @@ -78,7 +78,7 @@ class APICest $data = new stdClass; $data->name = $this->faker->word; - $data->vendorcontacts = []; + $data->vendor_contacts = []; $this->createEntity('vendor', $data); $this->listEntities('vendor'); From 3300619d28bfd29f0011f69baa8768c673e634d6 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 4 May 2016 23:27:12 +0300 Subject: [PATCH 14/16] Added support for gzip to the .htaccess file --- .htaccess | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/.htaccess b/.htaccess index 27a6945d38f8..8b1f582ca455 100644 --- a/.htaccess +++ b/.htaccess @@ -6,3 +6,141 @@ # https://coderwall.com/p/erbaig/laravel-s-htaccess-to-remove-public-from-url # RewriteRule ^(.*)$ public/$1 [L] + +# https://github.com/h5bp/server-configs-apache/blob/master/dist/.htaccess + + +# ###################################################################### +# # INTERNET EXPLORER # +# ###################################################################### + +# ---------------------------------------------------------------------- +# | Iframes cookies | +# ---------------------------------------------------------------------- + +# Allow cookies to be set from iframes in Internet Explorer. +# +# https://msdn.microsoft.com/en-us/library/ms537343.aspx +# http://www.w3.org/TR/2000/CR-P3P-20001215/ + + + Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"" + + + +# ###################################################################### +# # MEDIA TYPES AND CHARACTER ENCODINGS # +# ###################################################################### + +# ---------------------------------------------------------------------- +# | Character encodings | +# ---------------------------------------------------------------------- + +# Serve all resources labeled as `text/html` or `text/plain` +# with the media type `charset` parameter set to `UTF-8`. +# +# https://httpd.apache.org/docs/current/mod/core.html#adddefaultcharset + +AddDefaultCharset utf-8 + +# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + +# Serve the following file types with the media type `charset` +# parameter set to `UTF-8`. +# +# https://httpd.apache.org/docs/current/mod/mod_mime.html#addcharset + + + AddCharset utf-8 .atom \ + .bbaw \ + .css \ + .geojson \ + .js \ + .json \ + .jsonld \ + .manifest \ + .rdf \ + .rss \ + .topojson \ + .vtt \ + .webapp \ + .webmanifest \ + .xloc \ + .xml + + + +# ###################################################################### +# # WEB PERFORMANCE # +# ###################################################################### + +# ---------------------------------------------------------------------- +# | Compression | +# ---------------------------------------------------------------------- + + + + # Force compression for mangled headers. + # https://developer.yahoo.com/blogs/ydn/pushing-beyond-gzipping-25601.html + + + + SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding + RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding + + + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + # Map certain file types to the specified encoding type in order to + # make Apache serve them with the appropriate `Content-Encoding` HTTP + # response header (this will NOT make Apache compress them!). + + # If the following file types wouldn't be served without the appropriate + # `Content-Enable` HTTP response header, client applications (e.g.: + # browsers) wouldn't know that they first need to uncompress the response, + # and thus, wouldn't be able to understand the content. + + # http://httpd.apache.org/docs/current/mod/mod_mime.html#addencoding + + + AddEncoding gzip svgz + + + # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + # Compress all output labeled with one of the following media types. + + # IMPORTANT: For Apache versions below 2.3.7 you don't need to enable + # `mod_filter` and can remove the `` & `` + # lines as `AddOutputFilterByType` is still in the core directives. + + + AddOutputFilterByType DEFLATE "application/atom+xml" \ + "application/javascript" \ + "application/json" \ + "application/ld+json" \ + "application/manifest+json" \ + "application/rdf+xml" \ + "application/rss+xml" \ + "application/schema+json" \ + "application/vnd.geo+json" \ + "application/vnd.ms-fontobject" \ + "application/x-font-ttf" \ + "application/x-web-app-manifest+json" \ + "application/xhtml+xml" \ + "application/xml" \ + "font/opentype" \ + "image/svg+xml" \ + "image/x-icon" \ + "text/cache-manifest" \ + "text/css" \ + "text/html" \ + "text/javascript" \ + "text/plain" \ + "text/vtt" \ + "text/x-component" \ + "text/xml" + + + \ No newline at end of file From 32bf47aacff801a43aa188a1aba2e228e4ee2a9b Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Wed, 4 May 2016 23:49:20 +0300 Subject: [PATCH 15/16] Added support for filtering API lists by updated_at --- app/Http/Controllers/BaseAPIController.php | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/Http/Controllers/BaseAPIController.php b/app/Http/Controllers/BaseAPIController.php index 8ffc45ffcf51..a172c2e1c5db 100644 --- a/app/Http/Controllers/BaseAPIController.php +++ b/app/Http/Controllers/BaseAPIController.php @@ -90,10 +90,21 @@ class BaseAPIController extends Controller $transformerClass = EntityModel::getTransformerName($this->entityType); $transformer = new $transformerClass(Auth::user()->account, Input::get('serializer')); - $include = $transformer->getDefaultIncludes(); - $include = $this->getRequestIncludes($include); - $query->with($include); - + $includes = $transformer->getDefaultIncludes(); + $includes = $this->getRequestIncludes($includes); + + if ($updatedAt = Input::get('updated_at')) { + $query->where('updated_at', '>=', $updatedAt); + } + + foreach ($includes as $include) { + $query->with([$include => function($query) use ($updatedAt) { + if ($updatedAt) { + $query->where('updated_at', '>=', $updatedAt); + } + }]); + } + if ($clientPublicId = Input::get('client_id')) { $filter = function($query) use ($clientPublicId) { $query->where('public_id', '=', $clientPublicId); @@ -156,7 +167,7 @@ class BaseAPIController extends Controller if (Utils::isNinjaDev()) { $count = count(\DB::getQueryLog()); Log::info(Request::method() . ' - ' . Request::url() . ": $count queries"); - //Log::info(print_r(\DB::getQueryLog(), true)); + //Log::info(json_encode(\DB::getQueryLog())); } $index = Request::get('index') ?: 'data'; From 5d00d186012c3e4494d89eef7d637fe6b6e64d12 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 5 May 2016 00:26:39 +0300 Subject: [PATCH 16/16] Added support for filtering API lists by updated_at --- app/Http/Controllers/BaseAPIController.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/app/Http/Controllers/BaseAPIController.php b/app/Http/Controllers/BaseAPIController.php index a172c2e1c5db..0718e95b91e4 100644 --- a/app/Http/Controllers/BaseAPIController.php +++ b/app/Http/Controllers/BaseAPIController.php @@ -93,17 +93,19 @@ class BaseAPIController extends Controller $includes = $transformer->getDefaultIncludes(); $includes = $this->getRequestIncludes($includes); - if ($updatedAt = Input::get('updated_at')) { - $query->where('updated_at', '>=', $updatedAt); - } + $query->with($includes); - foreach ($includes as $include) { - $query->with([$include => function($query) use ($updatedAt) { - if ($updatedAt) { - $query->where('updated_at', '>=', $updatedAt); + if ($updatedAt = Input::get('updated_at')) { + $updatedAt = date('Y-m-d H:i:s', $updatedAt); + $query->where(function($query) use ($includes, $updatedAt) { + $query->where('updated_at', '>=', $updatedAt); + foreach ($includes as $include) { + $query->orWhereHas($include, function($query) use ($updatedAt) { + $query->where('updated_at', '>=', $updatedAt); + }); } - }]); - } + }); + } if ($clientPublicId = Input::get('client_id')) { $filter = function($query) use ($clientPublicId) { @@ -167,7 +169,7 @@ class BaseAPIController extends Controller if (Utils::isNinjaDev()) { $count = count(\DB::getQueryLog()); Log::info(Request::method() . ' - ' . Request::url() . ": $count queries"); - //Log::info(json_encode(\DB::getQueryLog())); + Log::info(json_encode(\DB::getQueryLog())); } $index = Request::get('index') ?: 'data';