diff --git a/.changeset/new-bottles-tap.md b/.changeset/new-bottles-tap.md new file mode 100644 index 000000000..21758c1d6 --- /dev/null +++ b/.changeset/new-bottles-tap.md @@ -0,0 +1,5 @@ +--- +'@monite/sdk-react': minor +--- + +feat(DEV-13687) Argon changes during invoice creation diff --git a/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/CreateReceivables.tsx b/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/CreateReceivables.tsx index 0bf0bed62..e3864f14a 100644 --- a/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/CreateReceivables.tsx +++ b/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/CreateReceivables.tsx @@ -65,7 +65,7 @@ const CreateReceivablesBase = ({ isLoading: isEntityLoading, isNonCompliantFlow, } = useMyEntity(); - + const fallbackCurrency = 'USD'; const methods = useForm({ resolver: yupResolver( getCreateInvoiceValidationSchema( @@ -236,33 +236,31 @@ const CreateReceivablesBase = ({ onSubmit={handleSubmit(handleCreateReceivable)} style={{ marginBottom: theme.spacing(7) }} > + + + {t(i18n)`Invoice`}{' '} + + #{INVOICE_DOCUMENT_AUTO_ID} + + + - - - {t(i18n)`Invoice`}{' '} - - #{INVOICE_DOCUMENT_AUTO_ID} - - - - + + + { const counterpartId = watch('counterpart_id'); - const { - data: counterpartContacts, - error: contactPersonError, - isLoading: isContactPersonsLoading, - } = useCounterpartContactList(counterpartId); const { data: counterpartVats, isLoading: isCounterpartVatsLoading } = useCounterpartVatList(counterpartId); const { data: counterpart, isLoading: isCounterpartLoading } = @@ -102,14 +92,33 @@ export const CustomerSection = ({ disabled }: SectionGeneralProps) => { const [isCreateCounterpartOpened, setIsCreateCounterpartOpened] = useState(false); - const defaultContactName = counterpartContacts?.find( - (contact) => contact.is_default - ); - - const contactPersonDisplayableError = - usePrevious(contactPersonError) ?? contactPersonError; + const [isShippingAddressShown, setIsShippingAddressShown] = + useState(false); const className = 'Monite-CreateReceivable-CustomerSection'; + const isHiddenForUS = + !_isCounterpartAddressesLoading && + Array.isArray(counterpartAddresses?.data) && + counterpartAddresses.data.length > 0 && + counterpartAddresses.data[0]?.country === 'US'; + const isAddressFormDisabled = + isCounterpartAddressesLoading || + !counterpartId || + disabled || + counterpartAddresses?.data.length === 1; + + useEffect(() => { + if (counterpartAddresses && counterpartAddresses.data.length === 1) { + setValue('default_shipping_address_id', counterpartAddresses.data[0].id); + setValue('default_billing_address_id', counterpartAddresses.data[0].id); + } + }, [counterpartAddresses, setValue]); + + useEffect(() => { + if (counterpartVats && counterpartVats.data.length === 1) { + setValue('counterpart_vat_id_id', counterpartVats.data[0].id); + } + }, [counterpartVats, setValue]); return ( @@ -126,40 +135,6 @@ export const CustomerSection = ({ disabled }: SectionGeneralProps) => { /> {counterpartId && ( <> - - - ) : null, - }} - /> - - - {contactPersonDisplayableError && - getAPIErrorMessage(i18n, contactPersonDisplayableError)} - - - - {t( - i18n - )`No contact persons available`} - - { disabled={ isCounterpartVatsLoading || !counterpartVats?.data || - counterpartVats?.data.length === 0 || + counterpartVats?.data.length < 2 || disabled } + hidden={isHiddenForUS} error={Boolean(error)} > {t(i18n)`VAT ID`} @@ -205,6 +181,7 @@ export const CustomerSection = ({ disabled }: SectionGeneralProps) => { variant="standard" label={t(i18n)`TAX ID`} value={counterpart?.tax_id ?? ''} + hidden={isHiddenForUS} InputProps={{ startAdornment: isCounterpartLoading ? ( @@ -224,11 +201,13 @@ export const CustomerSection = ({ disabled }: SectionGeneralProps) => { ), }} /> - - {t(i18n)`No TAX ID available`} - + {!isHiddenForUS && ( + + {t(i18n)`No TAX ID available`} + + )} { fullWidth required error={Boolean(error)} - disabled={ - isCounterpartAddressesLoading || !counterpartId || disabled - } + disabled={isAddressFormDisabled} > {t( i18n @@ -267,57 +244,69 @@ export const CustomerSection = ({ disabled }: SectionGeneralProps) => { )} /> - ( - - {t( - i18n - )`Shipping address`} - - - )} - /> + {t( + i18n + )`Shipping address`} + + + )} + /> + )} )} diff --git a/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/EntitySection.tsx b/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/EntitySection.tsx index 0005a214e..788775019 100644 --- a/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/EntitySection.tsx +++ b/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/EntitySection.tsx @@ -3,7 +3,7 @@ import { Controller, useFormContext } from 'react-hook-form'; import { CreateReceivablesFormProps } from '@/components/receivables/InvoiceDetails/CreateReceivable/validation'; import { t } from '@lingui/macro'; import { useLingui } from '@lingui/react'; -import { Box, FormControl, TextField } from '@mui/material'; +import { Box, FormControl, TextField, Typography } from '@mui/material'; import type { SectionGeneralProps } from './Section.types'; @@ -21,7 +21,17 @@ export const EntitySection = ({ disabled }: EntitySectionProps) => { const { control } = useFormContext(); return ( - + + + {t(i18n)`Memo`} + diff --git a/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/components/Billing/FullfillmentSummary.tsx b/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/components/Billing/FullfillmentSummary.tsx index dd727a4d4..f56838368 100644 --- a/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/components/Billing/FullfillmentSummary.tsx +++ b/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/components/Billing/FullfillmentSummary.tsx @@ -7,7 +7,8 @@ import { useRootElements } from '@/core/context/RootElementsProvider'; import { t } from '@lingui/macro'; import { useLingui } from '@lingui/react'; import { LockOutlined } from '@mui/icons-material'; -import { FormControlLabel, Checkbox, Box, Typography } from '@mui/material'; +import AddIcon from '@mui/icons-material/Add'; +import { Button, Box, Typography } from '@mui/material'; import { DatePicker } from '@mui/x-date-pickers'; import { PaymentSection } from '../../PaymentSection'; @@ -15,7 +16,7 @@ import { SectionGeneralProps } from '../../Section.types'; export const FullfillmentSummary = ({ disabled }: SectionGeneralProps) => { const { i18n } = useLingui(); - const { control, resetField, setValue, watch } = + const { control, resetField, watch } = useFormContext(); const { api, locale } = useMoniteContext(); @@ -27,8 +28,7 @@ export const FullfillmentSummary = ({ disabled }: SectionGeneralProps) => { const dateTime = i18n.date(new Date(), locale.dateTimeFormat); - const [isSameAsInvoiceDateChecked, setIsSameAsInvoiceDateChecked] = - useState(false); + const [isFieldShown, setIsFieldShown] = useState(false); const paymentTermsId = watch('payment_terms_id'); @@ -38,114 +38,115 @@ export const FullfillmentSummary = ({ disabled }: SectionGeneralProps) => { return ( <> - - - + + + {t(i18n)`Issue date`} - + {dateTime} - - + + {t(i18n)`Set on issuance`} - - + + {t(i18n)`Due date`} - + {t(i18n)`${selectedPaymentTerm?.name ?? 'Not selected'}`} - - + + + {t(i18n)`Set by payment term`} - ( - <> - { - const today = new Date(); - - if (today.toDateString() === date?.toDateString()) { - setIsSameAsInvoiceDateChecked(true); - } else { - setIsSameAsInvoiceDateChecked(false); - } - - field.onChange(date); - }} - label={t(i18n)`Fulfillment date`} - slotProps={{ - popper: { - container: root, - }, - dialog: { - container: root, - }, - actionBar: { - actions: ['today'], - }, - textField: { - fullWidth: true, - helperText: error?.message, - }, - field: { - clearable: true, - onClear: () => { - resetField(field.name); - setIsSameAsInvoiceDateChecked(false); - }, - }, - }} - views={['year', 'month', 'day']} - /> - { - const checked = event.target.checked; - - if (checked) { - setValue(field.name, new Date(), { - shouldValidate: true, - }); - } else { - resetField(field.name); - } - - setIsSameAsInvoiceDateChecked(checked); - }} - /> - } - label={t(i18n)`Same as invoice date`} - /> - - )} - /> - + + {!isFieldShown && ( + + )} + {isFieldShown && ( + ( + <> + { + field.onChange(date); + }} + label={t(i18n)`Fulfillment date`} + slotProps={{ + popper: { + container: root, + }, + dialog: { + container: root, + }, + actionBar: { + actions: ['today'], + }, + textField: { + fullWidth: true, + helperText: error?.message, + }, + field: { + clearable: true, + onClear: () => { + resetField(field.name); + }, + }, + }} + views={['year', 'month', 'day']} + /> + + )} + /> + )} ); diff --git a/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/components/Billing/YourVatDetailsForm.tsx b/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/components/Billing/YourVatDetailsForm.tsx index 8cdc86fab..470a01478 100644 --- a/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/components/Billing/YourVatDetailsForm.tsx +++ b/packages/sdk-react/src/components/receivables/InvoiceDetails/CreateReceivable/sections/components/Billing/YourVatDetailsForm.tsx @@ -1,3 +1,4 @@ +import { useEffect } from 'react'; import { Controller, useFormContext } from 'react-hook-form'; import { CountryInvoiceOption } from '@/components/receivables/InvoiceDetails/CreateReceivable/components/CountryInvoiceOption'; @@ -21,7 +22,7 @@ import { export const YourVatDetailsForm = ({ disabled }: { disabled: boolean }) => { const { i18n } = useLingui(); - const { control } = useFormContext(); + const { control, setValue } = useFormContext(); const { root } = useRootElements(); @@ -46,6 +47,15 @@ export const YourVatDetailsForm = ({ disabled }: { disabled: boolean }) => { entityVatIds.data.length === 0 ); + const isHiddenForUS = + entity?.address.country && entity?.address.country === 'US'; + + useEffect(() => { + if (entityVatIds && entityVatIds.data.length === 1) { + setValue('entity_vat_id_id', entityVatIds.data[0].id); + } + }, [entityVatIds, setValue]); + return ( {showEntityVatIdField && ( @@ -56,8 +66,13 @@ export const YourVatDetailsForm = ({ disabled }: { disabled: boolean }) => { ); }; diff --git a/packages/sdk-react/src/components/receivables/InvoiceDetails/ExistingInvoiceDetails/components/EditInvoiceDetails.tsx b/packages/sdk-react/src/components/receivables/InvoiceDetails/ExistingInvoiceDetails/components/EditInvoiceDetails.tsx index dc8513fe9..61337a747 100644 --- a/packages/sdk-react/src/components/receivables/InvoiceDetails/ExistingInvoiceDetails/components/EditInvoiceDetails.tsx +++ b/packages/sdk-react/src/components/receivables/InvoiceDetails/ExistingInvoiceDetails/components/EditInvoiceDetails.tsx @@ -264,12 +264,12 @@ const EditInvoiceDetailsContent = ({ #{invoice.document_id ?? INVOICE_DOCUMENT_AUTO_ID} -