Merge pull request #11184 from turbo124/v5-develop

v5.12.14
This commit is contained in:
David Bomba 2025-08-15 08:51:25 +10:00 committed by GitHub
commit 08332ed087
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 264 additions and 184 deletions

View File

@ -1 +1 @@
5.12.13
5.12.14

View File

@ -12,8 +12,9 @@
namespace App\DataMapper;
use App\Utils\Traits\MakesHash;
use stdClass;
use App\Utils\Ninja;
use App\Utils\Traits\MakesHash;
/**
* CompanySettings.
@ -931,7 +932,10 @@ class CompanySettings extends BaseSettings
{
$notification = new stdClass();
$notification->email = [];
if(Ninja::isSelfHost()) {
$notification->email = ['invoice_sent_all', 'payment_success_all', 'payment_manual_all'];
}
return $notification;
}

View File

@ -155,8 +155,10 @@ class LoginController extends BaseController
$user = $user->fresh();
}
nlog("LOGIN:: {$request->email} - {$user->account_id}");
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
$cu = $this->hydrateCompanyUser($user);
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
@ -307,7 +309,7 @@ class LoginController extends BaseController
Auth::login($existing_user, false);
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
$cu = $this->hydrateCompanyUser($existing_user);
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
@ -336,7 +338,7 @@ class LoginController extends BaseController
]);
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
$cu = $this->hydrateCompanyUser($user);
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
@ -385,7 +387,7 @@ class LoginController extends BaseController
$user->save();
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
$cu = $this->hydrateCompanyUser($user);
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
@ -398,11 +400,11 @@ class LoginController extends BaseController
return $this->timeConstrainedResponse($cu);
}
private function hydrateCompanyUser(): Builder
private function hydrateCompanyUser(User $user): Builder
{
/** @var \App\Models\User $user */
$user = auth()->user();
// /** @var \App\Models\User $user */
// $user = auth()->user();
/** @var Builder $cu */
$cu = CompanyUser::query()->where('user_id', $user->id);
@ -427,8 +429,6 @@ class LoginController extends BaseController
$truth->setCompany($set_company);
//21-03-2024
$cu->each(function ($cu) {
/** @var \App\Models\CompanyUser $cu */
if (CompanyToken::query()->where('company_id', $cu->company_id)->where('user_id', $cu->user_id)->where('is_system', true)->doesntExist()) {
@ -512,7 +512,7 @@ class LoginController extends BaseController
Auth::login($existing_user, false);
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
$cu = $this->hydrateCompanyUser($existing_user);
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
@ -527,19 +527,12 @@ class LoginController extends BaseController
return $this->timeConstrainedResponse($cu);
}
private function existingLoginUser($oauth_user_id, $provider)
private function existingLoginUser($user)
{
/** @var \App\Models\User $user */
$user = auth()->user();
$user->update([
'oauth_user_id' => $oauth_user_id,
'oauth_provider_id' => $provider,
]);
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
$cu = $this->hydrateCompanyUser($user);
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);
@ -598,7 +591,13 @@ class LoginController extends BaseController
Auth::login($existing_login_user, false);
return $this->existingLoginUser($google->harvestSubField($user), 'google');
$existing_login_user->update([
'oauth_user_id' => $google->harvestSubField($user),
'oauth_provider_id' => 'google',
]);
return $this->existingLoginUser($existing_login_user);
}
if (request()->has('create') && request()->input('create') == 'true') {
@ -635,16 +634,14 @@ class LoginController extends BaseController
return $account;
}
Auth::login($account->default_company->owner(), false);
/** @var \App\Models\User $user */
$user = auth()->user();
$user = $account->default_company->owner();
$user->email_verified_at = now();
$user->save();
Auth::login($user, false);
/** @var \App\Models\CompanyUser $cu */
$cu = $this->hydrateCompanyUser();
$cu = $this->hydrateCompanyUser($user);
if ($cu->count() == 0) {
return response()->json(['message' => 'User found, but not attached to any companies, please see your administrator'], 400);

View File

@ -199,7 +199,7 @@ class InvoiceTransformer extends BaseTransformer
$item->is_amount_discount = data_get($qb_item, 'DiscountAmount', 0) > 0 ? true : false;
$item->type_id = stripos(data_get($qb_item, 'ItemAccountRef.name') ?? '', 'Service') !== false ? '2' : '1';
$item->tax_id = $taxCodeRef == 'NON' ? (string)Product::PRODUCT_TYPE_EXEMPT : $item->type_id;
$item->tax_rate1 = (float)$taxCodeRef == 'NON' ? 0 : $tax_array[0];
$item->tax_rate1 = $taxCodeRef == 'NON' ? 0 : (float)$tax_array[0];
$item->tax_name1 = $taxCodeRef == 'NON' ? '' : $tax_array[1];
$items[] = (object)$item;
@ -215,7 +215,7 @@ class InvoiceTransformer extends BaseTransformer
$item->discount = 0;
$item->is_amount_discount = true;
$item->tax_rate1 = (float)$include_discount == 'true' ? $tax_array[0] : 0;
$item->tax_rate1 = $include_discount == 'true' ? (float)$tax_array[0] : 0;
$item->tax_name1 = $include_discount == 'true' ? $tax_array[1] : '';
$item->type_id = '1';

View File

@ -15,6 +15,7 @@ namespace App\Transformers;
use stdClass;
use App\Models\Task;
use App\Models\User;
use App\Utils\Ninja;
use App\Models\Quote;
use App\Models\Client;
use App\Models\Credit;
@ -157,7 +158,6 @@ class CompanyTransformer extends EntityTransformer
'matomo_id' => (string) $company->matomo_id ?: '',
'enabled_item_tax_rates' => (int) $company->enabled_item_tax_rates,
'client_can_register' => (bool) $company->client_can_register,
// 'is_large' => (bool) $company->is_large,
'is_large' => (bool) $this->isLarge($company),
'is_disabled' => (bool) $company->is_disabled,
'enable_shop_api' => (bool) $company->enable_shop_api,
@ -226,6 +226,7 @@ class CompanyTransformer extends EntityTransformer
'has_quickbooks_token' => $company->quickbooks ? true : false,
'is_quickbooks_token_active' => $company->quickbooks?->accessTokenKey ?? false,
'legal_entity_id' => $company->legal_entity_id ?? null,
'microsoft_client_id' => Ninja::isSelfHost() ? config('services.microsoft.client_id') : '',
];
}

94
composer.lock generated
View File

@ -5318,16 +5318,16 @@
},
{
"name": "laravel/framework",
"version": "v11.45.1",
"version": "v11.45.2",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "b09ba32795b8e71df10856a2694706663984a239"
"reference": "d134bf11e2208c0c5bd488cf19e612ca176b820a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/b09ba32795b8e71df10856a2694706663984a239",
"reference": "b09ba32795b8e71df10856a2694706663984a239",
"url": "https://api.github.com/repos/laravel/framework/zipball/d134bf11e2208c0c5bd488cf19e612ca176b820a",
"reference": "d134bf11e2208c0c5bd488cf19e612ca176b820a",
"shasum": ""
},
"require": {
@ -5435,7 +5435,7 @@
"league/flysystem-read-only": "^3.25.1",
"league/flysystem-sftp-v3": "^3.25.1",
"mockery/mockery": "^1.6.10",
"orchestra/testbench-core": "^9.13.2",
"orchestra/testbench-core": "^9.16.0",
"pda/pheanstalk": "^5.0.6",
"php-http/discovery": "^1.15",
"phpstan/phpstan": "^2.0",
@ -5529,7 +5529,7 @@
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"time": "2025-06-03T14:01:40+00:00"
"time": "2025-08-13T20:28:00+00:00"
},
{
"name": "laravel/octane",
@ -8388,16 +8388,16 @@
},
{
"name": "nikic/php-parser",
"version": "v5.6.0",
"version": "v5.6.1",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56"
"reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/221b0d0fdf1369c71047ad1d18bb5880017bbc56",
"reference": "221b0d0fdf1369c71047ad1d18bb5880017bbc56",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
"reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2",
"shasum": ""
},
"require": {
@ -8416,7 +8416,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.0-dev"
"dev-master": "5.x-dev"
}
},
"autoload": {
@ -8440,9 +8440,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.0"
"source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1"
},
"time": "2025-07-27T20:03:57+00:00"
"time": "2025-08-13T20:13:15+00:00"
},
{
"name": "nordigen/nordigen-php",
@ -8825,16 +8825,16 @@
},
{
"name": "open-telemetry/context",
"version": "1.3.0",
"version": "1.3.1",
"source": {
"type": "git",
"url": "https://github.com/opentelemetry-php/context.git",
"reference": "4d5d98f1d4311a55b8d07e3d4c06d2430b4e6efc"
"reference": "438f71812242db3f196fb4c717c6f92cbc819be6"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opentelemetry-php/context/zipball/4d5d98f1d4311a55b8d07e3d4c06d2430b4e6efc",
"reference": "4d5d98f1d4311a55b8d07e3d4c06d2430b4e6efc",
"url": "https://api.github.com/repos/opentelemetry-php/context/zipball/438f71812242db3f196fb4c717c6f92cbc819be6",
"reference": "438f71812242db3f196fb4c717c6f92cbc819be6",
"shasum": ""
},
"require": {
@ -8880,7 +8880,7 @@
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
"source": "https://github.com/open-telemetry/opentelemetry-php"
},
"time": "2025-08-04T03:25:06+00:00"
"time": "2025-08-13T01:12:00+00:00"
},
{
"name": "paragonie/constant_time_encoding",
@ -18067,16 +18067,16 @@
},
{
"name": "fidry/cpu-core-counter",
"version": "1.2.0",
"version": "1.3.0",
"source": {
"type": "git",
"url": "https://github.com/theofidry/cpu-core-counter.git",
"reference": "8520451a140d3f46ac33042715115e290cf5785f"
"reference": "db9508f7b1474469d9d3c53b86f817e344732678"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f",
"reference": "8520451a140d3f46ac33042715115e290cf5785f",
"url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678",
"reference": "db9508f7b1474469d9d3c53b86f817e344732678",
"shasum": ""
},
"require": {
@ -18086,10 +18086,10 @@
"fidry/makefile": "^0.2.0",
"fidry/php-cs-fixer-config": "^1.1.2",
"phpstan/extension-installer": "^1.2.0",
"phpstan/phpstan": "^1.9.2",
"phpstan/phpstan-deprecation-rules": "^1.0.0",
"phpstan/phpstan-phpunit": "^1.2.2",
"phpstan/phpstan-strict-rules": "^1.4.4",
"phpstan/phpstan": "^2.0",
"phpstan/phpstan-deprecation-rules": "^2.0.0",
"phpstan/phpstan-phpunit": "^2.0",
"phpstan/phpstan-strict-rules": "^2.0",
"phpunit/phpunit": "^8.5.31 || ^9.5.26",
"webmozarts/strict-phpunit": "^7.5"
},
@ -18116,7 +18116,7 @@
],
"support": {
"issues": "https://github.com/theofidry/cpu-core-counter/issues",
"source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0"
"source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0"
},
"funding": [
{
@ -18124,7 +18124,7 @@
"type": "github"
}
],
"time": "2024-08-06T10:04:20+00:00"
"time": "2025-08-14T07:29:31+00:00"
},
{
"name": "filp/whoops",
@ -18199,16 +18199,16 @@
},
{
"name": "friendsofphp/php-cs-fixer",
"version": "v3.85.1",
"version": "v3.86.0",
"source": {
"type": "git",
"url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git",
"reference": "2fb6d7f6c3398dca5786a1635b27405d73a417ba"
"reference": "4a952bd19dc97879b0620f495552ef09b55f7d36"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/2fb6d7f6c3398dca5786a1635b27405d73a417ba",
"reference": "2fb6d7f6c3398dca5786a1635b27405d73a417ba",
"url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4a952bd19dc97879b0620f495552ef09b55f7d36",
"reference": "4a952bd19dc97879b0620f495552ef09b55f7d36",
"shasum": ""
},
"require": {
@ -18292,7 +18292,7 @@
],
"support": {
"issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues",
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.85.1"
"source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.86.0"
},
"funding": [
{
@ -18300,7 +18300,7 @@
"type": "github"
}
],
"time": "2025-07-29T22:22:50+00:00"
"time": "2025-08-13T22:36:21+00:00"
},
{
"name": "hamcrest/hamcrest-php",
@ -20720,23 +20720,23 @@
},
{
"name": "sebastian/recursion-context",
"version": "6.0.2",
"version": "6.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
"reference": "694d156164372abbd149a4b85ccda2e4670c0e16"
"reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16",
"reference": "694d156164372abbd149a4b85ccda2e4670c0e16",
"url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/f6458abbf32a6c8174f8f26261475dc133b3d9dc",
"reference": "f6458abbf32a6c8174f8f26261475dc133b3d9dc",
"shasum": ""
},
"require": {
"php": ">=8.2"
},
"require-dev": {
"phpunit/phpunit": "^11.0"
"phpunit/phpunit": "^11.3"
},
"type": "library",
"extra": {
@ -20772,15 +20772,27 @@
"support": {
"issues": "https://github.com/sebastianbergmann/recursion-context/issues",
"security": "https://github.com/sebastianbergmann/recursion-context/security/policy",
"source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2"
"source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.3"
},
"funding": [
{
"url": "https://github.com/sebastianbergmann",
"type": "github"
},
{
"url": "https://liberapay.com/sebastianbergmann",
"type": "liberapay"
},
{
"url": "https://thanks.dev/u/gh/sebastianbergmann",
"type": "thanks_dev"
},
{
"url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context",
"type": "tidelift"
}
],
"time": "2024-07-03T05:10:34+00:00"
"time": "2025-08-13T04:42:22+00:00"
},
{
"name": "sebastian/type",

View File

@ -17,8 +17,8 @@ return [
'require_https' => env('REQUIRE_HTTPS', true),
'app_url' => rtrim(env('APP_URL', ''), '/'),
'app_domain' => env('APP_DOMAIN', 'invoicing.co'),
'app_version' => env('APP_VERSION', '5.12.13'),
'app_tag' => env('APP_TAG', '5.12.13'),
'app_version' => env('APP_VERSION', '5.12.14'),
'app_tag' => env('APP_TAG', '5.12.14'),
'minimum_client_version' => '5.0.16',
'terms_version' => '1.0.1',
'api_secret' => env('API_SECRET', false),

View File

@ -53,7 +53,7 @@ return [
],
'microsoft' => [
'client_id' => env('MICROSOFT_CLIENT_ID'),
'client_id' => env('MICROSOFT_CLIENT_ID',''),
'client_secret' => env('MICROSOFT_CLIENT_SECRET'),
'redirect' => env('MICROSOFT_REDIRECT_URI'),
],

View File

@ -5614,6 +5614,7 @@ $lang = array(
'include_project_tasks_help' => 'Also invoice tasks that are part of a project',
'tax_nexus' => 'Tax Nexus',
'tax_period_report' => 'Tax Period Report',
'creator' => 'Created by',
);
return $lang;

View File

@ -21,6 +21,7 @@ parameters:
- 'app/Http/Middleware/ThrottleRequestsWithPredis.php'
- 'app/Utils/Traits/*'
- 'Modules/Accounting/*'
- 'tests/*'
universalObjectCratesClasses:
- App\DataMapper\Tax\RuleInterface
- App\DataMapper\FeesAndLimits

View File

@ -22,16 +22,16 @@ use Tests\TestCase;
*/
class PeppolApiTest extends TestCase
{
use DatabaseTransactions;
// use DatabaseTransactions;
use MockAccountData;
protected function setUp(): void
{
parent::setUp();
if (!config('ninja.storecove_api_key')) {
// if (!config('ninja.storecove_api_key')) {
$this->markTestSkipped('Storecove API key not set');
}
// }
$this->makeTestData();
@ -49,7 +49,7 @@ class PeppolApiTest extends TestCase
config(['ninja.environment' => 'selfhost']);
/**
* @var \App\Models\CompanyUser $user
* @var \App\Models\User $user
*/
$user = $this->user;

View File

@ -23,6 +23,7 @@ use App\DataMapper\Tax\TaxModel;
use App\DataMapper\ClientSettings;
use App\DataMapper\CompanySettings;
use App\Factory\CompanyUserFactory;
use App\Repositories\InvoiceRepository;
use InvoiceNinja\EInvoice\EInvoice;
use InvoiceNinja\EInvoice\Symfony\Encode;
use App\Services\EDocument\Standards\Peppol;
@ -41,7 +42,7 @@ use InvoiceNinja\EInvoice\Models\FatturaPA\FatturaElettronicaHeaderType\FatturaE
class PeppolTest extends TestCase
{
use DatabaseTransactions;
// use DatabaseTransactions;
use MockAccountData;
protected int $iterations = 10;
@ -245,6 +246,8 @@ class PeppolTest extends TestCase
$ii = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$ii = $repo->save([], $ii);
$this->assertEquals(floatval(11898.81), $ii->amount);
$company = $entity_data['company'];
@ -302,6 +305,9 @@ class PeppolTest extends TestCase
$invoice->number = null;
$invoice->save();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$data = [
'entity' => 'invoices',
'entity_id' => $invoice->hashed_id
@ -511,6 +517,11 @@ class PeppolTest extends TestCase
];
$invoice->save();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$company = $entity_data['company'];
$settings = $company->settings;
@ -628,6 +639,9 @@ class PeppolTest extends TestCase
$invoice = $data['invoice'];
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->e_invoice = [
'Invoice' => [
'InvoicePeriod' => [
@ -671,6 +685,10 @@ class PeppolTest extends TestCase
$invoice = $data['invoice'];
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->e_invoice = [
'Invoice' => [
'InvoicePeriod' => [
@ -721,6 +739,9 @@ class PeppolTest extends TestCase
$invoice = $data['invoice'];
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$storecove = new Storecove();
$p = new Peppol($invoice);
$p->run();
@ -851,6 +872,10 @@ class PeppolTest extends TestCase
$invoice = $invoice->calc()->getInvoice();
$invoice->service()->markSent()->save();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$this->assertEquals(100, $invoice->amount);
$peppol = new Peppol($invoice);
@ -988,6 +1013,9 @@ class PeppolTest extends TestCase
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->service()->markSent()->save();
@ -1117,6 +1145,10 @@ class PeppolTest extends TestCase
]);
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->service()->markSent()->save();
$this->assertEquals(113.05, $invoice->amount);
@ -1250,6 +1282,10 @@ class PeppolTest extends TestCase
]);
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->service()->markSent()->save();
$this->assertEquals(96.39, $invoice->amount);
@ -1402,6 +1438,10 @@ class PeppolTest extends TestCase
]);
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->service()->markSent()->save();
$this->assertEquals(107.10, $invoice->amount);
@ -1553,6 +1593,11 @@ class PeppolTest extends TestCase
]);
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->service()->markSent()->save();
$this->assertEquals(107.1, $invoice->amount);
@ -1702,6 +1747,10 @@ class PeppolTest extends TestCase
]);
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->service()->markSent()->save();
$this->assertEquals(113.05, $invoice->amount);
@ -1843,6 +1892,10 @@ class PeppolTest extends TestCase
]);
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->service()->markSent()->save();
$this->assertEquals(119, $invoice->amount);
@ -1965,6 +2018,10 @@ class PeppolTest extends TestCase
]);
$invoice = $invoice->calc()->getInvoice();
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->service()->markSent()->save();
$this->assertEquals(100, $invoice->amount);
@ -2063,6 +2120,10 @@ class PeppolTest extends TestCase
'date' => now()->format('Y-m-d')
]);
$repo = new InvoiceRepository();
$invoice = $repo->save([], $invoice);
$invoice->service()->markSent()->save();
$peppol = new Peppol($invoice);
@ -2096,7 +2157,4 @@ class PeppolTest extends TestCase
}
}

View File

@ -54,7 +54,7 @@ class ReportCsvGenerationTest extends TestCase
$this->withoutExceptionHandling();
// Invoice::withTrashed()->cursor()->each(function ($i) { $i->forceDelete();});
config(['queue.default' => 'sync']);
$this->buildData();
@ -272,13 +272,12 @@ class ReportCsvGenerationTest extends TestCase
public function testContactProps()
{
Invoice::factory()->count(5)->create(
[
Invoice::factory()->count(5)->create([
'client_id' => $this->client->id,
'company_id' => $this->company->id,
'user_id' => $this->user->id
]
);
]);
$data = [
'date_range' => 'all',
@ -328,7 +327,7 @@ $this->account->forceDelete();
private function poll($hash)
{
$response = Http::retry(100, 400, throw: false)
$response = Http::retry(100, 200, throw: false)
->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,

View File

@ -38,7 +38,8 @@ class QuickbooksExportTest extends TestCase
{
parent::setUp();
if(config('ninja.is_travis') || !config('services.quickbooks.client_id')){
if(config('ninja.testvars.travis') || !config('services.quickbooks.client_id')){
$this->markTestSkipped('No Quickbooks Client ID found');
}

View File

@ -45,7 +45,6 @@ class QuickbooksMappingTest extends TestCase
$this->markTestSkipped('Skip test for GH Actions');
}
$this->qb_data = json_decode(file_get_contents($this->backup_file), true);
$this->makeTestData();
@ -101,6 +100,8 @@ class QuickbooksMappingTest extends TestCase
Invoice::where('company_id', $this->company->id)->cursor()->each(function ($invoice) use ($qb_invoices) {
$qb_invoice = $qb_invoices->where('Id', $invoice->sync->qb_id)->first();
nlog($qb_invoice);
nlog($invoice->toArray());
if(!$qb_invoice) {
nlog("Borked trying to find invoice {$invoice->sync->qb_id} in qb_invoices");
}
@ -110,6 +111,11 @@ class QuickbooksMappingTest extends TestCase
$total_amount = $qb_invoice['TotalAmt'];
$total_balance = $qb_invoice['Balance'];
nlog($total_amount);
nlog($invoice->amount);
nlog($total_balance);
nlog($invoice->balance);
$delta_amount = abs(round($total_amount - $invoice->amount,2));
$delta_balance = abs(round($total_balance - $invoice->balance,2));

View File

@ -41,13 +41,14 @@ class QuickbooksTest extends TestCase
{
parent::setUp();
if (config('ninja.testvars.travis') !== false) {
$this->markTestSkipped('Skip test for GH Actions');
}
elseif(Company::whereNotNull('quickbooks')->count() == 0){
$this->markTestSkipped('No need to run this test on Travis');
}
// if (config('ninja.testvars.travis') !== false) {
// $this->markTestSkipped('Skip test for GH Actions');
// }
// elseif(Company::whereNotNull('quickbooks')->count() == 0){
// $this->markTestSkipped('No need to run this test on Travis');
// }
$this->faker = \Faker\Factory::create();
}

View File

@ -32,6 +32,7 @@ class PlanTest extends TestCase
use DatabaseTransactions;
use MockAccountData;
protected $faker;
protected function setUp(): void
{
parent::setUp();
@ -89,24 +90,24 @@ class PlanTest extends TestCase
$this->assertEquals($date->addMonthNoOverflow()->startOfDay(), $next_date->startOfDay());
}
public function testLicense()
{
$this->markTestSkipped();
// public function testLicense()
// {
// $this->markTestSkipped();
$license = new License();
$license->license_key = "1234";
$license->product_id = "3";
$license->email = 'test@gmail.com';
$license->is_claimed = 1;
$license->save();
// $license = new License();
// $license->license_key = "1234";
// $license->product_id = "3";
// $license->email = 'test@gmail.com';
// $license->is_claimed = 1;
// $license->save();
$license->fresh();
// $license->fresh();
$response = $this->get("/claim_license?license_key=1234&product_id=3")
->assertStatus(200);
// $response = $this->get("/claim_license?license_key=1234&product_id=3")
// ->assertStatus(200);
$response = $this->get("/claim_license?license_key=12345&product_id=3")
->assertStatus(400);
// $response = $this->get("/claim_license?license_key=12345&product_id=3")
// ->assertStatus(400);
}
// }
}

View File

@ -31,12 +31,13 @@ use Tests\TestCase;
*/
class MultiDBUserTest extends TestCase
{
protected $token;
protected $company_token;
protected function setUp(): void
{
parent::setUp();
// $this->withoutExceptionHandling();
if (! config('ninja.db.multi_db_enabled')) {
$this->markTestSkipped('Multi DB not enabled - skipping');
}
@ -133,7 +134,8 @@ class MultiDBUserTest extends TestCase
$this->token = \Illuminate\Support\Str::random(40);
$this->company_token = CompanyToken::on('db-ninja-01')->create([
/** @var CompanyToken $company_token */
$company_token = CompanyToken::on('db-ninja-01')->create([
'user_id' => $user->id,
'company_id' => $coco->id,
'account_id' => $account->id,
@ -141,6 +143,7 @@ class MultiDBUserTest extends TestCase
'token' => $this->token,
]);
$this->company_token = $company_token;
User::unguard(false);
}
@ -183,14 +186,6 @@ class MultiDBUserTest extends TestCase
$this->assertFalse(MultiDB::userFindAndSetDb('bademail@example.com'));
}
/*
* This is what you do when you demand 100% code coverage :/
*/
public function test_set_db_invokes()
{
$this->expectNotToPerformAssertions(MultiDB::setDB('db-ninja-01'));
}
public function test_cross_db_user_linking_fails_appropriately()
{
//$this->withoutExceptionHandling();
@ -219,65 +214,55 @@ class MultiDBUserTest extends TestCase
}
// public function test_cross_db_user_linking_succeeds_appropriately()
// {
// $data = [
// 'first_name' => 'hey',
// 'last_name' => 'you',
// 'email' => 'db1@example.com',
// 'company_user' => [
// 'is_admin' => false,
// 'is_owner' => false,
// 'permissions' => 'create_client,create_invoice',
// ],
// ];
// 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) {
// \Log::error('in the validator');
// $message = json_decode($e->validator->getMessageBag(), 1);
// \Log::error($message);
// $this->assertNotNull($message);
// }
// if ($response) {
// $response->assertStatus(200);
// }
// }
protected function tearDown(): void
{
parent::tearDown();
$u = User::on('db-ninja-01')->where('email', 'db1@example.com')->first();
if ($u) {
$u->account->delete();
try {
// Clean up database records before calling parent::tearDown()
$this->cleanupTestData();
} catch (\Exception $e) {
// Log error but don't fail teardown
error_log("Error during test cleanup: " . $e->getMessage());
}
parent::tearDown();
}
private function cleanupTestData(): void
{
// Only proceed if we have database connections available
if (!app()->bound('db') || !config('database.connections.db-ninja-01')) {
return;
}
try {
// Clean up db-ninja-01
if (\DB::connection('db-ninja-01')->getPdo()) {
$u = User::on('db-ninja-01')->where('email', 'db1@example.com')->first();
if ($u && $u->account) {
$u->account->delete();
}
$u = User::on('db-ninja-01')->where('email', 'db2@example.com')->first();
if ($u) {
if ($u && $u->account) {
$u->account->delete();
}
}
// Clean up db-ninja-02
if (\DB::connection('db-ninja-02')->getPdo()) {
$u = User::on('db-ninja-02')->where('email', 'db1@example.com')->first();
if ($u) {
if ($u && $u->account) {
$u->account->delete();
}
$u = User::on('db-ninja-02')->where('email', 'db2@example.com')->first();
if ($u) {
if ($u && $u->account) {
$u->account->delete();
}
}
} catch (\Exception $e) {
// Log error but don't fail cleanup
error_log("Error during database cleanup: " . $e->getMessage());
}
}
}

View File

@ -106,9 +106,12 @@ class UniqueEmailTest extends TestCase
protected function tearDown(): void
{
parent::tearDown();
DB::connection('db-ninja-01')->table('users')->delete();
DB::connection('db-ninja-02')->table('users')->delete();
parent::tearDown();
}
}

View File

@ -76,6 +76,10 @@ class PdfServiceTest extends TestCase
$this->makeTestData();
if (config('ninja.testvars.travis')) {
$this->markTestSkipped();
}
$this->fake_email = $this->faker->email();
}

View File

@ -24,7 +24,7 @@ use Illuminate\Foundation\Testing\DatabaseTransactions;
class CloneQuoteToInvoiceFactoryTest extends TestCase
{
use MockAccountData;
use DatabaseTransactions;
// use DatabaseTransactions;
protected function setUp(): void
{

View File

@ -34,7 +34,7 @@ use Illuminate\Foundation\Testing\DatabaseTransactions;
class EntityTest extends TestCase
{
use MockAccountData;
// use DatabaseTransactions;
use DatabaseTransactions;
public $invoice;

View File

@ -22,7 +22,7 @@ use Tests\TestCase;
class InvitationTest extends TestCase
{
use MockAccountData;
use DatabaseTransactions;
// use DatabaseTransactions;
use MakesHash;
protected function setUp(): void
@ -57,10 +57,13 @@ class InvitationTest extends TestCase
$response = null;
$data = $this->invoice->toArray();
unset($data['hashed_id']);
$response = $this->withHeaders([
'X-API-SECRET' => config('ninja.api_secret'),
'X-API-TOKEN' => $this->token,
])->putJson('/api/v1/invoices/'.$this->encodePrimaryKey($this->invoice->id), $this->invoice->toArray());
])->putJson('/api/v1/invoices/'.$this->invoice->hashed_id, $this->invoice->toArray());
$response->assertStatus(200);

View File

@ -26,7 +26,7 @@ use Tests\TestCase;
class InvoiceMarkPaidTest extends TestCase
{
use MockAccountData;
use DatabaseTransactions;
// use DatabaseTransactions;
public $invoice;
@ -82,7 +82,6 @@ class InvoiceMarkPaidTest extends TestCase
$response->assertStatus(200);
$this->assertEquals(0, $response->json('data.balance'));
$this->assertEquals(10, $response->json('data.paid_to_date'));
$this->assertEquals(4, $response->json('data.status_id'));
@ -94,6 +93,8 @@ class InvoiceMarkPaidTest extends TestCase
$this->assertEquals(4, $i->status_id);
$c->forceDelete();
}
@ -116,6 +117,7 @@ class InvoiceMarkPaidTest extends TestCase
$line_items[] = $item;
/** @var \App\Models\Invoice $i */
$i = Invoice::factory()->create([
'discount' => 0,
'tax_name1' => '',
@ -158,6 +160,7 @@ class InvoiceMarkPaidTest extends TestCase
$this->assertEquals(4, $i->status_id);
$c->forceDelete();
}
}

View File

@ -68,9 +68,9 @@ class TaxConfigTest extends TestCase
// $this->assertEquals('CA', USStates::getState('90210'));
$this->bootApi($client);
$this->tp->updateClientTaxData();
$this->assertNotNull($client);
}
}