diff --git a/packages/twenty-front/src/modules/object-record/spreadsheet-import/useSpreadsheetRecordImport.ts b/packages/twenty-front/src/modules/object-record/spreadsheet-import/useSpreadsheetRecordImport.ts index 28516c7939e..284306e95ea 100644 --- a/packages/twenty-front/src/modules/object-record/spreadsheet-import/useSpreadsheetRecordImport.ts +++ b/packages/twenty-front/src/modules/object-record/spreadsheet-import/useSpreadsheetRecordImport.ts @@ -1,4 +1,4 @@ -import { isNonEmptyString } from '@sniptt/guards'; +import { isNonEmptyString, isUndefined } from '@sniptt/guards'; import { useIcons } from 'twenty-ui'; import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; @@ -9,11 +9,26 @@ import { Field, SpreadsheetOptions } from '@/spreadsheet-import/types'; import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar'; import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar'; import { FieldMetadataType } from '~/generated-metadata/graphql'; +import { convertCurrencyMicrosToCurrency } from '~/utils/convert-currency-amount'; import { isDefined } from '~/utils/isDefined'; const firstName = 'Firstname'; const lastName = 'Lastname'; +const currencyCode = 'Currency Code'; +const amountMicros = 'Amount'; + +const addressFields = { + addressStreet1: 'Address 1', + addressStreet2: 'Address 2', + addressCity: 'City', + addressPostcode: 'Post Code', + addressState: 'State', + addressCountry: 'Country', + addressLat: 'Latitude', + addressLng: 'Longitude', +}; + export const useSpreadsheetRecordImport = (objectNameSingular: string) => { const { openSpreadsheetImport } = useSpreadsheetImport(); const { enqueueSnackBar } = useSnackBar(); @@ -72,6 +87,46 @@ export const useSpreadsheetRecordImport = (objectNameSingular: string) => { field.label + ' (ID)', ), }); + } else if (field.type === FieldMetadataType.Currency) { + templateFields.push({ + icon: getIcon(field.icon), + label: `${currencyCode} (${field.label})`, + key: `${currencyCode} (${field.name})`, + fieldType: { + type: 'input', + }, + validations: getSpreadSheetValidation( + field.type, + `${currencyCode} (${field.label})`, + ), + }); + templateFields.push({ + icon: getIcon(field.icon), + label: `${amountMicros} (${field.label})`, + key: `${amountMicros} (${field.name})`, + fieldType: { + type: 'input', + }, + validations: getSpreadSheetValidation( + field.type, + `${amountMicros} (${field.label})`, + ), + }); + } else if (field.type === FieldMetadataType.Address) { + Object.entries(addressFields).forEach(([_, value]) => { + templateFields.push({ + icon: getIcon(field.icon), + label: `${value} (${field.label})`, + key: `${value} (${field.name})`, + fieldType: { + type: 'input', + }, + validations: getSpreadSheetValidation( + field.type, + `${value} (${field.label})`, + ), + }); + }); } else if (field.type === FieldMetadataType.Select) { templateFields.push({ icon: getIcon(field.icon), @@ -128,6 +183,10 @@ export const useSpreadsheetRecordImport = (objectNameSingular: string) => { for (const field of fields) { const value = record[field.name]; + if (isUndefined(value)) { + continue; + } + switch (field.type) { case FieldMetadataType.Boolean: if (value !== undefined) { @@ -141,13 +200,74 @@ export const useSpreadsheetRecordImport = (objectNameSingular: string) => { } break; case FieldMetadataType.Currency: - if (value !== undefined) { + if ( + isDefined( + record[`${amountMicros} (${field.name})`] || + record[`${currencyCode} (${field.name})`], + ) + ) { + fieldMapping[field.name] = { + amountMicros: convertCurrencyMicrosToCurrency( + Number(record[`${amountMicros} (${field.name})`]), + ), + currencyCode: + record[`${currencyCode} (${field.name})`] || 'USD', + }; + } + break; + case FieldMetadataType.Address: { + if ( + isDefined( + record[`${addressFields.addressStreet1} (${field.name})`] || + record[ + `${addressFields.addressStreet2} (${field.name})` + ] || + record[`${addressFields.addressCity} (${field.name})`] || + record[ + `${addressFields.addressPostcode} (${field.name})` + ] || + record[`${addressFields.addressState} (${field.name})`] || + record[ + `${addressFields.addressCountry} (${field.name})` + ] || + record[`${addressFields.addressLat} (${field.name})`] || + record[`${addressFields.addressLng} (${field.name})`], + ) + ) { fieldMapping[field.name] = { - amountMicros: Number(value), - currencyCode: 'USD', + addressStreet1: + record[ + `${addressFields.addressStreet1} (${field.name})` + ] || '', + addressStreet2: + record[ + `${addressFields.addressStreet2} (${field.name})` + ] || '', + addressCity: + record[`${addressFields.addressCity} (${field.name})`] || + '', + addressPostcode: Number( + record[ + `${addressFields.addressPostcode} (${field.name})` + ], + ), + addressState: + record[`${addressFields.addressState} (${field.name})`] || + '', + addressCountry: + record[ + `${addressFields.addressCountry} (${field.name})` + ] || '', + addressLat: Number( + record[`${addressFields.addressLat} (${field.name})`], + ), + addressLng: Number( + record[`${addressFields.addressLng} (${field.name})`], + ), }; } break; + } case FieldMetadataType.Link: if (value !== undefined) { fieldMapping[field.name] = {