diff --git a/VERSION.txt b/VERSION.txt index 69dd5a4045a8..248ea8b88544 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -5.1.65 \ No newline at end of file +5.1.66 \ No newline at end of file diff --git a/app/Http/Controllers/ImportJsonController.php b/app/Http/Controllers/ImportJsonController.php new file mode 100644 index 000000000000..5a95fa23a813 --- /dev/null +++ b/app/Http/Controllers/ImportJsonController.php @@ -0,0 +1,64 @@ +user()->getCompany(), auth()->user()); + + return response()->json(['message' => 'Processing'], 200); + + } +} diff --git a/app/Http/Controllers/InvoiceController.php b/app/Http/Controllers/InvoiceController.php index b2ea9da7cac3..263fa992f5f5 100644 --- a/app/Http/Controllers/InvoiceController.php +++ b/app/Http/Controllers/InvoiceController.php @@ -845,13 +845,11 @@ class InvoiceController extends BaseController */ public function deliveryNote(ShowInvoiceRequest $request, Invoice $invoice) { + $file = $invoice->service()->getInvoiceDeliveryNote($invoice, $invoice->invitations->first()->contact); - try { - return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true); - } catch (\Exception $e) { - return response(['message' => 'Oops, something went wrong. Make sure you have symlink to storage/ in public/ directory.'], 500); - } + return response()->download($file, basename($file), ['Cache-Control:' => 'no-cache'])->deleteFileAfterSend(true); + } /** diff --git a/app/Jobs/Company/CompanyExport.php b/app/Jobs/Company/CompanyExport.php index 8fa94893d591..fd26f3a33ce6 100644 --- a/app/Jobs/Company/CompanyExport.php +++ b/app/Jobs/Company/CompanyExport.php @@ -212,7 +212,7 @@ class CompanyExport implements ShouldQueue $this->export_data['credit_invitations'] = CreditInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($credit){ - $credit = $this->transformArrayOfKeys($credit, ['company_id', 'user_id', 'client_contact_id', 'recurring_invoice_id']); + $credit = $this->transformArrayOfKeys($credit, ['company_id', 'user_id', 'client_contact_id', 'credit_id']); return $credit->makeVisible(['id']); @@ -220,9 +220,10 @@ class CompanyExport implements ShouldQueue $this->export_data['designs'] = $this->company->user_designs->makeHidden(['id'])->all(); - $this->export_data['documents'] = $this->company->documents->map(function ($document){ + $this->export_data['documents'] = $this->company->all_documents->map(function ($document){ - $document = $this->transformArrayOfKeys($document, ['user_id', 'assigned_user_id', 'company_id', 'project_id', 'vendor_id']); + $document = $this->transformArrayOfKeys($document, ['user_id', 'assigned_user_id', 'company_id', 'project_id', 'vendor_id','documentable_id']); + $document->hashed_id = $this->encodePrimaryKey($document->id); return $document->makeVisible(['id']); @@ -260,14 +261,18 @@ class CompanyExport implements ShouldQueue $invoice = $this->transformBasicEntities($invoice); $invoice = $this->transformArrayOfKeys($invoice, ['recurring_id','client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id']); - return $invoice->makeVisible(['id']); + return $invoice->makeVisible(['id', + 'private_notes', + 'user_id', + 'client_id', + 'company_id',]); })->all(); $this->export_data['invoice_invitations'] = InvoiceInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($invoice){ - $invoice = $this->transformArrayOfKeys($invoice, ['company_id', 'user_id', 'client_contact_id', 'recurring_invoice_id']); + $invoice = $this->transformArrayOfKeys($invoice, ['company_id', 'user_id', 'client_contact_id', 'invoice_id']); return $invoice->makeVisible(['id']); @@ -281,19 +286,14 @@ class CompanyExport implements ShouldQueue })->makeHidden(['id'])->all(); - $this->export_data['paymentables'] = $this->company->payments()->with('paymentables')->cursor()->map(function ($paymentable){ - - $paymentable = $this->transformArrayOfKeys($paymentable, ['payment_id','paymentable_id']); - - return $paymentable; - - })->all(); $this->export_data['payments'] = $this->company->payments->map(function ($payment){ $payment = $this->transformBasicEntities($payment); $payment = $this->transformArrayOfKeys($payment, ['client_id','project_id', 'vendor_id', 'client_contact_id', 'invitation_id', 'company_gateway_id']); + $payment->paymentables = $this->transformPaymentable($payment); + return $payment->makeVisible(['id']); })->all(); @@ -328,14 +328,14 @@ class CompanyExport implements ShouldQueue $this->export_data['quote_invitations'] = QuoteInvitation::where('company_id', $this->company->id)->withTrashed()->cursor()->map(function ($quote){ - $quote = $this->transformArrayOfKeys($quote, ['company_id', 'user_id', 'client_contact_id', 'recurring_invoice_id']); + $quote = $this->transformArrayOfKeys($quote, ['company_id', 'user_id', 'client_contact_id', 'quote_id']); - return $quote; + return $quote->makeVisible(['id']); })->all(); - $this->export_data['recurring_invoices'] = $this->company->recurring_invoices->map(function ($ri){ + $this->export_data['recurring_invoices'] = $this->company->recurring_invoices->makeVisible(['id'])->map(function ($ri){ $ri = $this->transformBasicEntities($ri); $ri = $this->transformArrayOfKeys($ri, ['client_id', 'vendor_id', 'project_id', 'design_id', 'subscription_id']); @@ -432,7 +432,7 @@ class CompanyExport implements ShouldQueue })->makeHidden(['id'])->all(); //write to tmp and email to owner(); - + $this->zipAndSend(); return true; @@ -441,7 +441,7 @@ class CompanyExport implements ShouldQueue private function transformBasicEntities($model) { - return $this->transformArrayOfKeys($model, ['id', 'user_id', 'assigned_user_id', 'company_id']); + return $this->transformArrayOfKeys($model, ['user_id', 'assigned_user_id', 'company_id']); } @@ -456,6 +456,24 @@ class CompanyExport implements ShouldQueue } + private function transformPaymentable($payment) + { + + $new_arr = []; + + foreach($payment->paymentables as $paymentable) + { + + $paymentable->payment_id = $this->encodePrimaryKey($paymentable->payment_id); + $paymentable->paymentable_id = $this->encodePrimaryKey($paymentable->paymentable_id); + + $new_arr[] = $paymentable; + } + + return $new_arr; + + } + private function zipAndSend() { diff --git a/app/Jobs/Company/CompanyImport.php b/app/Jobs/Company/CompanyImport.php index 3a718e579024..7ff1ccc2a627 100644 --- a/app/Jobs/Company/CompanyImport.php +++ b/app/Jobs/Company/CompanyImport.php @@ -80,13 +80,12 @@ class CompanyImport implements ShouldQueue // 'recurring_invoices', // 'quotes', // 'payments', + // 'subscriptions', // 'expenses', // 'tasks', // 'documents', - // 'subscriptions', // 'webhooks', // 'system_logs', - // 'paymentables', // 'company_ledger', // 'backups', ]; diff --git a/app/Models/Activity.php b/app/Models/Activity.php index 77bb73338326..7ebe6d890e90 100644 --- a/app/Models/Activity.php +++ b/app/Models/Activity.php @@ -103,6 +103,15 @@ class Activity extends StaticModel 'deleted_at' => 'timestamp', ]; + protected $appends = [ + 'hashed_id', + ]; + + public function getHashedIdAttribute() + { + return $this->encodePrimaryKey($this->id); + } + public function getEntityType() { return self::class; diff --git a/app/Models/Company.php b/app/Models/Company.php index e197b6de4da4..50096c00abe4 100644 --- a/app/Models/Company.php +++ b/app/Models/Company.php @@ -131,6 +131,11 @@ class Company extends BaseModel return $this->morphMany(Document::class, 'documentable'); } + public function all_documents() + { + return $this->HasMany(Document::class); + } + public function getEntityType() { return self::class; diff --git a/app/Models/Quote.php b/app/Models/Quote.php index 87f70d4a75c1..c7d3118dc76a 100644 --- a/app/Models/Quote.php +++ b/app/Models/Quote.php @@ -71,10 +71,6 @@ class Quote extends BaseModel 'custom_surcharge2', 'custom_surcharge3', 'custom_surcharge4', - // 'custom_surcharge_tax1', - // 'custom_surcharge_tax2', - // 'custom_surcharge_tax3', - // 'custom_surcharge_tax4', 'design_id', 'assigned_user_id', 'exchange_rate', diff --git a/config/ninja.php b/config/ninja.php index 68a57bab86b5..1c31e50de6a4 100644 --- a/config/ninja.php +++ b/config/ninja.php @@ -14,8 +14,8 @@ return [ 'require_https' => env('REQUIRE_HTTPS', true), 'app_url' => rtrim(env('APP_URL', ''), '/'), 'app_domain' => env('APP_DOMAIN', 'invoicing.co'), - 'app_version' => '5.1.65', - 'app_tag' => '5.1.65-release', + 'app_version' => '5.1.66', + 'app_tag' => '5.1.66-release', 'minimum_client_version' => '5.0.16', 'terms_version' => '1.0.1', 'api_secret' => env('API_SECRET', ''), diff --git a/database/migrations/2021_05_30_100933_make_documents_assigned_user_nullable.php b/database/migrations/2021_05_30_100933_make_documents_assigned_user_nullable.php new file mode 100644 index 000000000000..3135b0d5fc74 --- /dev/null +++ b/database/migrations/2021_05_30_100933_make_documents_assigned_user_nullable.php @@ -0,0 +1,43 @@ +unsignedInteger('assigned_user_id')->nullable()->change(); + }); + + Document::where('assigned_user_id', 0)->update(['assigned_user_id' => null]); + + if(config('ninja.db.multi_db_enabled')){ + foreach (MultiDB::$dbs as $db) { + Document::on($db)->where('assigned_user_id', 0)->update(['assigned_user_id' => null]); + } + } + else{ + Document::where('assigned_user_id', 0)->update(['assigned_user_id' => null]); + } + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + // + } +} diff --git a/routes/api.php b/routes/api.php index ea1477edd5a8..1ce7f9bc8ce3 100644 --- a/routes/api.php +++ b/routes/api.php @@ -84,6 +84,7 @@ Route::group(['middleware' => ['api_db', 'token_auth', 'locale'], 'prefix' => 'a Route::post('group_settings/bulk', 'GroupSettingController@bulk'); Route::post('import', 'ImportController@import')->name('import.import'); + Route::post('import_json', 'ImportJsonController@import')->name('import.import_json'); Route::post('preimport', 'ImportController@preimport')->name('import.preimport'); Route::resource('invoices', 'InvoiceController'); // name = (invoices. index / create / show / update / destroy / edit diff --git a/tests/Feature/Import/ImportCompanyTest.php b/tests/Feature/Import/ImportCompanyTest.php index ce60bcb08c6e..ae3b5d3ce750 100644 --- a/tests/Feature/Import/ImportCompanyTest.php +++ b/tests/Feature/Import/ImportCompanyTest.php @@ -12,30 +12,43 @@ namespace Tests\Feature\Import; use App\Jobs\Import\CSVImport; use App\Models\Account; +use App\Models\Activity; +use App\Models\Backup; use App\Models\Client; use App\Models\ClientContact; use App\Models\ClientGatewayToken; use App\Models\Company; use App\Models\CompanyGateway; +use App\Models\CompanyLedger; use App\Models\CompanyToken; use App\Models\CompanyUser; +use App\Models\Credit; +use App\Models\CreditInvitation; +use App\Models\Design; +use App\Models\Document; use App\Models\Expense; use App\Models\ExpenseCategory; use App\Models\GroupSetting; use App\Models\Invoice; +use App\Models\InvoiceInvitation; use App\Models\Payment; use App\Models\PaymentTerm; +use App\Models\Paymentable; use App\Models\Product; use App\Models\Project; +use App\Models\Quote; +use App\Models\QuoteInvitation; use App\Models\RecurringInvoice; use App\Models\RecurringInvoiceInvitation; use App\Models\Subscription; +use App\Models\Task; use App\Models\TaskStatus; use App\Models\TaxRate; use App\Models\User; use App\Models\Vendor; use App\Models\VendorContact; use App\Utils\Traits\MakesHash; +use Illuminate\Foundation\Testing\DatabaseTransactions; use Illuminate\Routing\Middleware\ThrottleRequests; use Illuminate\Support\Facades\Cache; use Illuminate\Support\Str; @@ -51,6 +64,7 @@ use Tests\TestCase; class ImportCompanyTest extends TestCase { use MakesHash; + use DatabaseTransactions; public $account; public $company; @@ -87,6 +101,13 @@ class ImportCompanyTest extends TestCase $this->backup_json_object = json_decode(file_get_contents($backup_json_file)); + Credit::all()->each(function($credit){ + $credit->forceDelete(); + }); + + CreditInvitation::all()->each(function($credit){ + $credit->forceDelete(); + }); } public function testBackupJsonRead() @@ -530,9 +551,9 @@ class ImportCompanyTest extends TestCase // Recurring Invoice Invitations $this->assertEquals(2, count($this->backup_json_object->recurring_invoice_invitations)); -nlog($this->backup_json_object->recurring_invoice_invitations); + $this->genericImport(RecurringInvoiceInvitation::class, - ['user_id', 'client_contact_id', 'company_id', 'id', 'hashed_id'], + ['user_id', 'client_contact_id', 'company_id', 'id', 'hashed_id', 'recurring_invoice_id'], [ ['users' => 'user_id'], ['recurring_invoices' => 'recurring_invoice_id'], @@ -545,13 +566,499 @@ nlog($this->backup_json_object->recurring_invoice_invitations); // Recurring Invoice Invitations +// Invoices + + $this->assertEquals(2, count($this->backup_json_object->invoices)); + + $this->genericImport(Invoice::class, + ['user_id', 'client_id', 'company_id', 'id', 'hashed_id', 'recurring_id','status'], + [ + ['users' => 'user_id'], + ['users' => 'assigned_user_id'], + ['recurring_invoices' => 'recurring_id'], + ['clients' => 'client_id'], + ['subscriptions' => 'subscription_id'], + ['projects' => 'project_id'], + ['vendors' => 'vendor_id'], + ], + 'invoices', + 'number'); + + $this->assertEquals(2, Invoice::count()); + + +// Invoices + +// Invoice Invitations + + $this->assertEquals(2, count($this->backup_json_object->invoice_invitations)); + + $this->genericImport(InvoiceInvitation::class, + ['user_id', 'client_contact_id', 'company_id', 'id', 'hashed_id', 'invoice_id'], + [ + ['users' => 'user_id'], + ['invoices' => 'invoice_id'], + ['client_contacts' => 'client_contact_id'], + ], + 'invoice_invitations', + 'key'); + + $this->assertEquals(2, InvoiceInvitation::count()); + +// Invoice Invitations + + +// Quotes + $this->assertEquals(2, count($this->backup_json_object->quotes)); + + $this->genericImport(Quote::class, + ['user_id', 'client_id', 'company_id', 'id', 'hashed_id', 'recurring_id','status'], + [ + ['users' => 'user_id'], + ['users' => 'assigned_user_id'], + ['recurring_invoices' => 'recurring_id'], + ['clients' => 'client_id'], + ['subscriptions' => 'subscription_id'], + ['projects' => 'project_id'], + ['vendors' => 'vendor_id'], + ], + 'quotes', + 'number'); + + $this->assertEquals(2, Quote::count()); + + +// Quotes + +// Quotes Invitations + + $this->assertEquals(2, count($this->backup_json_object->quote_invitations)); + + $this->genericImport(QuoteInvitation::class, + ['user_id', 'client_contact_id', 'company_id', 'id', 'hashed_id', 'quote_id'], + [ + ['users' => 'user_id'], + ['quotes' => 'quote_id'], + ['client_contacts' => 'client_contact_id'], + ], + 'quote_invitations', + 'key'); + + $this->assertEquals(2, QuoteInvitation::count()); + +// Quotes Invitations + +// Credits + $this->assertEquals(2, count($this->backup_json_object->credits)); + + $this->genericImport(Credit::class, + ['user_id', 'client_id', 'company_id', 'id', 'hashed_id', 'recurring_id','status'], + [ + ['users' => 'user_id'], + ['users' => 'assigned_user_id'], + ['recurring_invoices' => 'recurring_id'], + ['clients' => 'client_id'], + ['subscriptions' => 'subscription_id'], + ['projects' => 'project_id'], + ['vendors' => 'vendor_id'], + ], + 'credits', + 'number'); + + $this->assertEquals(2, Credit::count()); + + +// Credits + +// Credits Invitations + + $this->assertEquals(2, count($this->backup_json_object->credit_invitations)); + + $this->genericImport(CreditInvitation::class, + ['user_id', 'client_contact_id', 'company_id', 'id', 'hashed_id', 'credit_id'], + [ + ['users' => 'user_id'], + ['credits' => 'credit_id'], + ['client_contacts' => 'client_contact_id'], + ], + 'credit_invitations', + 'key'); + + $this->assertEquals(2, CreditInvitation::count()); + +// Credits Invitations + + +// Expenses + + $this->assertEquals(2, count($this->backup_json_object->expenses)); + + $this->genericImport(Expense::class, + ['assigned_user_id', 'user_id', 'client_id', 'company_id', 'id', 'hashed_id', 'project_id','vendor_id'], + [ + ['users' => 'user_id'], + ['users' => 'assigned_user_id'], + ['clients' => 'client_id'], + ['projects' => 'project_id'], + ['vendors' => 'vendor_id'], + ], + 'expenses', + 'number'); + + $this->assertEquals(2, Expense::count()); + +// Expenses + +// Tasks + + $this->assertEquals(3, count($this->backup_json_object->tasks)); + + $this->genericImport(Task::class, + ['assigned_user_id', 'user_id', 'client_id', 'company_id', 'id', 'hashed_id', 'invoice_id','project_id'], + [ + ['users' => 'user_id'], + ['users' => 'assigned_user_id'], + ['clients' => 'client_id'], + ['projects' => 'project_id'], + ['invoices' => 'invoice_id'], + ], + 'tasks', + 'number'); + + $this->assertEquals(3, Task::count()); + +// Tasks + +// Payments + + $this->assertEquals(2, count($this->backup_json_object->payments)); + + $this->genericImport(Payment::class, + ['assigned_user_id', 'user_id', 'client_id', 'company_id', 'id', 'hashed_id', 'client_contact_id','invitation_id','vendor_id','paymentables'], + [ + ['users' => 'user_id'], + ['users' => 'assigned_user_id'], + ['clients' => 'client_id'], + ['client_contacts' => 'client_contact_id'], + ['vendors' => 'vendor_id'], + ['invoice_invitations' => 'invitation_id'], + ['company_gateways' => 'company_gateway_id'], + ], + 'payments', + 'number'); + + $this->assertEquals(2, Payment::count()); + +// Payments + +// Paymentables + + $this->paymentablesImport(); + + $this->assertEquals(1, Paymentable::count()); + + +// Paymentables + + +// Activities + $activities = []; + + foreach($this->backup_json_object->activities as $activity) + { + $activity->account_id = $this->company->account_id; + $activities[] = $activity; + } + + $this->assertEquals(25, count($this->backup_json_object->activities)); + + $this->backup_json_object->activities = $activities; + + $this->genericImport(Activity::class, + [ + 'user_id', + 'company_id', + 'client_id', + 'client_contact_id', + 'project_id', + 'vendor_id', + 'payment_id', + 'invoice_id', + 'credit_id', + 'invitation_id', + 'task_id', + 'expense_id', + 'token_id', + 'quote_id', + 'subscription_id', + 'recurring_invoice_id', + 'hashed_id', + 'company_id', + ], + [ + ['users' => 'user_id'], + ['clients' => 'client_id'], + ['client_contacts' => 'client_contact_id'], + ['projects' => 'project_id'], + ['vendors' => 'vendor_id'], + ['payments' => 'payment_id'], + ['invoices' => 'invoice_id'], + ['credits' => 'credit_id'], + ['tasks' => 'task_id'], + ['expenses' => 'expense_id'], + ['quotes' => 'quote_id'], + ['subscriptions' => 'subscription_id'], + ['recurring_invoices' => 'recurring_invoice_id'], + ['invitations' => 'invitation_id'], + ], + 'activities', + 'created_at'); + + $this->assertEquals(25, Activity::count()); + +// Activities + +// Backup + + $this->assertEquals(25, count($this->backup_json_object->backups)); + + $this->genericImportWithoutCompany(Backup::class, + ['activity_id','hashed_id'], + [ + ['activities' => 'activity_id'], + ], + 'backups', + 'created_at'); + + $this->assertEquals(25, Backup::count()); + +// Backup + +// Company Ledger + $this->assertEquals(3, count($this->backup_json_object->company_ledger)); + + $this->genericImport(CompanyLedger::class, + ['company_id', 'user_id', 'client_id', 'activity_id', 'id','account_id'], + [ + ['users' => 'user_id'], + ['clients' => 'client_id'], + ['activities' => 'activity_id'], + ], + 'company_ledger', + 'created_at'); + + $this->assertEquals(3, CompanyLedger::count()); + +// Company Ledger + +// Designs + + $this->genericImport(Design::class, + ['company_id', 'user_id'], + [ + ['users' => 'user_id'], + ], + 'designs', + 'name'); + +// Designs + +// Documents + $this->assertEquals(2, count($this->backup_json_object->documents)); + + $this->documentsImport(); + + $this->assertEquals(2, Document::count()); + +// Documents } + private function documentsImport() + { + + foreach($this->backup_json_object->documents as $document) + { + + $new_document = new Document(); + $new_document->user_id = $this->transformId('users', $document->user_id); + $new_document->assigned_user_id = $this->transformId('users', $document->assigned_user_id); + $new_document->company_id = $this->company->id; + $new_document->project_id = $this->transformId('projects', $document->project_id); + $new_document->vendor_id = $this->transformId('vendors', $document->vendor_id); + $new_document->url = $document->url; + $new_document->preview = $document->preview; + $new_document->name = $document->name; + $new_document->type = $document->type; + $new_document->disk = $document->disk; + $new_document->hash = $document->hash; + $new_document->size = $document->size; + $new_document->width = $document->width; + $new_document->height = $document->height; + $new_document->is_default = $document->is_default; + $new_document->custom_value1 = $document->custom_value1; + $new_document->custom_value2 = $document->custom_value2; + $new_document->custom_value3 = $document->custom_value3; + $new_document->custom_value4 = $document->custom_value4; + $new_document->deleted_at = $document->deleted_at; + $new_document->documentable_id = $this->transformDocumentId($document->documentable_id, $document->documentable_type); + $new_document->documentable_type = $document->documentable_type; + + $new_document->save(['timestamps' => false]); + + } + } + + private function transformDocumentId($id, $type) + { + switch ($type) { + case Company::class: + return $this->company->id; + break; + case Client::class: + return $this->transformId('clients', $id); + break; + case ClientContact::class: + return $this->transformId('client_contacts', $id); + break; + case Credit::class: + return $this->transformId('credits', $id); + break; + case Expense::class: + return $this->transformId('expenses', $id); + break; + case 'invoices': + return $this->transformId('invoices', $id); + break; + case Payment::class: + return $this->transformId('payments', $id); + break; + case Product::class: + return $this->transformId('products', $id); + break; + case Quote::class: + return $this->transformId('quotes', $id); + break; + case RecurringInvoice::class: + return $this->transformId('recurring_invoices', $id); + break; + case Company::class: + return $this->transformId('clients', $id); + break; + + + default: + # code... + break; + } + } + + private function paymentablesImport() + { + + foreach($this->backup_json_object->payments as $payment) + { + + foreach($payment->paymentables as $paymentable_obj) + { + + $paymentable = new Paymentable(); + $paymentable->payment_id = $this->transformId('payments', $paymentable_obj->payment_id); + $paymentable->paymentable_type = $paymentable_obj->paymentable_type; + $paymentable->amount = $paymentable_obj->amount; + $paymentable->refunded = $paymentable_obj->refunded; + $paymentable->created_at = $paymentable_obj->created_at; + $paymentable->deleted_at = $paymentable_obj->deleted_at; + $paymentable->updated_at = $paymentable_obj->updated_at; + $paymentable->paymentable_id = $this->convertPaymentableId($paymentable_obj->paymentable_type, $paymentable_obj->paymentable_id); + $paymentable->paymentable_type = $paymentable_obj->paymentable_type; + $paymentable->save(['timestamps' => false]); + } + } + } + + private function convertPaymentableId($type, $id) + { + switch ($type) { + case 'invoices': + return $this->transformId('invoices', $id); + break; + case Credit::class: + return $this->transformId('credits', $id); + break; + case Payment::class: + return $this->transformId('payments', $id); + default: + # code... + break; + } + } + + private function genericNewClassImport($class, $unset, $transforms, $object_property) { $class::unguard(); + foreach($this->backup_json_object->{$object_property} as $obj) + { + /* Remove unwanted keys*/ + $obj_array = (array)$obj; + foreach($unset as $un){ + unset($obj_array[$un]); + } + + $activity_invitation_key = false; + + if($class instanceof Activity){ + + if(isset($obj->invitation_id)){ + + if(isset($obj->invoice_id)) + $activity_invitation_key = 'invoice_invitations'; + elseif(isset($obj->quote_id)) + $activity_invitation_key = 'quote_invitations'; + elseif($isset($obj->credit_id)) + $activity_invitation_key = 'credit_invitations'; + } + + } + + /* Transform old keys to new keys */ + foreach($transforms as $transform) + { + foreach($transform as $key => $value) + { + if($class instanceof Activity && $activity_invitation_key) + $key = $activity_invitation_key; + + $obj_array["{$value}"] = $this->transformId($key, $obj->{$value}); + } + } + + if($class instanceof CompanyGateway) { + $obj_array['config'] = encrypt($obj_array['config']); + } + + $new_obj = new $class(); + $new_obj->company_id = $this->company->id; + $new_obj->fill($obj_array); + + $new_obj->save(['timestamps' => false]); + + $this->ids["{$object_property}"]["{$obj->hashed_id}"] = $new_obj->id; + + } + + $class::reguard(); + + + } + + private function genericImportWithoutCompany($class, $unset, $transforms, $object_property, $match_key) + { + + $class::unguard(); + foreach($this->backup_json_object->{$object_property} as $obj) { /* Remove unwanted keys*/ @@ -569,25 +1076,32 @@ nlog($this->backup_json_object->recurring_invoice_invitations); } } - if($class instanceof CompanyGateway) { - $obj_array['config'] = encrypt($obj_array['config']); + /* New to convert product ids from old hashes to new hashes*/ + if($class instanceof Subscription){ + $obj_array['product_ids'] = $this->recordProductIds($obj_array['product_ids']); + $obj_array['recurring_product_ids'] = $this->recordProductIds($obj_array['recurring_product_ids']); } - $new_obj = new $class(); - $new_obj->company_id = $this->company->id; - $new_obj->fill($obj_array); + $new_obj = $class::firstOrNew( + [$match_key => $obj->{$match_key}], + $obj_array, + ); $new_obj->save(['timestamps' => false]); - $this->ids["{$object_property}"]["{$obj->hashed_id}"] = $new_obj->id; + if($new_obj instanceof CompanyLedger){ + + } + else + $this->ids["{$object_property}"]["{$obj->hashed_id}"] = $new_obj->id; } $class::reguard(); - } + private function genericImport($class, $unset, $transforms, $object_property, $match_key) { @@ -623,7 +1137,10 @@ nlog($this->backup_json_object->recurring_invoice_invitations); $new_obj->save(['timestamps' => false]); - $this->ids["{$object_property}"]["{$obj->hashed_id}"] = $new_obj->id; + if($new_obj instanceof CompanyLedger){ + } + else + $this->ids["{$object_property}"]["{$obj->hashed_id}"] = $new_obj->id; } @@ -656,7 +1173,7 @@ nlog($this->backup_json_object->recurring_invoice_invitations); } if (! array_key_exists("{$old}", $this->ids[$resource])) { - throw new \Exception("Missing resource key: {$old}"); + throw new \Exception("Missing {$resource} key: {$old}"); } return $this->ids[$resource]["{$old}"]; diff --git a/tests/Feature/Import/backup.zip b/tests/Feature/Import/backup.zip index fec0e85ceba8..66f5bfdc7e50 100644 Binary files a/tests/Feature/Import/backup.zip and b/tests/Feature/Import/backup.zip differ diff --git a/tests/Feature/UserTest.php b/tests/Feature/UserTest.php index 843e819f112d..07db7e2034ac 100644 --- a/tests/Feature/UserTest.php +++ b/tests/Feature/UserTest.php @@ -54,6 +54,10 @@ class UserTest extends TestCase ThrottleRequests::class, PasswordProtection::class ); + + // if (config('ninja.testvars.travis') !== false) { + // $this->markTestSkipped('Skip test for Travis'); + // } } public function testUserList() @@ -95,54 +99,58 @@ class UserTest extends TestCase $this->assertNotNull($arr['data']['company_user']); } - // public function testUserAttachAndDetach() - // { - // $this->withoutMiddleware(PasswordProtection::class); + public function testUserAttachAndDetach() + { - // $user = UserFactory::create($this->account->id); - // $user->first_name = 'Test'; - // $user->last_name = 'Palloni'; - // $user->email = $this->default_email; - // $user->save(); + $this->withoutMiddleware(PasswordProtection::class); - // $data = $user->toArray(); + $data = [ + 'first_name' => 'Test', + 'last_name' => 'Palloni', + 'email' => $this->default_email, + ]; - // $response = false; + $response = false; - // try { - // $response = $this->withHeaders([ - // 'X-API-SECRET' => config('ninja.api_secret'), - // 'X-API-TOKEN' => $this->token, - // 'X-API-PASSWORD' => 'ALongAndBriliantPassword', - // ])->post('/api/v1/users?include=company_user', $data); + try { + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + 'X-API-PASSWORD' => 'ALongAndBriliantPassword', + ])->post('/api/v1/users?include=company_user', $data); - // } catch (ValidationException $e) { - // $message = json_decode($e->validator->getMessageBag(), 1); - // nlog($message); - // var_dump($message); - // $this->assertNotNull($message); - // } + } catch (ValidationException $e) { + $message = json_decode($e->validator->getMessageBag(), 1); + nlog($message); + var_dump($message); + $this->assertNotNull($message); + } - // $response->assertStatus(200); + $response->assertStatus(200); - // // $this->assertNotNull($user->company_user); - // // $this->assertEquals($user->company_user->company_id, $this->company->id); + $arr = $response->json(); - // $response = $this->withHeaders([ - // 'X-API-SECRET' => config('ninja.api_secret'), - // 'X-API-TOKEN' => $this->token, - // 'X-API-PASSWORD' => 'ALongAndBriliantPassword', - // ])->delete('/api/v1/users/'.$this->encodePrimaryKey($user->id).'/detach_from_company?include=company_user'); + // $this->assertNotNull($user->company_user); + // $this->assertEquals($user->company_user->company_id, $this->company->id); - // $response->assertStatus(200); + $response = $this->withHeaders([ + 'X-API-SECRET' => config('ninja.api_secret'), + 'X-API-TOKEN' => $this->token, + 'X-API-PASSWORD' => 'ALongAndBriliantPassword', + ])->delete('/api/v1/users/'.$arr['data']['id'].'/detach_from_company?include=company_user'); - // $cu = CompanyUser::whereUserId($user->id)->whereCompanyId($this->company->id)->first(); - // $ct = CompanyToken::whereUserId($user->id)->whereCompanyId($this->company->id)->first(); + $response->assertStatus(200); - // $this->assertNull($cu); - // $this->assertNull($ct); - // $this->assertNotNull($user); - // } + $user_id = $this->decodePrimaryKey($arr['data']['id']); + + $cu = CompanyUser::whereUserId($user_id)->whereCompanyId($this->company->id)->first(); + $ct = CompanyToken::whereUserId($user_id)->whereCompanyId($this->company->id)->first(); + $user = User::find($user_id); + + $this->assertNull($cu); + $this->assertNull($ct); + $this->assertNotNull($user); + } public function testAttachUserToMultipleCompanies() { @@ -168,14 +176,12 @@ class UserTest extends TestCase $cu->save(); /*Create New Blank User and Attach to Company 2*/ - $new_user = UserFactory::create($this->account->id); - $new_user->first_name = 'Test'; - $new_user->last_name = 'Palloni'; - $new_user->email = $this->default_email; - $new_user->save(); - - $data = $new_user->toArray(); - + $data = [ + 'first_name' => 'Test', + 'last_name' => 'Palloni', + 'email' => $this->default_email, + ]; + $response = $this->withHeaders([ 'X-API-SECRET' => config('ninja.api_secret'), 'X-API-TOKEN' => $company_token->token, diff --git a/tests/Unit/SystemHealthTest.php b/tests/Unit/SystemHealthTest.php index 648962b4449c..9df0bcefba0d 100644 --- a/tests/Unit/SystemHealthTest.php +++ b/tests/Unit/SystemHealthTest.php @@ -34,9 +34,9 @@ class SystemHealthTest extends TestCase $this->assertTrue((bool) $results['system_health']); - $this->assertTrue($results['extensions'][0]['mysqli']); - $this->assertTrue($results['extensions'][1]['gd']); - $this->assertTrue($results['extensions'][2]['curl']); - $this->assertTrue($results['extensions'][3]['zip']); + // $this->assertTrue($results['extensions'][0]['mysqli']); + $this->assertTrue($results['extensions'][0]['gd']); + $this->assertTrue($results['extensions'][1]['curl']); + $this->assertTrue($results['extensions'][2]['zip']); } }