From f149ff43b440a827003182d62a462fbb51d63c85 Mon Sep 17 00:00:00 2001 From: Ahmed Bouhuolia Date: Tue, 24 Feb 2026 20:53:14 +0200 Subject: [PATCH] feat(contacts): add country field to customer and vendor address forms Co-authored-by: Cursor --- .../src/modules/Contacts/types/Contacts.types.ts | 8 ++++---- .../modules/Customers/dtos/ContactAddress.dto.ts | 8 ++++---- .../src/modules/Vendors/dtos/EditVendor.dto.ts | 5 ++++- .../CustomerForm/CustomerAddressTabs.tsx | 16 ++++++++-------- .../CustomerForm/CustomerForm.schema.tsx | 8 ++++---- .../CustomerForm/CustomerFormFormik.tsx | 7 +++++-- .../CustomerForm/CustomerFormPrimarySection.tsx | 2 +- .../containers/Customers/CustomerForm/utils.tsx | 8 ++++---- .../Vendors/VendorForm/VendorForm.schema.tsx | 8 ++++---- .../Vendors/VendorForm/VendorFormFormik.tsx | 7 +++++-- .../src/containers/Vendors/VendorForm/utils.tsx | 8 ++++---- packages/webapp/src/utils/index.tsx | 14 ++++++++++++++ 12 files changed, 61 insertions(+), 38 deletions(-) diff --git a/packages/server/src/modules/Contacts/types/Contacts.types.ts b/packages/server/src/modules/Contacts/types/Contacts.types.ts index 1d5fd1016..352d69e15 100644 --- a/packages/server/src/modules/Contacts/types/Contacts.types.ts +++ b/packages/server/src/modules/Contacts/types/Contacts.types.ts @@ -10,7 +10,7 @@ export interface IContactAddress { billingAddressCity: string; billingAddressCountry: string; billingAddressEmail: string; - billingAddressZipcode: string; + billingAddressPostcode: string; billingAddressPhone: string; billingAddressState: string; @@ -19,7 +19,7 @@ export interface IContactAddress { shippingAddressCity: string; shippingAddressCountry: string; shippingAddressEmail: string; - shippingAddressZipcode: string; + shippingAddressPostcode: string; shippingAddressPhone: string; shippingAddressState: string; } @@ -29,7 +29,7 @@ export interface IContactAddressDTO { billingAddressCity?: string; billingAddressCountry?: string; billingAddressEmail?: string; - billingAddressZipcode?: string; + billingAddressPostcode?: string; billingAddressPhone?: string; billingAddressState?: string; @@ -38,7 +38,7 @@ export interface IContactAddressDTO { shippingAddressCity?: string; shippingAddressCountry?: string; shippingAddressEmail?: string; - shippingAddressZipcode?: string; + shippingAddressPostcode?: string; shippingAddressPhone?: string; shippingAddressState?: string; } diff --git a/packages/server/src/modules/Customers/dtos/ContactAddress.dto.ts b/packages/server/src/modules/Customers/dtos/ContactAddress.dto.ts index 8e4224eb6..8fc4da490 100644 --- a/packages/server/src/modules/Customers/dtos/ContactAddress.dto.ts +++ b/packages/server/src/modules/Customers/dtos/ContactAddress.dto.ts @@ -27,10 +27,10 @@ export class ContactAddressDto { @IsEmail() billingAddressEmail?: string; - @ApiProperty({ required: false, description: 'Billing address zipcode' }) + @ApiProperty({ required: false, description: 'Billing address postcode' }) @IsOptional() @IsString() - billingAddressZipcode?: string; + billingAddressPostcode?: string; @ApiProperty({ required: false, description: 'Billing address phone' }) @IsOptional() @@ -67,10 +67,10 @@ export class ContactAddressDto { @IsEmail() shippingAddressEmail?: string; - @ApiProperty({ required: false, description: 'Shipping address zipcode' }) + @ApiProperty({ required: false, description: 'Shipping address postcode' }) @IsOptional() @IsString() - shippingAddressZipcode?: string; + shippingAddressPostcode?: string; @ApiProperty({ required: false, description: 'Shipping address phone' }) @IsOptional() diff --git a/packages/server/src/modules/Vendors/dtos/EditVendor.dto.ts b/packages/server/src/modules/Vendors/dtos/EditVendor.dto.ts index 1396b948a..7497c6064 100644 --- a/packages/server/src/modules/Vendors/dtos/EditVendor.dto.ts +++ b/packages/server/src/modules/Vendors/dtos/EditVendor.dto.ts @@ -48,7 +48,10 @@ export class EditVendorDto extends ContactAddressDto { @IsString() personalPhone?: string; - @ApiProperty({ required: false, description: 'Additional notes about the vendor' }) + @ApiProperty({ + required: false, + description: 'Additional notes about the vendor', + }) @IsOptional() @IsString() note?: string; diff --git a/packages/webapp/src/containers/Customers/CustomerForm/CustomerAddressTabs.tsx b/packages/webapp/src/containers/Customers/CustomerForm/CustomerAddressTabs.tsx index 7005804c7..f73943c0a 100644 --- a/packages/webapp/src/containers/Customers/CustomerForm/CustomerAddressTabs.tsx +++ b/packages/webapp/src/containers/Customers/CustomerForm/CustomerAddressTabs.tsx @@ -27,20 +27,20 @@ const CustomerBillingAddress = ({}) => { {/*------------ Billing Address 1 -----------*/} } inline={true} > - + {/*------------ Billing Address 2 -----------*/} } inline={true} > - + {/*------------ Billing Address city -----------*/} { {/*------------ Shipping Address 1 -----------*/} } inline={true} > - + {/*------------ Shipping Address 2 -----------*/} } inline={true} > - + {/*------------ Shipping Address city -----------*/} diff --git a/packages/webapp/src/containers/Customers/CustomerForm/CustomerForm.schema.tsx b/packages/webapp/src/containers/Customers/CustomerForm/CustomerForm.schema.tsx index c18783e4a..40b05864f 100644 --- a/packages/webapp/src/containers/Customers/CustomerForm/CustomerForm.schema.tsx +++ b/packages/webapp/src/containers/Customers/CustomerForm/CustomerForm.schema.tsx @@ -25,16 +25,16 @@ const Schema = Yup.object().shape({ note: Yup.string().trim(), billing_address_country: Yup.string().trim(), - billing_address_1: Yup.string().trim(), - billing_address_2: Yup.string().trim(), + billing_address1: Yup.string().trim(), + billing_address2: Yup.string().trim(), billing_address_city: Yup.string().trim(), billing_address_state: Yup.string().trim(), billing_address_postcode: Yup.string().nullable(), billing_address_phone: Yup.string().nullable(), shipping_address_country: Yup.string().trim(), - shipping_address_1: Yup.string().trim(), - shipping_address_2: Yup.string().trim(), + shipping_address1: Yup.string().trim(), + shipping_address2: Yup.string().trim(), shipping_address_city: Yup.string().trim(), shipping_address_state: Yup.string().trim(), shipping_address_postcode: Yup.string().nullable(), diff --git a/packages/webapp/src/containers/Customers/CustomerForm/CustomerFormFormik.tsx b/packages/webapp/src/containers/Customers/CustomerForm/CustomerFormFormik.tsx index e8192963a..3689f3b25 100644 --- a/packages/webapp/src/containers/Customers/CustomerForm/CustomerFormFormik.tsx +++ b/packages/webapp/src/containers/Customers/CustomerForm/CustomerFormFormik.tsx @@ -8,7 +8,7 @@ import styled from 'styled-components'; import { CLASSES } from '@/constants/classes'; import { CreateCustomerForm, EditCustomerForm } from './CustomerForm.schema'; -import { compose, transformToForm, saveInvoke } from '@/utils'; +import { compose, transformToForm, saveInvoke, parseBoolean } from '@/utils'; import { useCustomerFormContext } from './CustomerFormProvider'; import { defaultInitialValues } from './utils'; @@ -60,7 +60,10 @@ function CustomerFormFormik({ // Handles the form submit. const handleFormSubmit = (values, formArgs) => { const { setSubmitting, resetForm } = formArgs; - const formValues = { ...values }; + const formValues = { + ...values, + active: parseBoolean(values.active, true), + }; const onSuccess = (res) => { AppToaster.show({ diff --git a/packages/webapp/src/containers/Customers/CustomerForm/CustomerFormPrimarySection.tsx b/packages/webapp/src/containers/Customers/CustomerForm/CustomerFormPrimarySection.tsx index 2f23a3a97..e969b75fd 100644 --- a/packages/webapp/src/containers/Customers/CustomerForm/CustomerFormPrimarySection.tsx +++ b/packages/webapp/src/containers/Customers/CustomerForm/CustomerFormPrimarySection.tsx @@ -55,7 +55,7 @@ export default function CustomerFormPrimarySection({}) { label={} inline={true} > - + {/*----------- Display Name -----------*/} diff --git a/packages/webapp/src/containers/Customers/CustomerForm/utils.tsx b/packages/webapp/src/containers/Customers/CustomerForm/utils.tsx index a6d17c45c..cc0f62577 100644 --- a/packages/webapp/src/containers/Customers/CustomerForm/utils.tsx +++ b/packages/webapp/src/containers/Customers/CustomerForm/utils.tsx @@ -23,16 +23,16 @@ export const defaultInitialValues = { active: true, billing_address_country: '', - billing_address_1: '', - billing_address_2: '', + billing_address1: '', + billing_address2: '', billing_address_city: '', billing_address_state: '', billing_address_postcode: '', billing_address_phone: '', shipping_address_country: '', - shipping_address_1: '', - shipping_address_2: '', + shipping_address1: '', + shipping_address2: '', shipping_address_city: '', shipping_address_state: '', shipping_address_postcode: '', diff --git a/packages/webapp/src/containers/Vendors/VendorForm/VendorForm.schema.tsx b/packages/webapp/src/containers/Vendors/VendorForm/VendorForm.schema.tsx index 6393481c3..891d415a8 100644 --- a/packages/webapp/src/containers/Vendors/VendorForm/VendorForm.schema.tsx +++ b/packages/webapp/src/containers/Vendors/VendorForm/VendorForm.schema.tsx @@ -18,16 +18,16 @@ const Schema = Yup.object().shape({ note: Yup.string().trim(), billing_address_country: Yup.string().trim(), - billing_address_1: Yup.string().trim(), - billing_address_2: Yup.string().trim(), + billing_address1: Yup.string().trim(), + billing_address2: Yup.string().trim(), billing_address_city: Yup.string().trim(), billing_address_state: Yup.string().trim(), billing_address_postcode: Yup.string().nullable(), billing_address_phone: Yup.string().nullable(), shipping_address_country: Yup.string().trim(), - shipping_address_1: Yup.string().trim(), - shipping_address_2: Yup.string().trim(), + shipping_address1: Yup.string().trim(), + shipping_address2: Yup.string().trim(), shipping_address_city: Yup.string().trim(), shipping_address_state: Yup.string().trim(), shipping_address_postcode: Yup.string().nullable(), diff --git a/packages/webapp/src/containers/Vendors/VendorForm/VendorFormFormik.tsx b/packages/webapp/src/containers/Vendors/VendorForm/VendorFormFormik.tsx index 51cfa1eff..afa33e102 100644 --- a/packages/webapp/src/containers/Vendors/VendorForm/VendorFormFormik.tsx +++ b/packages/webapp/src/containers/Vendors/VendorForm/VendorFormFormik.tsx @@ -21,7 +21,7 @@ import VendorFloatingActions from './VendorFloatingActions'; import { withCurrentOrganization } from '@/containers/Organization/withCurrentOrganization'; import { useVendorFormContext } from './VendorFormProvider'; -import { compose, transformToForm, safeInvoke } from '@/utils'; +import { compose, transformToForm, safeInvoke, parseBoolean } from '@/utils'; import { defaultInitialValues } from './utils'; import '@/style/pages/Vendors/Form.scss'; @@ -69,7 +69,10 @@ function VendorFormFormik({ // Handles the form submit. const handleFormSubmit = (values, form) => { const { setSubmitting, resetForm } = form; - const requestForm = { ...values }; + const requestForm = { + ...values, + active: parseBoolean(values.active, true), + }; setSubmitting(true); diff --git a/packages/webapp/src/containers/Vendors/VendorForm/utils.tsx b/packages/webapp/src/containers/Vendors/VendorForm/utils.tsx index 5be562763..ea57a30fd 100644 --- a/packages/webapp/src/containers/Vendors/VendorForm/utils.tsx +++ b/packages/webapp/src/containers/Vendors/VendorForm/utils.tsx @@ -22,16 +22,16 @@ export const defaultInitialValues = { active: true, billing_address_country: '', - billing_address_1: '', - billing_address_2: '', + billing_address1: '', + billing_address2: '', billing_address_city: '', billing_address_state: '', billing_address_postcode: '', billing_address_phone: '', shipping_address_country: '', - shipping_address_1: '', - shipping_address_2: '', + shipping_address1: '', + shipping_address2: '', shipping_address_city: '', shipping_address_state: '', shipping_address_postcode: '', diff --git a/packages/webapp/src/utils/index.tsx b/packages/webapp/src/utils/index.tsx index 24d7597ac..e579da0e8 100644 --- a/packages/webapp/src/utils/index.tsx +++ b/packages/webapp/src/utils/index.tsx @@ -84,6 +84,20 @@ export const handleBooleanChange = (handler) => { return (event) => handler(event.target.checked); }; +/** + * Parses a value to boolean (handles 1, 0, '1', '0', true, false). + * @param {*} value + * @param {boolean} defaultValue - value when empty/unknown + * @returns {boolean} + */ +export const parseBoolean = (value, defaultValue = false) => { + if (typeof value === 'boolean') return value; + if (value === 1 || value === '1') return true; + if (value === 0 || value === '0') return false; + if (value == null || value === '') return defaultValue; + return Boolean(value); +}; + /** Event handler that exposes the target element's value as a string. */ export const handleStringChange = (handler) => { return (event) => handler(event.target.value);