add currency to organization update endpoint

This commit is contained in:
Gregor Vostrak
2026-06-09 12:37:20 +02:00
committed by Constantin Graf
parent c8024de452
commit 96ecc5335a
5 changed files with 94 additions and 1 deletions

View File

@@ -50,6 +50,9 @@ class OrganizationController extends Controller
if ($request->getName() !== null) {
$organization->name = $request->getName();
}
if ($request->getCurrency() !== null) {
$organization->currency = $request->getCurrency();
}
if ($request->getEmployeesCanSeeBillableRates() !== null) {
$organization->employees_can_see_billable_rates = $request->getEmployeesCanSeeBillableRates();
}

View File

@@ -11,6 +11,7 @@ use App\Enums\NumberFormat;
use App\Enums\TimeFormat;
use App\Http\Requests\V1\BaseFormRequest;
use App\Models\Organization;
use App\Rules\CurrencyRule;
use Illuminate\Validation\Rule;
/**
@@ -21,7 +22,7 @@ class OrganizationUpdateRequest extends BaseFormRequest
/**
* Get the validation rules that apply to the request.
*
* @return array<string, array<string|\Illuminate\Contracts\Validation\Rule>>
* @return array<string, array<string|\Illuminate\Contracts\Validation\Rule|\Illuminate\Contracts\Validation\ValidationRule>>
*/
public function rules(): array
{
@@ -30,6 +31,10 @@ class OrganizationUpdateRequest extends BaseFormRequest
'string',
'max:255',
],
'currency' => [
'string',
new CurrencyRule,
],
'billable_rate' => array_merge(
[
'nullable',
@@ -68,6 +73,11 @@ class OrganizationUpdateRequest extends BaseFormRequest
return $this->has('name') ? (string) $this->input('name') : null;
}
public function getCurrency(): ?string
{
return $this->has('currency') ? (string) $this->input('currency') : null;
}
public function getNumberFormat(): ?NumberFormat
{
return $this->has('number_format') ? NumberFormat::from($this->input('number_format')) : null;

View File

@@ -55,6 +55,33 @@ test('test that organization name can be updated', async ({ page }) => {
);
});
test('test that organization currency can be updated', async ({ page }) => {
await goToOrganizationSettings(page);
await page.getByLabel('Currency', { exact: true }).selectOption('USD');
await Promise.all([
page.waitForRequest(
(request) =>
request.url().includes('/api/v1/organizations/') &&
request.method() === 'PUT' &&
request.postDataJSON().currency === 'USD'
),
page.waitForResponse(
async (response) =>
response.url().includes('/api/v1/organizations/') &&
response.request().method() === 'PUT' &&
response.status() === 200 &&
(await response.json()).data.currency === 'USD'
),
page
.locator('form')
.filter({ hasText: 'Organization Name' })
.getByRole('button', { name: 'Save' })
.click(),
]);
await page.reload();
await expect(page.getByLabel('Currency', { exact: true })).toHaveValue('USD');
});
test('test that organization billable rate can be updated with all existing time entries', async ({
page,
}) => {

View File

@@ -330,6 +330,7 @@ const OrganizationResource = z
const OrganizationUpdateRequest = z
.object({
name: z.string().max(255),
currency: z.string(),
billable_rate: z.union([z.number(), z.null()]),
employees_can_see_billable_rates: z.boolean(),
employees_can_manage_tasks: z.boolean(),

View File

@@ -382,6 +382,58 @@ class OrganizationEndpointTest extends ApiEndpointTestAbstract
]);
}
public function test_update_endpoint_can_update_the_currency_of_the_organization(): void
{
// Arrange
$data = $this->createUserWithPermission([
'organizations:update',
]);
$this->assertBillableRateServiceIsUnused();
$data->organization->currency = 'EUR';
$data->organization->save();
Passport::actingAs($data->user);
// Act
$response = $this->putJson(route('api.v1.organizations.update', [$data->organization->getKey()]), [
'name' => $data->organization->name,
'currency' => 'USD',
]);
// Assert
$response->assertStatus(200);
$response->assertJsonPath('data.currency', 'USD');
$this->assertDatabaseHas(Organization::class, [
'id' => $data->organization->getKey(),
'currency' => 'USD',
]);
}
public function test_update_endpoint_fails_if_currency_is_invalid(): void
{
// Arrange
$data = $this->createUserWithPermission([
'organizations:update',
]);
$this->assertBillableRateServiceIsUnused();
$data->organization->currency = 'EUR';
$data->organization->save();
Passport::actingAs($data->user);
// Act
$response = $this->putJson(route('api.v1.organizations.update', [$data->organization->getKey()]), [
'name' => $data->organization->name,
'currency' => 'NOT_A_CURRENCY',
]);
// Assert
$response->assertStatus(422);
$response->assertJsonValidationErrors(['currency']);
$this->assertDatabaseHas(Organization::class, [
'id' => $data->organization->getKey(),
'currency' => 'EUR',
]);
}
public function test_delete_endpoint_if_user_does_not_have_permission(): void
{
// Arrange