diff --git a/app/Http/Controllers/Migration/StepsController.php b/app/Http/Controllers/Migration/StepsController.php new file mode 100644 index 0000000000..a7c5b5896a --- /dev/null +++ b/app/Http/Controllers/Migration/StepsController.php @@ -0,0 +1,498 @@ +account = Auth::user()->account; + + $date = date('Y-m-d'); + $accountKey = $this->account->account_key; + + $output = fopen('php://output', 'w') or Utils::fatalError(); + + $fileName = "{$accountKey}-{$date}-invoiceninja"; + + $data = [ + 'company' => $this->getCompany(), + 'users' => $this->getUsers(), + 'tax_rates' => $this->getTaxRates(), + 'clients' => $this->getClients(), + 'products' => $this->getProducts(), + 'invoices' => $this->getInvoices(), + 'quotes' => $this->getQuotes(), + 'payments' => array_merge($this->getPayments(), $this->getCredits()), + 'credits' => $this->getCreditsNotes(), + ]; + + $file = storage_path("{$fileName}.zip"); + + $zip = new \ZipArchive(); + $zip->open($file, \ZipArchive::CREATE | \ZipArchive::OVERWRITE); + $zip->addFromString('migration.json', json_encode($data)); + $zip->close(); + + header('Content-Type: application/zip'); + header('Content-Length: ' . filesize($file)); + header("Content-Disposition: attachment; filename={$fileName}.zip"); + + readfile($file); + unlink($file); + + return response()->json($data); + } + + /** + * Export company and map to the v2 fields. + * + * @return array + */ + protected function getCompany() + { + return [ + 'account_id' => $this->account->id, + 'industry_id' => $this->account->industry_id, + 'ip' => $this->account->ip, + 'company_key' => $this->account->account_key, + 'logo' => $this->account->logo, + 'convert_products' => $this->account->convert_products, + 'fill_products' => $this->account->fill_products, + 'update_products' => $this->account->update_products, + 'show_product_details' => $this->account->show_product_notes, + 'custom_surcharge_taxes1' => $this->account->custom_invoice_taxes1, + 'custom_surcharge_taxes2' => $this->account->custom_invoice_taxes2, + 'enable_invoice_quantity' => !$this->account->hide_quantity, + 'subdomain' => $this->account->subdomain, + 'size_id' => $this->account->size_id, + 'enable_modules' => $this->account->enabled_modules, + 'custom_fields' => $this->account->custom_fields, + 'uses_inclusive_taxes' => $this->account->inclusive_taxes, + 'created_at' => $this->account->created_at ? $this->account->created_at->toDateString() : null, + 'updated_at' => $this->account->updated_at ? $this->account->updated_at->toDateString() : null, + ]; + } + + /** + * @return array + */ + public function getTaxRates() + { + $rates = TaxRate::where('account_id', $this->account->id) + ->withTrashed() + ->get(); + + $transformed = []; + + foreach ($rates as $rate) { + $transformed[] = [ + 'name' => $rate->name, + 'rate' => $rate->rate, + 'company_id' => $rate->account_id, + 'user_id' => $rate->user_id, + 'created_at' => $rate->created_at ? $rate->created_at->toDateString() : null, + 'updated_at' => $rate->updated_at ? $rate->updated_at->toDateString() : null, + 'deleted_at' => $rate->deleted_at ? $rate->deleted_at->toDateString() : null, + ]; + } + + return $transformed; + } + + /** + * @return array + */ + protected function getClients() + { + $clients = []; + + foreach ($this->account->clients()->withTrashed()->get() as $client) { + $clients[] = [ + 'id' => $client->id, + 'company_id' => $client->account_id, + 'user_id' => $client->user_id, + 'name' => $client->name, + 'balance' => $client->balance, + 'paid_to_date' => $client->paid_to_date, + 'address1' => $client->address1, + 'address2' => $client->address2, + 'city' => $client->city, + 'state' => $client->state, + 'postal_code' => $client->postal_code, + 'country_id' => $client->country_id, + 'phone' => $client->work_phone, + 'private_notes' => $client->private_notes, + 'last_login' => $client->last_login, + 'website' => $client->website, + 'industry_id' => $client->industry_id, + 'size_id' => $client->size_id, + 'is_deleted' => $client->is_deleted, + 'vat_number' => $client->vat_number, + 'id_number' => $client->id_number, + 'custom_value1' => $client->custom_value1, + 'custom_value2' => $client->custom_value2, + 'shipping_address1' => $client->shipping_address1, + 'shipping_address2' => $client->shipping_address2, + 'shipping_city' => $client->shipping_city, + 'shipping_state' => $client->shipping_state, + 'shipping_postal_code' => $client->shipping_postal_code, + 'shipping_country_id' => $client->shipping_country_id, + ]; + } + + return $clients; + } + + /** + * @return array + */ + protected function getProducts() + { + $products = Product::where('account_id', $this->account->id) + ->withTrashed() + ->get(); + + $transformed = []; + + foreach ($products as $product) { + $transformed[] = [ + 'company_id' => $product->account_id, + 'user_id' => $product->user_id, + 'custom_value1' => $product->custom_value1, + 'custom_value2' => $product->custom_value2, + 'product_key' => $product->product_key, + 'notes' => $product->notes, + 'cost' => $product->cost, + 'quantity' => $product->qty, + 'tax_name1' => $product->tax_name1, + 'tax_name2' => $product->tax_name2, + 'tax_rate1' => $product->tax_rate1, + 'tax_rate2' => $product->tax_rate2, + 'created_at' => $product->created_at ? $product->created_at->toDateString() : null, + 'updated_at' => $product->updated_at ? $product->updated_at->toDateString() : null, + 'deleted_at' => $product->deleted_at ? $product->deleted_at->toDateString() : null, + ]; + } + + return $transformed; + } + + /** + * @return array + */ + public function getUsers() + { + $users = User::where('account_id', $this->account->id) + ->withTrashed() + ->get(); + + $transformed = []; + + foreach ($users as $user) { + $transformed[] = [ + 'id' => $user->id, + 'first_name' => $user->first_name, + 'last_name' => $user->last_name, + 'phone' => $user->phone, + 'email' => $user->email, + 'confirmation_code' => $user->confirmation_code, + 'failed_logins' => $user->failed_logins, + 'referral_code' => $user->referral_code, + 'oauth_user_id' => $user->oauth_user_id, + 'oauth_provider_id' => $user->oauth_provider_id, + 'google_2fa_secret' => $user->google_2fa_secret, + 'accepted_terms_version' => $user->accepted_terms_version, + 'password' => $user->password, + 'remember_token' => $user->remember_token, + 'created_at' => $user->created_at ? $user->created_at->toDateString() : null, + 'updated_at' => $user->updated_at ? $user->updated_at->toDateString() : null, + 'deleted_at' => $user->deleted_at ? $user->deleted_at->toDateString() : null, + ]; + } + + return $transformed; + } + + private function getCreditsNotes() + { + $credits = []; + + foreach ($this->account->invoices()->where('amount', '<', '0')->withTrashed()->get() as $credit) { + $credits[] = [ + 'id' => $credit->id, + 'client_id' => $credit->client_id, + 'user_id' => $credit->user_id, + 'company_id' => $credit->account_id, + 'status_id' => $credit->invoice_status_id, + 'design_id' => $credit->invoice_design_id, + 'number' => $credit->invoice_number, + 'discount' => $credit->discount, + 'is_amount_discount' => $credit->is_amount_discount ?: false, + 'po_number' => $credit->po_number, + 'date' => $credit->invoice_date, + 'last_sent_date' => $credit->last_sent_date, + 'due_date' => $credit->due_date, + 'is_deleted' => $credit->is_deleted, + 'footer' => $credit->invoice_footer, + 'public_notes' => $credit->public_notes, + 'private_notes' => $credit->private_notes, + 'terms' => $credit->terms, + 'tax_name1' => $credit->tax_name1, + 'tax_name2' => $credit->tax_name2, + 'tax_rate1' => $credit->tax_rate1, + 'tax_rate2' => $credit->tax_rate2, + 'custom_value1' => $credit->custom_value1, + 'custom_value2' => $credit->custom_value2, + 'next_send_date' => null, + 'amount' => $credit->amount, + 'balance' => $credit->balance, + 'partial' => $credit->partial, + 'partial_due_date' => $credit->partial_due_date, + 'line_items' => $this->getInvoiceItems($credit->invoice_items), + 'created_at' => $credit->created_at ? $credit->created_at->toDateString() : null, + 'updated_at' => $credit->updated_at ? $credit->updated_at->toDateString() : null, + 'deleted_at' => $credit->deleted_at ? $credit->deleted_at->toDateString() : null, + ]; + } + + return $credits; + } + + /** + * @return array + */ + protected function getInvoices() + { + $invoices = []; + + foreach ($this->account->invoices()->where('amount', '>=', '0')->withTrashed()->get() as $invoice) { + $invoices[] = [ + 'id' => $invoice->id, + 'client_id' => $invoice->client_id, + 'user_id' => $invoice->user_id, + 'company_id' => $invoice->account_id, + 'status_id' => $invoice->invoice_status_id, + 'design_id' => $invoice->invoice_design_id, + 'number' => $invoice->invoice_number, + 'discount' => $invoice->discount, + 'is_amount_discount' => $invoice->is_amount_discount ?: false, + 'po_number' => $invoice->po_number, + 'date' => $invoice->invoice_date, + 'last_sent_date' => $invoice->last_sent_date, + 'due_date' => $invoice->due_date, + 'is_deleted' => $invoice->is_deleted, + 'footer' => $invoice->invoice_footer, + 'public_notes' => $invoice->public_notes, + 'private_notes' => $invoice->private_notes, + 'terms' => $invoice->terms, + 'tax_name1' => $invoice->tax_name1, + 'tax_name2' => $invoice->tax_name2, + 'tax_rate1' => $invoice->tax_rate1, + 'tax_rate2' => $invoice->tax_rate2, + 'custom_value1' => $invoice->custom_value1, + 'custom_value2' => $invoice->custom_value2, + 'next_send_date' => null, + 'amount' => $invoice->amount, + 'balance' => $invoice->balance, + 'partial' => $invoice->partial, + 'partial_due_date' => $invoice->partial_due_date, + 'line_items' => $this->getInvoiceItems($invoice->invoice_items), + 'created_at' => $invoice->created_at ? $invoice->created_at->toDateString() : null, + 'updated_at' => $invoice->updated_at ? $invoice->updated_at->toDateString() : null, + 'deleted_at' => $invoice->deleted_at ? $invoice->deleted_at->toDateString() : null, + ]; + } + + return $invoices; + } + + /** + * @param $items + * @return array + */ + public function getInvoiceItems($items) + { + $transformed = []; + + foreach ($items as $item) { + $transformed[] = [ + 'id' => $item->id, + 'quantity' => $item->qty, + 'cost' => $item->cost, + 'product_key' => $item->product_key, + 'notes' => $item->notes, + 'discount' => $item->discount, + 'tax_name1' => $item->tax_name1, + 'tax_rate1' => $item->tax_rate1, + 'date' => $item->created_at, + 'custom_value1' => $item->custom_value1, + 'custom_value2' => $item->custom_value2, + 'line_item_type_id' => $item->invoice_item_type_id, + ]; + } + + return $transformed; + } + + /** + * @return array + */ + public function getQuotes() + { + $transformed = []; + + $quotes = Invoice::where('account_id', $this->account->id) + ->where('invoice_type_id', '=', INVOICE_TYPE_QUOTE) + ->withTrashed() + ->get(); + + foreach ($quotes as $quote) { + $transformed[] = [ + 'id' => $quote->id, + 'client_id' => $quote->client_id, + 'user_id' => $quote->user_id, + 'company_id' => $quote->account_id, + 'status_id' => $quote->invoice_status_id, + 'design_id' => $quote->invoice_design_id, + 'number' => $quote->invoice_number, + 'discount' => $quote->discount, + 'is_amount_discount' => $quote->is_amount_discount ?: false, + 'po_number' => $quote->po_number, + 'date' => $quote->invoice_date, + 'last_sent_date' => $quote->last_sent_date, + 'due_date' => $quote->due_date, + 'is_deleted' => $quote->is_deleted, + 'footer' => $quote->invoice_footer, + 'public_notes' => $quote->public_notes, + 'private_notes' => $quote->private_notes, + 'terms' => $quote->terms, + 'tax_name1' => $quote->tax_name1, + 'tax_name2' => $quote->tax_name2, + 'tax_rate1' => $quote->tax_rate1, + 'tax_rate2' => $quote->tax_rate2, + 'custom_value1' => $quote->custom_value1, + 'custom_value2' => $quote->custom_value2, + 'next_send_date' => null, + 'amount' => $quote->amount, + 'balance' => $quote->balance, + 'partial' => $quote->partial, + 'partial_due_date' => $quote->partial_due_date, + 'created_at' => $quote->created_at ? $quote->created_at->toDateString() : null, + 'updated_at' => $quote->updated_at ? $quote->updated_at->toDateString() : null, + 'deleted_at' => $quote->deleted_at ? $quote->deleted_at->toDateString() : null, + ]; + } + + return $transformed; + } + + public function getPayments() + { + $transformed = []; + + $payments = Payment::where('account_id', $this->account->id) + ->withTrashed() + ->get(); + + foreach ($payments as $payment) { + $transformed[] = [ + 'id' => $payment->id, + 'invoices' => [ + ['invoice_id' => $payment->invoice_id, 'amount' => $payment->amount, 'refunded' => $payment->refunded], + ], + 'invoice_id' => $payment->invoice_id, + 'company_id' => $payment->account_id, + 'client_id' => $payment->client_id, + 'user_id' => $payment->user_id, + 'client_contact_id' => $payment->contact_id, + 'invitation_id' => $payment->invitation_id, + 'company_gateway_id' => $payment->account_gateway_id, + 'type_id' => $payment->payment_type_id, + 'status_id' => $payment->payment_status_id, + 'amount' => $payment->amount, + 'applied' => $payment->amount, + 'refunded' => $payment->refunded, + 'date' => $payment->payment_date, + 'transaction_reference' => $payment->transaction_reference, + 'payer_id' => $payment->payer_id, + 'is_deleted' => $payment->is_deleted, + 'updated_at' => $payment->updated_at ? $payment->updated_at->toDateString() : null, + 'created_at' => $payment->created_at ? $payment->created_at->toDateString() : null, + 'deleted_at' => $payment->deleted_at ? $payment->deleted_at->toDateString() : null, + ]; + } + + return $transformed; + } + + /** + * @return array + */ + private function getCredits() + { + $credits = Credit::where('account_id', $this->account->id)->where('balance', '>', '0')->whereIsDeleted(false) + ->withTrashed() + ->get(); + + $transformed = []; + + foreach ($credits as $credit) { + $transformed[] = [ + 'client_id' => $credit->client_id, + 'user_id' => $credit->user_id, + 'company_id' => $credit->account_id, + 'is_deleted' => $credit->is_deleted, + 'amount' => $credit->balance, + 'applied' => 0, + 'refunded' => 0, + 'date' => $credit->date, + 'created_at' => $credit->created_at ? $credit->created_at->toDateString() : null, + 'updated_at' => $credit->updated_at ? $credit->updated_at->toDateString() : null, + 'deleted_at' => $credit->deleted_at ? $credit->deleted_at->toDateString() : null, + ]; + } + + return $transformed; + } +} diff --git a/composer.json b/composer.json index 741afa4bec..28a0f32381 100644 --- a/composer.json +++ b/composer.json @@ -68,7 +68,9 @@ "webpatser/laravel-countries": "dev-master#75992ad", "websight/l5-google-cloud-storage": "dev-master", "wepay/php-sdk": "^0.2", - "wildbit/postmark-php": "^2.5" + "wildbit/postmark-php": "^2.5", + "ext-json": "*", + "ext-zip": "*" }, "require-dev": { "symfony/dom-crawler": "~3.1", diff --git a/resources/lang/en/texts.php b/resources/lang/en/texts.php index 44ef367361..2fd606456a 100644 --- a/resources/lang/en/texts.php +++ b/resources/lang/en/texts.php @@ -205,7 +205,6 @@ $LANG = array( 'registration_required' => 'Please sign up to email an invoice', 'confirmation_required' => 'Please confirm your email address, :link to resend the confirmation email.', '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', @@ -569,7 +568,7 @@ $LANG = array( 'hours' => 'Hours', 'task_details' => 'Task Details', 'duration' => 'Duration', - 'time_log'=> 'Time Log', + 'time_log' => 'Time Log', 'end_time' => 'End Time', 'end' => 'End', 'invoiced' => 'Invoiced', @@ -1809,7 +1808,7 @@ $LANG = array( 'industry_Transportation' => 'Transportation', 'industry_Travel & Luxury' => 'Travel & Luxury', 'industry_Other' => 'Other', - 'industry_Photography' =>'Photography', + 'industry_Photography' => 'Photography', 'view_client_portal' => 'View client portal', 'view_portal' => 'View Portal', @@ -1895,7 +1894,6 @@ $LANG = array( 'toggle_history' => 'Toggle History', 'unassigned' => 'Unassigned', 'task' => 'Task', - 'task_details'=>'Task Details', 'contact_name' => 'Contact Name', 'city_state_postal' => 'City/State/Postal', 'custom_field' => 'Custom Field', @@ -1984,37 +1982,37 @@ $LANG = array( 'authorization' => 'Authorization', 'signed' => 'Signed', - // BlueVine - 'bluevine_promo' => 'Get flexible business lines of credit and invoice factoring using BlueVine.', - 'bluevine_modal_label' => 'Sign up with BlueVine', - 'bluevine_modal_text' => '

Fast funding for your business. No paperwork.

+ // BlueVine + 'bluevine_promo' => 'Get flexible business lines of credit and invoice factoring using BlueVine.', + 'bluevine_modal_label' => 'Sign up with BlueVine', + 'bluevine_modal_text' => '

Fast funding for your business. No paperwork.

', - 'bluevine_create_account' => 'Create an account', - 'quote_types' => 'Get a quote for', - 'invoice_factoring' => 'Invoice factoring', - 'line_of_credit' => 'Line of credit', - 'fico_score' => 'Your FICO score', - 'business_inception' => 'Business Inception Date', - 'average_bank_balance' => 'Average bank account balance', - 'annual_revenue' => 'Annual revenue', - 'desired_credit_limit_factoring' => 'Desired invoice factoring limit', - 'desired_credit_limit_loc' => 'Desired line of credit limit', - 'desired_credit_limit' => 'Desired credit limit', - 'bluevine_credit_line_type_required' => 'You must choose at least one', - 'bluevine_field_required' => 'This field is required', - 'bluevine_unexpected_error' => 'An unexpected error occurred.', - 'bluevine_no_conditional_offer' => 'More information is required before getting a quote. Click continue below.', - 'bluevine_invoice_factoring' => 'Invoice Factoring', - 'bluevine_conditional_offer' => 'Conditional Offer', - 'bluevine_credit_line_amount' => 'Credit Line', - 'bluevine_advance_rate' => 'Advance Rate', - 'bluevine_weekly_discount_rate' => 'Weekly Discount Rate', - 'bluevine_minimum_fee_rate' => 'Minimum Fee', - 'bluevine_line_of_credit' => 'Line of Credit', - 'bluevine_interest_rate' => 'Interest Rate', - 'bluevine_weekly_draw_rate' => 'Weekly Draw Rate', - 'bluevine_continue' => 'Continue to BlueVine', - 'bluevine_completed' => 'BlueVine signup completed', + 'bluevine_create_account' => 'Create an account', + 'quote_types' => 'Get a quote for', + 'invoice_factoring' => 'Invoice factoring', + 'line_of_credit' => 'Line of credit', + 'fico_score' => 'Your FICO score', + 'business_inception' => 'Business Inception Date', + 'average_bank_balance' => 'Average bank account balance', + 'annual_revenue' => 'Annual revenue', + 'desired_credit_limit_factoring' => 'Desired invoice factoring limit', + 'desired_credit_limit_loc' => 'Desired line of credit limit', + 'desired_credit_limit' => 'Desired credit limit', + 'bluevine_credit_line_type_required' => 'You must choose at least one', + 'bluevine_field_required' => 'This field is required', + 'bluevine_unexpected_error' => 'An unexpected error occurred.', + 'bluevine_no_conditional_offer' => 'More information is required before getting a quote. Click continue below.', + 'bluevine_invoice_factoring' => 'Invoice Factoring', + 'bluevine_conditional_offer' => 'Conditional Offer', + 'bluevine_credit_line_amount' => 'Credit Line', + 'bluevine_advance_rate' => 'Advance Rate', + 'bluevine_weekly_discount_rate' => 'Weekly Discount Rate', + 'bluevine_minimum_fee_rate' => 'Minimum Fee', + 'bluevine_line_of_credit' => 'Line of Credit', + 'bluevine_interest_rate' => 'Interest Rate', + 'bluevine_weekly_draw_rate' => 'Weekly Draw Rate', + 'bluevine_continue' => 'Continue to BlueVine', + 'bluevine_completed' => 'BlueVine signup completed', 'vendor_name' => 'Vendor', 'entity_state' => 'State', @@ -2111,7 +2109,6 @@ $LANG = array( 'domain' => 'Domain', 'domain_help' => 'Used in the client portal and when sending emails.', 'domain_help_website' => 'Used when sending emails.', - 'preview' => 'Preview', 'import_invoices' => 'Import Invoices', 'new_report' => 'New Report', 'edit_report' => 'Edit Report', @@ -2147,22 +2144,20 @@ $LANG = array( 'sent_by' => 'Sent by :user', 'recipients' => 'Recipients', 'save_as_default' => 'Save as default', - 'template' => 'Template', 'start_of_week_help' => 'Used by date selectors', 'financial_year_start_help' => 'Used by date range selectors', 'reports_help' => 'Shift + Click to sort by multiple columns, Ctrl + Click to clear the grouping.', 'this_year' => 'This Year', - // Updated login screen - 'ninja_tagline' => 'Create. Send. Get Paid.', - 'login_or_existing' => 'Or login with a connected account.', - 'sign_up_now' => 'Sign Up Now', - 'not_a_member_yet' => 'Not a member yet?', - 'login_create_an_account' => 'Create an Account!', - 'client_login' => 'Client Login', + // Updated login screen + 'ninja_tagline' => 'Create. Send. Get Paid.', + 'login_or_existing' => 'Or login with a connected account.', + 'sign_up_now' => 'Sign Up Now', + 'not_a_member_yet' => 'Not a member yet?', + 'login_create_an_account' => 'Create an Account!', - // New Client Portal styling - 'invoice_from' => 'Invoices From:', + // New Client Portal styling + 'invoice_from' => 'Invoices From:', 'email_alias_message' => 'We require each company to have a unique email address.
Consider using an alias. ie, email+label@example.com', 'full_name' => 'Full Name', 'month_year' => 'MONTH/YEAR', @@ -2335,12 +2330,10 @@ $LANG = array( 'updated_recurring_expense' => 'Successfully updated recurring expense', 'created_recurring_expense' => 'Successfully created recurring expense', 'archived_recurring_expense' => 'Successfully archived recurring expense', - 'archived_recurring_expense' => 'Successfully archived recurring expense', 'restore_recurring_expense' => 'Restore Recurring Expense', 'restored_recurring_expense' => 'Successfully restored recurring expense', 'delete_recurring_expense' => 'Delete Recurring Expense', 'deleted_recurring_expense' => 'Successfully deleted project', - 'deleted_recurring_expense' => 'Successfully deleted project', 'view_recurring_expense' => 'View Recurring Expense', 'taxes_and_fees' => 'Taxes and fees', 'import_failed' => 'Import Failed', @@ -2483,7 +2476,7 @@ $LANG = array( 'tax1' => 'First Tax', 'tax2' => 'Second Tax', 'fee_help' => 'Gateway fees are the costs charged for access to the financial networks that handle the processing of online payments.', - 'format_export' => 'Exporting format', + 'format_export' => 'Exporting format', 'custom1' => 'First Custom', 'custom2' => 'Second Custom', 'contact_first_name' => 'Contact First Name', @@ -2918,8 +2911,6 @@ $LANG = array( 'send_notifications_for' => 'Send Notifications For', 'all_invoices' => 'All Invoices', 'my_invoices' => 'My Invoices', - 'mobile_refresh_warning' => 'If you\'re using the mobile app you may need to do a full refresh.', - 'enable_proposals_for_background' => 'To upload a background image :link to enable the proposals module.', 'payment_reference' => 'Payment Reference', 'maximum' => 'Maximum', 'sort' => 'Sort', @@ -3277,6 +3268,15 @@ $LANG = array( 'google_sign_up' => 'Google Sign Up', 'sign_up_with_google' => 'Sign Up With Google', 'long_press_multiselect' => 'Long-press Multiselect', + 'migrate_to_next_version' => 'Migrate to the next version of Invoice Ninja', + 'migrate_intro_text' => 'We\'ve been working on next version of Invoice Ninja. Click the button bellow to start the migration.', + 'start_the_migration' => 'Start the migration', + 'migration' => 'Migration', + 'welcome_to_the_new_version' => 'Welcome to the new version of Invoice Ninja', + 'next_step_data_download' => 'At the next step, we\'ll let you download your data for the migration.', + 'download_data' => 'Press button below to download the data.', + 'migration_import' => 'Awesome! Now you are ready to import your migration. Go to your new installation to import your data', + 'continue' => 'Continue', ); return $LANG; diff --git a/resources/views/accounts/management.blade.php b/resources/views/accounts/management.blade.php index 9bda2dc1e0..84f25f6998 100644 --- a/resources/views/accounts/management.blade.php +++ b/resources/views/accounts/management.blade.php @@ -238,6 +238,26 @@ +
+
+

{!! trans('texts.migrate_to_next_version') !!}

+
+
+ +
+
+ {!! trans('texts.migrate_intro_text') !!} +
+
+ + +
+
+ {!! Former::close() !!} @if (! Auth::user()->account->isNinjaOrLicenseAccount()) diff --git a/resources/views/migration/download.blade.php b/resources/views/migration/download.blade.php new file mode 100644 index 0000000000..71966fdbe8 --- /dev/null +++ b/resources/views/migration/download.blade.php @@ -0,0 +1,22 @@ +@extends('header') + +@section('content') + @parent + @include('accounts.nav', ['selected' => ACCOUNT_MANAGEMENT]) + +
+
+

{!! trans('texts.welcome_to_the_new_version') !!}

+
+
+

{!! trans('texts.download_data') !!}

+
+ {!! csrf_field() !!} + +
+
+ +
+@stop \ No newline at end of file diff --git a/resources/views/migration/import.blade.php b/resources/views/migration/import.blade.php new file mode 100644 index 0000000000..00e1eda41f --- /dev/null +++ b/resources/views/migration/import.blade.php @@ -0,0 +1,15 @@ +@extends('header') + +@section('content') + @parent + @include('accounts.nav', ['selected' => ACCOUNT_MANAGEMENT]) + +
+
+

{!! trans('texts.welcome_to_the_new_version') !!}

+
+
+

{!! trans('texts.migration_import') !!}

+
+
+@stop \ No newline at end of file diff --git a/resources/views/migration/start.blade.php b/resources/views/migration/start.blade.php new file mode 100644 index 0000000000..4fe0131d28 --- /dev/null +++ b/resources/views/migration/start.blade.php @@ -0,0 +1,19 @@ +@extends('header') + +@section('content') + @parent + @include('accounts.nav', ['selected' => ACCOUNT_MANAGEMENT]) + +
+
+

{!! trans('texts.welcome_to_the_new_version') !!}

+
+
+

{!! trans('texts.next_step_data_download') !!}

+
+ +
+ +@stop \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index db780da164..3e25c95c40 100644 --- a/routes/web.php +++ b/routes/web.php @@ -148,6 +148,13 @@ Route::group(['middleware' => ['lookup:user', 'auth:user']], function () { Route::get('settings/enable_two_factor', 'TwoFactorController@setupTwoFactor'); Route::post('settings/enable_two_factor', 'TwoFactorController@enableTwoFactor'); + Route::get('migration/start', 'Migration\StepsController@start'); + + Route::get('migration/download', 'Migration\StepsController@download'); + Route::post('migration/download', 'Migration\StepsController@handleDownload'); + + Route::get('migration/import', 'Migration\StepsController@import'); + Route::resource('clients', 'ClientController'); Route::get('api/clients', 'ClientController@getDatatable'); Route::get('api/activities/{client_id?}', 'ActivityController@getDatatable');