Merge pull request #10064 from turbo124/v5-develop

Fixes for validation of company import when migrating
This commit is contained in:
David Bomba 2024-10-02 11:22:37 +10:00 committed by GitHub
commit 01e49d20ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 139 additions and 175 deletions

View File

@ -1,143 +0,0 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Console\Commands;
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\Gateway;
use App\Models\GroupSetting;
use App\Models\Invoice;
use App\Models\InvoiceInvitation;
use App\Models\Payment;
use App\Models\Paymentable;
use App\Models\PaymentHash;
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\SystemLog;
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\Models\Webhook;
use Illuminate\Console\Command;
/**
* Class CheckDb.
*/
class CheckDb extends Command
{
protected $signature = 'ninja:check-db';
protected $description = 'Check MultiDB';
protected $log = '';
private $entities = [
Account::class,
Activity::class,
Backup::class,
Client::class,
ClientContact::class,
ClientGatewayToken::class,
Company::class,
CompanyGateway::class,
CompanyLedger::class,
CompanyToken::class,
CompanyUser::class,
Credit::class,
CreditInvitation::class,
Design::class,
Document::class,
Expense::class,
ExpenseCategory::class,
Gateway::class,
GroupSetting::class,
Invoice::class,
InvoiceInvitation::class,
Payment::class,
Paymentable::class,
PaymentHash::class,
Product::class,
Project::class,
Quote::class,
QuoteInvitation::class,
RecurringInvoice::class,
RecurringInvoiceInvitation::class,
Subscription::class,
SystemLog::class,
Task::class,
TaskStatus::class,
TaxRate::class,
User::class,
Vendor::class,
VendorContact::class,
WebHook::class,
];
public function handle()
{
$this->LogMessage('Checking - V5_DB1');
foreach ($this->entities as $entity) {
$count_db_1 = $entity::on('db-ninja-01')->count();
$count_db_2 = $entity::on('db-ninja-02a')->count();
$diff = $count_db_1 - $count_db_2;
if ($diff != 0) {
$this->logMessage("{$entity} DB1: {$count_db_1} - DB2: {$count_db_2} - diff = {$diff}");
}
}
$this->LogMessage('Checking - V5_DB2');
foreach ($this->entities as $entity) {
$count_db_1 = $entity::on('db-ninja-02')->count();
$count_db_2 = $entity::on('db-ninja-01a')->count();
$diff = $count_db_1 - $count_db_2;
if ($diff != 0) {
$this->logMessage("{$entity} DB1: {$count_db_1} - DB2: {$count_db_2} - diff = {$diff}");
}
}
}
private function logMessage($str)
{
$str = date('Y-m-d h:i:s').' '.$str;
$this->info($str);
$this->log .= $str."\n";
}
}

View File

@ -1,4 +1,13 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Http\Middleware;

View File

@ -1,4 +1,13 @@
<?php
/**
* Invoice Ninja (https://invoiceninja.com).
*
* @link https://github.com/invoiceninja/invoiceninja source repository
*
* @copyright Copyright (c) 2024. Invoice Ninja LLC (https://invoiceninja.com)
*
* @license https://www.elastic.co/licensing/elastic-license
*/
namespace App\Http\Middleware;
@ -14,7 +23,7 @@ class ThrottleRequestsWithPredis extends \Illuminate\Routing\Middleware\Throttle
*
* @var \Illuminate\Contracts\Redis\Factory
*/
protected $redis;
protected $redis; /** @phpstan-ignore-line */
/**
* The timestamp of the end of the current duration by key.
@ -38,9 +47,12 @@ class ThrottleRequestsWithPredis extends \Illuminate\Routing\Middleware\Throttle
/** @phpstan-ignore-next-line */
public function __construct(RateLimiter $limiter, Redis $redis)
{
parent::__construct($limiter);
/** @phpstan-ignore-next-line */
$this->redis = \Illuminate\Support\Facades\Redis::connection('sentinel-cache');
parent::__construct($limiter); /** @phpstan-ignore-line */
/** @phpstan-ignore-next-line */
$this->redis = \Illuminate\Support\Facades\Redis::connection('sentinel-cache'); /** @phpstan-ignore-line */
}
/**

View File

@ -52,6 +52,11 @@ class StoreProductRequest extends Request
$rules['stock_notification_threshold'] = 'sometimes|numeric';
$rules['stock_notification'] = 'sometimes|bool';
$rules['tax_rate1'] = 'bail|sometimes|numeric';
$rules['tax_rate2'] = 'bail|sometimes|numeric';
$rules['tax_rate3'] = 'bail|sometimes|numeric';
return $rules;
}
@ -67,6 +72,10 @@ class StoreProductRequest extends Request
$input['assigned_user_id'] = $this->decodePrimaryKey($input['assigned_user_id']);
}
$input['tax_name1'] = $input['tax_name1'] ?? '';
$input['tax_name2'] = $input['tax_name2'] ?? '';
$input['tax_name3'] = $input['tax_name3'] ?? '';
$this->replace($input);
}
}

View File

@ -38,9 +38,7 @@ class UpdateUserRequest extends Request
'password' => 'nullable|string|min:6',
];
if (isset($input['email'])) {
$rules['email'] = ['email', 'sometimes', new UniqueUserRule($this->user, $input['email'])];
}
$rules['email'] = ['email', 'sometimes', new UniqueUserRule($this->user, $input['email'])];
if (Ninja::isHosted() && $this->phone_has_changed && $this->phone && isset($this->phone)) {
$rules['phone'] = ['sometimes', 'bail', 'string', new HasValidPhoneNumber()];
@ -53,9 +51,11 @@ class UpdateUserRequest extends Request
{
$input = $this->all();
if (array_key_exists('email', $input)) {
if (isset($input['email']) && is_string($input['email']) && strlen($input['email']) > 2) {
$input['email'] = trim($input['email']);
}
elseif(isset($input['email']))
$input['email'] = false;
if (array_key_exists('first_name', $input)) {
$input['first_name'] = strip_tags($input['first_name']);

View File

@ -433,6 +433,8 @@ class Import implements ShouldQueue
$rules = (new UpdateCompanyRequest())->rules();
unset($rules['expense_mailbox']);
$validator = Validator::make($data, $rules);
if ($validator->fails()) {

View File

@ -55,9 +55,9 @@ use Laracasts\Presenter\PresentableTrait;
* @property string|null $referral_code
* @property int|null $created_at
* @property int|null $updated_at
* @property int $is_scheduler_running
* @property bool $is_scheduler_running
* @property int|null $trial_duration
* @property int $is_onboarding
* @property bool $is_onboarding
* @property object|null $onboarding
* @property bool $is_migrated
* @property string|null $platform

View File

@ -98,22 +98,6 @@ return [
'options' => [],
],
'db-ninja-01a' => [
'driver' => 'mysql',
'host' => env('DB_HOST1', env('DB_HOST', '127.0.0.1')),
'database' => env('DB_DATABASE2', env('DB_DATABASE', 'forge')),
'username' => env('DB_USERNAME2', env('DB_USERNAME', 'forge')),
'password' => env('DB_PASSWORD2', env('DB_PASSWORD', '')),
'port' => env('DB_PORT1', env('DB_PORT', '3306')),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'prefix_indexes' => true,
'strict' => env('DB_STRICT', false),
'engine' => 'InnoDB ROW_FORMAT=DYNAMIC',
'options' => [],
],
'db-ninja-02' => [
'driver' => 'mysql',
'host' => env('DB_HOST2', env('DB_HOST', '127.0.0.1')),
@ -130,13 +114,13 @@ return [
'options' => [],
],
'db-ninja-02a' => [
'db-ninja-03' => [
'driver' => 'mysql',
'host' => env('DB_HOST2', env('DB_HOST', '127.0.0.1')),
'database' => env('DB_DATABASE1', env('DB_DATABASE', 'forge')),
'username' => env('DB_USERNAME1', env('DB_USERNAME', 'forge')),
'password' => env('DB_PASSWORD1', env('DB_PASSWORD', '')),
'port' => env('DB_PORT2', env('DB_PORT', '3306')),
'host' => env('DB_HOST3', env('DB_HOST', '127.0.0.1')),
'database' => env('DB_DATABASE3', env('DB_DATABASE', 'forge')),
'username' => env('DB_USERNAME3', env('DB_USERNAME', 'forge')),
'password' => env('DB_PASSWORD3', env('DB_PASSWORD', '')),
'port' => env('DB_PORT3', env('DB_PORT', '3306')),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',

View File

@ -6,6 +6,7 @@ parameters:
level: 5
paths:
- app
- Modules
excludePaths:
analyseAndScan:
- 'vendor'
@ -16,6 +17,7 @@ parameters:
- 'app/DataMapper/Analytics/*'
- 'app/PaymentDrivers/Authorize/*'
- 'app/PaymentDrivers/AuthorizePaymentDriver.php'
- 'app/Http/Middleware/ThrottleRequestsWithPredis.php'
- 'app/Utils/Traits/*'
universalObjectCratesClasses:
- App\DataMapper\Tax\RuleInterface

View File

@ -53,6 +53,27 @@ class ProductTest extends TestCase
}
public function testRequiredFields()
{
$product = [
'cost' => 10,
'vendor_id' => $this->vendor->hashed_id
];
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->postJson('/api/v1/products', $product)
->assertStatus(200);
$arr = $response->json();
$p = Product::find($this->decodePrimaryKey($arr['data']['id']));
$this->assertNull($p->vendor_id);
}
public function testProductCostMigration()
{
$items = [];

View File

@ -109,6 +109,74 @@ class UserTest extends TestCase
}
public function testValidEmailUpdate()
{
$company_token = $this->mockAccount();
$user = $company_token->user;
$user->load('company_user');
$data = $user->toArray();
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $company_token->token,
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
])->putJson('/api/v1/users/'.$user->hashed_id.'?include=company_user', $data);
$response->assertStatus(200);
}
public function testNullEmail()
{
$company_token = $this->mockAccount();
$user = $company_token->user;
$user->load('company_user');
$data = $user->toArray();
$data['email'] = '';
unset($data['password']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $company_token->token,
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
])->putJson('/api/v1/users/'.$user->hashed_id.'?include=company_user', $data);
$response->assertStatus(422);
$data = $user->toArray();
unset($data['password']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $company_token->token,
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
])->putJson('/api/v1/users/'.$user->hashed_id.'?include=company_user', $data);
$response->assertStatus(200);
$data = $user->toArray();
$data['email'] = $this->faker->unique()->safeEmail();
unset($data['password']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $company_token->token,
'X-API-PASSWORD' => 'ALongAndBriliantPassword',
])->putJson('/api/v1/users/'.$user->hashed_id.'?include=company_user', $data);
$response->assertStatus(200);
$arr = $response->json();
$this->assertEquals($arr['data']['email'], $data['email']);
}
public function testUserLocale()
{
$this->user->language_id = "13";