mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-05-24 02:14:21 -04:00
Merge pull request #10064 from turbo124/v5-develop
Fixes for validation of company import when migrating
This commit is contained in:
commit
01e49d20ad
@ -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";
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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']);
|
||||
|
@ -433,6 +433,8 @@ class Import implements ShouldQueue
|
||||
|
||||
$rules = (new UpdateCompanyRequest())->rules();
|
||||
|
||||
unset($rules['expense_mailbox']);
|
||||
|
||||
$validator = Validator::make($data, $rules);
|
||||
|
||||
if ($validator->fails()) {
|
||||
|
@ -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
|
||||
|
@ -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' => '',
|
||||
|
@ -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
|
||||
|
@ -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 = [];
|
||||
|
@ -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";
|
||||
|
Loading…
x
Reference in New Issue
Block a user