feat(commercial) : plafonne le chiffre d'affaires client/fournisseur à 999 999 999 999,99 (ERP-193)
This commit is contained in:
@@ -125,11 +125,15 @@
|
|||||||
:readonly="businessReadonly"
|
:readonly="businessReadonly"
|
||||||
:error="informationErrors.errors.employeesCount"
|
:error="informationErrors.errors.employeesCount"
|
||||||
/>
|
/>
|
||||||
|
<!-- CA plafonne a 999 999 999 999,99 (ERP-193) : clamp a la saisie,
|
||||||
|
:key force le re-affichage quand on plafonne (modelValue inchange). -->
|
||||||
<MalioInputAmount
|
<MalioInputAmount
|
||||||
v-model="information.revenueAmount"
|
:key="revenueAmountKey"
|
||||||
|
:model-value="information.revenueAmount"
|
||||||
:label="t('commercial.clients.form.information.revenueAmount')"
|
:label="t('commercial.clients.form.information.revenueAmount')"
|
||||||
:readonly="businessReadonly"
|
:readonly="businessReadonly"
|
||||||
:error="informationErrors.errors.revenueAmount"
|
:error="informationErrors.errors.revenueAmount"
|
||||||
|
@update:model-value="onRevenueAmountInput"
|
||||||
/>
|
/>
|
||||||
<MalioInputText
|
<MalioInputText
|
||||||
v-model="information.directorName"
|
v-model="information.directorName"
|
||||||
@@ -423,6 +427,7 @@ import {
|
|||||||
type InformationFormDraft,
|
type InformationFormDraft,
|
||||||
type MainFormDraft,
|
type MainFormDraft,
|
||||||
} from '~/modules/commercial/utils/forms/clientEdit'
|
} from '~/modules/commercial/utils/forms/clientEdit'
|
||||||
|
import { clampRevenueAmount } from '~/modules/commercial/utils/forms/amountInput'
|
||||||
import {
|
import {
|
||||||
buildClientFormTabKeys,
|
buildClientFormTabKeys,
|
||||||
isAddressValid,
|
isAddressValid,
|
||||||
@@ -491,6 +496,19 @@ const headerTitle = computed(() => client.value?.companyName ?? t('commercial.cl
|
|||||||
const main = reactive<MainFormDraft>(mapMainDraft({} as ClientDetail))
|
const main = reactive<MainFormDraft>(mapMainDraft({} as ClientDetail))
|
||||||
const information = reactive<InformationFormDraft>(mapInformationDraft({} as ClientDetail))
|
const information = reactive<InformationFormDraft>(mapInformationDraft({} as ClientDetail))
|
||||||
const accounting = reactive<AccountingFormDraft>(mapAccountingFormDraft({} as ClientDetail))
|
const accounting = reactive<AccountingFormDraft>(mapAccountingFormDraft({} as ClientDetail))
|
||||||
|
|
||||||
|
// CA plafonne a 999 999 999 999,99 (ERP-193). La :key force le re-affichage du
|
||||||
|
// champ controle quand le plafonnement laisse le modelValue inchange.
|
||||||
|
const revenueAmountKey = ref(0)
|
||||||
|
|
||||||
|
/** Saisie du CA : plafonne au maximum metier et re-synchronise le champ si plafonne. */
|
||||||
|
function onRevenueAmountInput(value: string | null): void {
|
||||||
|
const clamped = clampRevenueAmount(value)
|
||||||
|
information.revenueAmount = clamped ?? null
|
||||||
|
if (clamped !== value) {
|
||||||
|
revenueAmountKey.value += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
const contacts = ref<ContactFormDraft[]>([])
|
const contacts = ref<ContactFormDraft[]>([])
|
||||||
const addresses = ref<AddressFormDraft[]>([])
|
const addresses = ref<AddressFormDraft[]>([])
|
||||||
const ribs = ref<RibFormDraft[]>([])
|
const ribs = ref<RibFormDraft[]>([])
|
||||||
|
|||||||
@@ -120,11 +120,15 @@
|
|||||||
:readonly="isValidated('information')"
|
:readonly="isValidated('information')"
|
||||||
:error="informationErrors.errors.employeesCount"
|
:error="informationErrors.errors.employeesCount"
|
||||||
/>
|
/>
|
||||||
|
<!-- CA plafonne a 999 999 999 999,99 (ERP-193) : clamp a la saisie,
|
||||||
|
:key force le re-affichage quand on plafonne (modelValue inchange). -->
|
||||||
<MalioInputAmount
|
<MalioInputAmount
|
||||||
v-model="information.revenueAmount"
|
:key="revenueAmountKey"
|
||||||
|
:model-value="information.revenueAmount"
|
||||||
:label="t('commercial.clients.form.information.revenueAmount')"
|
:label="t('commercial.clients.form.information.revenueAmount')"
|
||||||
:readonly="isValidated('information')"
|
:readonly="isValidated('information')"
|
||||||
:error="informationErrors.errors.revenueAmount"
|
:error="informationErrors.errors.revenueAmount"
|
||||||
|
@update:model-value="onRevenueAmountInput"
|
||||||
/>
|
/>
|
||||||
<MalioInputText
|
<MalioInputText
|
||||||
v-model="information.directorName"
|
v-model="information.directorName"
|
||||||
@@ -407,6 +411,7 @@ import {
|
|||||||
lastFillableTabKey,
|
lastFillableTabKey,
|
||||||
showsRelationAndTriageFields,
|
showsRelationAndTriageFields,
|
||||||
} from '~/modules/commercial/utils/forms/clientFormRules'
|
} from '~/modules/commercial/utils/forms/clientFormRules'
|
||||||
|
import { clampRevenueAmount } from '~/modules/commercial/utils/forms/amountInput'
|
||||||
import {
|
import {
|
||||||
buildAddressPayload,
|
buildAddressPayload,
|
||||||
buildMainPayload,
|
buildMainPayload,
|
||||||
@@ -665,6 +670,19 @@ const information = reactive({
|
|||||||
directorName: null as string | null,
|
directorName: null as string | null,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// CA plafonne a 999 999 999 999,99 (ERP-193). La :key force le re-affichage du
|
||||||
|
// champ controle quand le plafonnement laisse le modelValue inchange.
|
||||||
|
const revenueAmountKey = ref(0)
|
||||||
|
|
||||||
|
/** Saisie du CA : plafonne au maximum metier et re-synchronise le champ si plafonne. */
|
||||||
|
function onRevenueAmountInput(value: string | null): void {
|
||||||
|
const clamped = clampRevenueAmount(value)
|
||||||
|
information.revenueAmount = clamped ?? null
|
||||||
|
if (clamped !== value) {
|
||||||
|
revenueAmountKey.value += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** PATCH /clients/{id} — mode strict : uniquement les champs du groupe information. */
|
/** PATCH /clients/{id} — mode strict : uniquement les champs du groupe information. */
|
||||||
async function submitInformation(): Promise<void> {
|
async function submitInformation(): Promise<void> {
|
||||||
if (clientId.value === null || tabSubmitting.value) return
|
if (clientId.value === null || tabSubmitting.value) return
|
||||||
|
|||||||
@@ -86,11 +86,15 @@
|
|||||||
:readonly="businessReadonly"
|
:readonly="businessReadonly"
|
||||||
:error="informationErrors.errors.employeesCount"
|
:error="informationErrors.errors.employeesCount"
|
||||||
/>
|
/>
|
||||||
|
<!-- CA plafonne a 999 999 999 999,99 (ERP-193) : clamp a la saisie,
|
||||||
|
:key force le re-affichage quand on plafonne (modelValue inchange). -->
|
||||||
<MalioInputAmount
|
<MalioInputAmount
|
||||||
v-model="information.revenueAmount"
|
:key="revenueAmountKey"
|
||||||
|
:model-value="information.revenueAmount"
|
||||||
:label="t('commercial.suppliers.form.information.revenueAmount')"
|
:label="t('commercial.suppliers.form.information.revenueAmount')"
|
||||||
:readonly="businessReadonly"
|
:readonly="businessReadonly"
|
||||||
:error="informationErrors.errors.revenueAmount"
|
:error="informationErrors.errors.revenueAmount"
|
||||||
|
@update:model-value="onRevenueAmountInput"
|
||||||
/>
|
/>
|
||||||
<MalioInputText
|
<MalioInputText
|
||||||
v-model="information.directorName"
|
v-model="information.directorName"
|
||||||
@@ -392,6 +396,7 @@ import {
|
|||||||
type MainFormDraft,
|
type MainFormDraft,
|
||||||
type SupplierEditAbilities,
|
type SupplierEditAbilities,
|
||||||
} from '~/modules/commercial/utils/forms/supplierEdit'
|
} from '~/modules/commercial/utils/forms/supplierEdit'
|
||||||
|
import { clampRevenueAmount } from '~/modules/commercial/utils/forms/amountInput'
|
||||||
import {
|
import {
|
||||||
buildSupplierFormTabKeys,
|
buildSupplierFormTabKeys,
|
||||||
isAddressValid,
|
isAddressValid,
|
||||||
@@ -457,6 +462,19 @@ const headerTitle = computed(() => supplier.value?.companyName ?? t('commercial.
|
|||||||
const main = reactive<MainFormDraft>(mapMainDraft({} as SupplierDetail))
|
const main = reactive<MainFormDraft>(mapMainDraft({} as SupplierDetail))
|
||||||
const information = reactive<InformationFormDraft>(mapInformationDraft({} as SupplierDetail))
|
const information = reactive<InformationFormDraft>(mapInformationDraft({} as SupplierDetail))
|
||||||
const accounting = reactive<AccountingFormDraft>(mapAccountingFormDraft({} as SupplierDetail))
|
const accounting = reactive<AccountingFormDraft>(mapAccountingFormDraft({} as SupplierDetail))
|
||||||
|
|
||||||
|
// CA plafonne a 999 999 999 999,99 (ERP-193). La :key force le re-affichage du
|
||||||
|
// champ controle quand le plafonnement laisse le modelValue inchange.
|
||||||
|
const revenueAmountKey = ref(0)
|
||||||
|
|
||||||
|
/** Saisie du CA : plafonne au maximum metier et re-synchronise le champ si plafonne. */
|
||||||
|
function onRevenueAmountInput(value: string | null): void {
|
||||||
|
const clamped = clampRevenueAmount(value)
|
||||||
|
information.revenueAmount = clamped ?? null
|
||||||
|
if (clamped !== value) {
|
||||||
|
revenueAmountKey.value += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
const contacts = ref<SupplierContactFormDraft[]>([])
|
const contacts = ref<SupplierContactFormDraft[]>([])
|
||||||
const addresses = ref<SupplierAddressFormDraft[]>([])
|
const addresses = ref<SupplierAddressFormDraft[]>([])
|
||||||
const ribs = ref<SupplierRibFormDraft[]>([])
|
const ribs = ref<SupplierRibFormDraft[]>([])
|
||||||
|
|||||||
@@ -80,11 +80,15 @@
|
|||||||
:readonly="isValidated('information')"
|
:readonly="isValidated('information')"
|
||||||
:error="informationErrors.errors.employeesCount"
|
:error="informationErrors.errors.employeesCount"
|
||||||
/>
|
/>
|
||||||
|
<!-- CA plafonne a 999 999 999 999,99 (ERP-193) : clamp a la saisie,
|
||||||
|
:key force le re-affichage quand on plafonne (modelValue inchange). -->
|
||||||
<MalioInputAmount
|
<MalioInputAmount
|
||||||
v-model="information.revenueAmount"
|
:key="revenueAmountKey"
|
||||||
|
:model-value="information.revenueAmount"
|
||||||
:label="t('commercial.suppliers.form.information.revenueAmount')"
|
:label="t('commercial.suppliers.form.information.revenueAmount')"
|
||||||
:readonly="isValidated('information')"
|
:readonly="isValidated('information')"
|
||||||
:error="informationErrors.errors.revenueAmount"
|
:error="informationErrors.errors.revenueAmount"
|
||||||
|
@update:model-value="onRevenueAmountInput"
|
||||||
/>
|
/>
|
||||||
<MalioInputText
|
<MalioInputText
|
||||||
v-model="information.directorName"
|
v-model="information.directorName"
|
||||||
@@ -375,6 +379,7 @@ import {
|
|||||||
buildMainPayload,
|
buildMainPayload,
|
||||||
buildRibPayload,
|
buildRibPayload,
|
||||||
} from '~/modules/commercial/utils/forms/supplierEdit'
|
} from '~/modules/commercial/utils/forms/supplierEdit'
|
||||||
|
import { clampRevenueAmount } from '~/modules/commercial/utils/forms/amountInput'
|
||||||
import {
|
import {
|
||||||
emptyAddress,
|
emptyAddress,
|
||||||
emptyContact,
|
emptyContact,
|
||||||
@@ -564,6 +569,19 @@ const information = reactive({
|
|||||||
volumeForecast: null as string | null,
|
volumeForecast: null as string | null,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// CA plafonne a 999 999 999 999,99 (ERP-193). La :key force le re-affichage du
|
||||||
|
// champ controle quand le plafonnement laisse le modelValue inchange.
|
||||||
|
const revenueAmountKey = ref(0)
|
||||||
|
|
||||||
|
/** Saisie du CA : plafonne au maximum metier et re-synchronise le champ si plafonne. */
|
||||||
|
function onRevenueAmountInput(value: string | null): void {
|
||||||
|
const clamped = clampRevenueAmount(value)
|
||||||
|
information.revenueAmount = clamped ?? null
|
||||||
|
if (clamped !== value) {
|
||||||
|
revenueAmountKey.value += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** PATCH /suppliers/{id} — mode strict : uniquement les champs du groupe information. */
|
/** PATCH /suppliers/{id} — mode strict : uniquement les champs du groupe information. */
|
||||||
async function submitInformation(): Promise<void> {
|
async function submitInformation(): Promise<void> {
|
||||||
if (supplierId.value === null || tabSubmitting.value) return
|
if (supplierId.value === null || tabSubmitting.value) return
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { describe, expect, it } from 'vitest'
|
||||||
|
import { clampRevenueAmount, REVENUE_AMOUNT_MAX } from '../amountInput'
|
||||||
|
|
||||||
|
describe('clampRevenueAmount', () => {
|
||||||
|
it('laisse les valeurs vides / nulles telles quelles', () => {
|
||||||
|
expect(clampRevenueAmount(null)).toBeNull()
|
||||||
|
expect(clampRevenueAmount(undefined)).toBeUndefined()
|
||||||
|
expect(clampRevenueAmount('')).toBe('')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('laisse une valeur sous le plafond inchangee', () => {
|
||||||
|
expect(clampRevenueAmount('1000.50')).toBe('1000.50')
|
||||||
|
expect(clampRevenueAmount('999999999999.99')).toBe('999999999999.99')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('plafonne une valeur au-dessus du maximum', () => {
|
||||||
|
expect(clampRevenueAmount('1000000000000')).toBe('999999999999.99')
|
||||||
|
expect(clampRevenueAmount('999999999999999.99')).toBe('999999999999.99')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('tolere une saisie a virgule / avec espaces (securite)', () => {
|
||||||
|
expect(clampRevenueAmount('1 000 000 000 000,00')).toBe('999999999999.99')
|
||||||
|
expect(clampRevenueAmount('12,5')).toBe('12,5')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('ne touche pas une saisie non numerique', () => {
|
||||||
|
expect(clampRevenueAmount('abc')).toBe('abc')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('expose le plafond metier', () => {
|
||||||
|
expect(REVENUE_AMOUNT_MAX).toBe(999_999_999_999.99)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
/**
|
||||||
|
* Helpers de saisie des montants des formulaires Client / Fournisseur (commercial).
|
||||||
|
* Purs / testables. Pendant FRONT de la contrainte back `LessThanOrEqual` posee sur
|
||||||
|
* `revenueAmount` (Client/Supplier) — retour metier ERP-193 : le chiffre d'affaires
|
||||||
|
* est plafonne a 999 999 999 999,99.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Plafond metier du chiffre d'affaires (CA) : 999 999 999 999,99. */
|
||||||
|
export const REVENUE_AMOUNT_MAX = 999_999_999_999.99
|
||||||
|
|
||||||
|
/** Valeur « modele » (decimale a point, sans separateur) renvoyee quand on plafonne. */
|
||||||
|
const REVENUE_AMOUNT_MAX_MODEL = '999999999999.99'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Plafonne le CA au maximum metier. Recoit le modele emis par `MalioInputAmount`
|
||||||
|
* (chaine propre a decimale `.`, sans espaces) ; tolere malgre tout une virgule /
|
||||||
|
* des espaces par securite. Renvoie la valeur telle quelle si elle est vide, non
|
||||||
|
* numerique ou sous le plafond ; sinon la valeur plafonnee.
|
||||||
|
*/
|
||||||
|
export function clampRevenueAmount(value: string | null | undefined): string | null | undefined {
|
||||||
|
if (value === null || value === undefined || value === '') {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
const n = Number(String(value).replace(/\s/g, '').replace(',', '.'))
|
||||||
|
if (Number.isNaN(n)) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return n > REVENUE_AMOUNT_MAX ? REVENUE_AMOUNT_MAX_MODEL : value
|
||||||
|
}
|
||||||
@@ -233,7 +233,10 @@ class Client implements TimestampableInterface, BlamableInterface, ClientInterfa
|
|||||||
#[Groups(['client:read', 'client:write:information'])]
|
#[Groups(['client:read', 'client:write:information'])]
|
||||||
private ?int $employeesCount = null;
|
private ?int $employeesCount = null;
|
||||||
|
|
||||||
|
// Chiffre d'affaires plafonne a 999 999 999 999,99 (12 chiffres, retour metier
|
||||||
|
// ERP-193). La colonne (decimal 15,2) tolere plus, mais le metier borne la saisie.
|
||||||
#[ORM\Column(type: 'decimal', precision: 15, scale: 2, nullable: true)]
|
#[ORM\Column(type: 'decimal', precision: 15, scale: 2, nullable: true)]
|
||||||
|
#[Assert\LessThanOrEqual(value: 999_999_999_999.99, message: 'Le chiffre d\'affaires ne peut pas dépasser 999 999 999 999,99.')]
|
||||||
#[Groups(['client:read', 'client:write:information'])]
|
#[Groups(['client:read', 'client:write:information'])]
|
||||||
private ?string $revenueAmount = null;
|
private ?string $revenueAmount = null;
|
||||||
|
|
||||||
|
|||||||
@@ -212,7 +212,10 @@ class Supplier implements TimestampableInterface, BlamableInterface, SupplierInt
|
|||||||
#[Groups(['supplier:read', 'supplier:write:information'])]
|
#[Groups(['supplier:read', 'supplier:write:information'])]
|
||||||
private ?int $employeesCount = null;
|
private ?int $employeesCount = null;
|
||||||
|
|
||||||
|
// Chiffre d'affaires plafonne a 999 999 999 999,99 (12 chiffres, retour metier
|
||||||
|
// ERP-193). La colonne (decimal 15,2) tolere plus, mais le metier borne la saisie.
|
||||||
#[ORM\Column(type: 'decimal', precision: 15, scale: 2, nullable: true)]
|
#[ORM\Column(type: 'decimal', precision: 15, scale: 2, nullable: true)]
|
||||||
|
#[Assert\LessThanOrEqual(value: 999_999_999_999.99, message: 'Le chiffre d\'affaires ne peut pas dépasser 999 999 999 999,99.')]
|
||||||
#[Groups(['supplier:read', 'supplier:write:information'])]
|
#[Groups(['supplier:read', 'supplier:write:information'])]
|
||||||
private ?string $revenueAmount = null;
|
private ?string $revenueAmount = null;
|
||||||
|
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ final class EntityConstraintsHaveFrenchMessageTest extends TestCase
|
|||||||
Assert\Positive::class,
|
Assert\Positive::class,
|
||||||
Assert\NegativeOrZero::class,
|
Assert\NegativeOrZero::class,
|
||||||
Assert\Negative::class,
|
Assert\Negative::class,
|
||||||
|
Assert\LessThanOrEqual::class,
|
||||||
];
|
];
|
||||||
|
|
||||||
public function testEveryConstraintHasAnExplicitFrenchMessage(): void
|
public function testEveryConstraintHasAnExplicitFrenchMessage(): void
|
||||||
@@ -302,7 +303,9 @@ final class EntityConstraintsHaveFrenchMessageTest extends TestCase
|
|||||||
Assert\Length::class => new Assert\Length(max: 1),
|
Assert\Length::class => new Assert\Length(max: 1),
|
||||||
Assert\Count::class => new Assert\Count(min: 1),
|
Assert\Count::class => new Assert\Count(min: 1),
|
||||||
Assert\Regex::class => new Assert\Regex(pattern: '/^x$/'),
|
Assert\Regex::class => new Assert\Regex(pattern: '/^x$/'),
|
||||||
default => new $class(),
|
// AbstractComparison exige value|propertyPath des l'instanciation.
|
||||||
|
Assert\LessThanOrEqual::class => new Assert\LessThanOrEqual(value: 0),
|
||||||
|
default => new $class(),
|
||||||
};
|
};
|
||||||
|
|
||||||
$value = $bare->{$prop} ?? null;
|
$value = $bare->{$prop} ?? null;
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace App\Tests\Module\Commercial\Api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validation back-autoritative du plafond du chiffre d'affaires (revenueAmount,
|
||||||
|
* onglet Information) sur Client ET Fournisseur — retour metier ERP-193.
|
||||||
|
*
|
||||||
|
* Le CA est plafonne a 999 999 999 999,99 (12 chiffres). La colonne decimal(15,2)
|
||||||
|
* tolererait plus, mais le metier borne la saisie : au-dela, 422 porte sur
|
||||||
|
* `revenueAmount` (mappable inline par useFormErrors). La valeur exactement egale
|
||||||
|
* au plafond reste acceptee. Le front clampe deja la saisie (amountInput.ts), mais
|
||||||
|
* le back reste la couche autoritaire.
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class RevenueAmountCapTest extends AbstractSupplierApiTestCase
|
||||||
|
{
|
||||||
|
/** Plafond metier : 12 chiffres + 2 decimales. */
|
||||||
|
private const string MAX = '999999999999.99';
|
||||||
|
|
||||||
|
/** Client : CA au-dela du plafond -> 422 porte sur revenueAmount. */
|
||||||
|
public function testClientRevenueAmountAuDelaDuPlafondEst422(): void
|
||||||
|
{
|
||||||
|
$client = $this->createAdminClient();
|
||||||
|
$seed = $this->seedClient('CA Cap Client SARL');
|
||||||
|
|
||||||
|
$body = $client->request('PATCH', '/api/clients/'.$seed->getId(), [
|
||||||
|
'headers' => ['Content-Type' => self::MERGE],
|
||||||
|
'json' => ['revenueAmount' => '1000000000000.00'],
|
||||||
|
])->toArray(false);
|
||||||
|
|
||||||
|
self::assertResponseStatusCodeSame(422);
|
||||||
|
self::assertArrayHasKey('revenueAmount', $this->violationsByPath($body));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Client : CA exactement au plafond -> accepte (200). */
|
||||||
|
public function testClientRevenueAmountAuPlafondEst200(): void
|
||||||
|
{
|
||||||
|
$client = $this->createAdminClient();
|
||||||
|
$seed = $this->seedClient('CA Max Client SARL');
|
||||||
|
|
||||||
|
$client->request('PATCH', '/api/clients/'.$seed->getId(), [
|
||||||
|
'headers' => ['Content-Type' => self::MERGE],
|
||||||
|
'json' => ['revenueAmount' => self::MAX],
|
||||||
|
]);
|
||||||
|
|
||||||
|
self::assertResponseStatusCodeSame(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fournisseur : CA au-dela du plafond -> 422 porte sur revenueAmount. */
|
||||||
|
public function testSupplierRevenueAmountAuDelaDuPlafondEst422(): void
|
||||||
|
{
|
||||||
|
$client = $this->createAdminClient();
|
||||||
|
$seed = $this->seedSupplier('CA Cap Fournisseur SARL');
|
||||||
|
|
||||||
|
$body = $client->request('PATCH', '/api/suppliers/'.$seed->getId(), [
|
||||||
|
'headers' => ['Content-Type' => self::MERGE],
|
||||||
|
'json' => ['revenueAmount' => '1000000000000.00'],
|
||||||
|
])->toArray(false);
|
||||||
|
|
||||||
|
self::assertResponseStatusCodeSame(422);
|
||||||
|
self::assertArrayHasKey('revenueAmount', $this->violationsByPath($body));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Fournisseur : CA exactement au plafond -> accepte (200). */
|
||||||
|
public function testSupplierRevenueAmountAuPlafondEst200(): void
|
||||||
|
{
|
||||||
|
$client = $this->createAdminClient();
|
||||||
|
$seed = $this->seedSupplier('CA Max Fournisseur SARL');
|
||||||
|
|
||||||
|
$client->request('PATCH', '/api/suppliers/'.$seed->getId(), [
|
||||||
|
'headers' => ['Content-Type' => self::MERGE],
|
||||||
|
'json' => ['revenueAmount' => self::MAX],
|
||||||
|
]);
|
||||||
|
|
||||||
|
self::assertResponseStatusCodeSame(200);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user