diff --git a/app/Helpers/Helper.php b/app/Helpers/Helper.php index 3a06fea177..9f89d9db8f 100644 --- a/app/Helpers/Helper.php +++ b/app/Helpers/Helper.php @@ -1701,6 +1701,8 @@ class Helper return []; } + $floater = (bool) Setting::getSettings()->null_company_is_floater; + foreach ($locations as $location) { // in case of an update of a single location, use the newly requested company_id if ($new_company_id) { @@ -1756,8 +1758,12 @@ class Helper // the correct mismatch signal. if ($item instanceof User) { $isMismatch = ! $item->canReceiveFromCompany((int) $location_company); + } elseif ($item->company_id == $location_company) { + $isMismatch = false; + } elseif (is_null($item->company_id) || is_null($location_company)) { + $isMismatch = ! $floater; } else { - $isMismatch = ($item->company_id != $location_company); + $isMismatch = true; } if ($isMismatch) { diff --git a/tests/Feature/Console/TestLocationsFmcsTest.php b/tests/Feature/Console/TestLocationsFmcsTest.php new file mode 100644 index 0000000000..250ed21f6f --- /dev/null +++ b/tests/Feature/Console/TestLocationsFmcsTest.php @@ -0,0 +1,190 @@ +create(array_merge([ + 'location_id' => $location->id, + 'rtd_location_id' => $location->id, + ], $attrs)); + } + + public function test_item_at_location_with_same_company_is_not_flagged() + { + $company = Company::factory()->create(); + $location = Location::factory()->for($company)->create(); + $asset = $this->assetAt($location, ['company_id' => $company->id]); + + $this->settings->enableMultipleFullCompanySupport(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertNotContains($asset->id, $this->mismatchedIds($result)); + } + + public function test_item_at_location_with_different_company_is_flagged() + { + [$companyA, $companyB] = Company::factory()->count(2)->create(); + $location = Location::factory()->for($companyA)->create(); + $asset = $this->assetAt($location, ['company_id' => $companyB->id]); + + $this->settings->enableMultipleFullCompanySupport(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertContains($asset->id, $this->mismatchedIds($result)); + } + + public function test_null_company_item_at_company_location_is_flagged_in_strict_mode() + { + $company = Company::factory()->create(); + $location = Location::factory()->for($company)->create(); + $asset = $this->assetAt($location, ['company_id' => null]); + + $this->settings->enableMultipleFullCompanySupport(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertContains($asset->id, $this->mismatchedIds($result)); + } + + public function test_null_company_item_at_company_location_is_not_flagged_in_floater_mode() + { + $company = Company::factory()->create(); + $location = Location::factory()->for($company)->create(); + $asset = $this->assetAt($location, ['company_id' => null]); + + $this->settings->enableFloaterMode(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertNotContains($asset->id, $this->mismatchedIds($result)); + } + + public function test_company_item_at_null_company_location_is_flagged_in_strict_mode() + { + $company = Company::factory()->create(); + $location = Location::factory()->create(['company_id' => null]); + $asset = $this->assetAt($location, ['company_id' => $company->id]); + + $this->settings->enableMultipleFullCompanySupport(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertContains($asset->id, $this->mismatchedIds($result)); + } + + public function test_company_item_at_null_company_location_is_not_flagged_in_floater_mode() + { + $company = Company::factory()->create(); + $location = Location::factory()->create(['company_id' => null]); + $asset = $this->assetAt($location, ['company_id' => $company->id]); + + $this->settings->enableFloaterMode(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertNotContains($asset->id, $this->mismatchedIds($result)); + } + + public function test_null_company_item_at_null_company_location_is_never_flagged() + { + $location = Location::factory()->create(['company_id' => null]); + $asset = $this->assetAt($location, ['company_id' => null]); + + $this->settings->enableMultipleFullCompanySupport(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertNotContains($asset->id, $this->mismatchedIds($result)); + } + + public function test_user_at_location_with_matching_company_is_not_flagged() + { + $company = Company::factory()->create(); + $location = Location::factory()->for($company)->create(); + $user = User::factory()->create(['location_id' => $location->id]); + $user->companies()->sync([$company->id]); + + $this->settings->enableMultipleFullCompanySupport(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertNotContains($user->id, $this->mismatchedIds($result)); + } + + public function test_user_at_location_with_different_company_is_flagged() + { + [$companyA, $companyB] = Company::factory()->count(2)->create(); + $location = Location::factory()->for($companyA)->create(); + $user = User::factory()->create(['location_id' => $location->id]); + $user->companies()->sync([$companyB->id]); + + $this->settings->enableMultipleFullCompanySupport(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertContains($user->id, $this->mismatchedIds($result)); + } + + public function test_null_company_user_at_company_location_is_flagged_in_strict_mode() + { + $company = Company::factory()->create(); + $location = Location::factory()->for($company)->create(); + $user = User::factory()->create(['company_id' => null, 'location_id' => $location->id]); + $user->companies()->sync([]); + + $this->settings->enableMultipleFullCompanySupport(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertContains($user->id, $this->mismatchedIds($result)); + } + + public function test_null_company_user_at_company_location_is_not_flagged_in_floater_mode() + { + $company = Company::factory()->create(); + $location = Location::factory()->for($company)->create(); + $user = User::factory()->create(['company_id' => null, 'location_id' => $location->id]); + $user->companies()->sync([]); + + $this->settings->enableFloaterMode(); + + $result = Helper::test_locations_fmcs(true); + + $this->assertNotContains($user->id, $this->mismatchedIds($result)); + } + + public function test_location_id_option_scopes_check_to_single_location() + { + [$companyA, $companyB] = Company::factory()->count(2)->create(); + $locationA = Location::factory()->for($companyA)->create(); + $locationB = Location::factory()->for($companyB)->create(); + $assetA = $this->assetAt($locationA, ['company_id' => $companyB->id]); // mismatch at A + $assetB = $this->assetAt($locationB, ['company_id' => $companyA->id]); // mismatch at B + + $this->settings->enableMultipleFullCompanySupport(); + + $result = Helper::test_locations_fmcs(true, $locationA->id); + + $this->assertContains($assetA->id, $this->mismatchedIds($result)); + $this->assertNotContains($assetB->id, $this->mismatchedIds($result)); + } +}