diff --git a/apps/storefront/src/hooks/dom/utils.ts b/apps/storefront/src/hooks/dom/utils.ts index c64a338b..ec6f8b37 100644 --- a/apps/storefront/src/hooks/dom/utils.ts +++ b/apps/storefront/src/hooks/dom/utils.ts @@ -11,6 +11,7 @@ import { B3LStorage, B3SStorage, calculateProductsPrice, + getActiveCurrencyInfo, getCalculatedProductPrice, getCookie, getProductOptionList, @@ -184,6 +185,8 @@ const addProductsToDraftQuote = async ( B3SStorage.get('B3CompanyInfo')?.id || B3SStorage.get('salesRepCompanyId') const customerGroupId = B3SStorage.get('B3CustomerInfo')?.customerGroupId + const { currency_code: currencyCode } = getActiveCurrencyInfo() + // fetch data with products IDs const { productsSearch } = await searchB2BProducts({ productIds: Array.from( @@ -193,6 +196,7 @@ const addProductsToDraftQuote = async ( ) ) ), + currencyCode, companyId, customerGroupId, }) @@ -318,10 +322,13 @@ const addProductFromProductPageToQuote = (setOpenPage: DispatchProps) => { const fn = +role === 99 || +role === 100 ? searchBcProducts : searchB2BProducts + const { currency_code: currencyCode } = getActiveCurrencyInfo() + const { productsSearch } = await fn({ productIds: [+productId], companyId, customerGroupId, + currencyCode, }) const newProductInfo: CustomFieldItems = diff --git a/apps/storefront/src/pages/address/shared/getAddressFields.ts b/apps/storefront/src/pages/address/shared/getAddressFields.ts index d99f1b22..36902a0d 100644 --- a/apps/storefront/src/pages/address/shared/getAddressFields.ts +++ b/apps/storefront/src/pages/address/shared/getAddressFields.ts @@ -110,7 +110,7 @@ const getBcAddressFields = async () => { const { accountFormFields } = await getB2BAccountFormFields(1) const addressFields = accountFormFields.filter( - (field: AccountFormFieldsItems) => field.groupName === 'Address' + (field: AccountFormFieldsItems) => field.groupId === 4 ) const bcAddressFields = getAccountFormFields(addressFields).address diff --git a/apps/storefront/src/pages/invoice/Invoice.tsx b/apps/storefront/src/pages/invoice/Invoice.tsx index 09f1d463..287c73c6 100644 --- a/apps/storefront/src/pages/invoice/Invoice.tsx +++ b/apps/storefront/src/pages/invoice/Invoice.tsx @@ -504,7 +504,7 @@ function Invoice() { handleViewInvoice(item.id, item.status) }} > - {item?.id || '-'} + {item?.invoiceNumber ? item?.invoiceNumber : item?.id} ), width: '8%', diff --git a/apps/storefront/src/pages/login/Login.tsx b/apps/storefront/src/pages/login/Login.tsx index 2aab03b0..ba09b3fc 100644 --- a/apps/storefront/src/pages/login/Login.tsx +++ b/apps/storefront/src/pages/login/Login.tsx @@ -20,14 +20,18 @@ import { superAdminEndMasquerade, } from '@/shared/service/b2b' import { b2bLogin, bcLogoutLogin, customerLoginAPI } from '@/shared/service/bc' +import { deleteCart, getCart } from '@/shared/service/bc/graphql/cart' +import { store } from '@/store' import { B3SStorage, + getCookie, getCurrentCustomerInfo, loginjump, logoutSession, snackbar, storeHash, } from '@/utils' +import { deleteCartData } from '@/utils/cartUtils' import LoginWidget from './component/LoginWidget' import { @@ -148,6 +152,28 @@ export default function Login(props: RegisteredProps) { snackbar.error(b3Lang('login.loginText.invoiceErrorTip')) } if (loginFlag === '3' && !isLogout) { + const cartEntityId: string = getCookie('cartId') + + const { + global: { + storeInfo: { platform }, + }, + } = store.getState() + + const cartInfo = cartEntityId + ? await getCart(cartEntityId, platform) + : null + + if (cartInfo) { + let newCartId = cartEntityId + if (cartInfo?.data && cartInfo?.data?.site) { + const { cart } = cartInfo.data.site + newCartId = cart?.entityId || cartEntityId + } + const deleteQuery = deleteCartData(newCartId) + await deleteCart(deleteQuery) + } + const { result } = (await bcLogoutLogin()).data.logout if (result !== 'success') return diff --git a/apps/storefront/src/pages/order/Order.tsx b/apps/storefront/src/pages/order/Order.tsx index f177f850..472057cb 100644 --- a/apps/storefront/src/pages/order/Order.tsx +++ b/apps/storefront/src/pages/order/Order.tsx @@ -117,7 +117,10 @@ function Order({ isCompanyOrder = false }: OrderProps) { const optionLabel = orderStatusTranslationVariables[option.systemLabel] const elementOption = option - elementOption.customLabel = b3Lang(optionLabel) + elementOption.customLabel = + b3Lang(optionLabel) === elementOption.systemLabel + ? elementOption.customLabel + : b3Lang(optionLabel) return option } @@ -259,11 +262,22 @@ function Order({ isCompanyOrder = false }: OrderProps) { } const handleFirterChange = (value: SearchChangeProps) => { + let currentStatus = value?.orderStatus || '' + if (currentStatus) { + const originStatus = getOrderStatuses.find( + (status) => + status.customLabel === currentStatus || + status.systemLabel === currentStatus + ) + + currentStatus = originStatus?.systemLabel || currentStatus + } + const search: Partial = { beginDateAt: value?.startValue || null, endDateAt: value?.endValue || null, createdBy: value?.PlacedBy || '', - statusCode: value?.orderStatus || '', + statusCode: currentStatus, companyName: value?.company || '', } setFilterData({ diff --git a/apps/storefront/src/pages/orderDetail/OrderDetail.tsx b/apps/storefront/src/pages/orderDetail/OrderDetail.tsx index 3d523618..559a0b46 100644 --- a/apps/storefront/src/pages/orderDetail/OrderDetail.tsx +++ b/apps/storefront/src/pages/orderDetail/OrderDetail.tsx @@ -27,6 +27,7 @@ import { OrderStatusResponse, } from '../../types' import OrderStatus from '../order/components/OrderStatus' +import { orderStatusTranslationVariables } from '../order/shared/getOrderStatus' import { OrderDetailsContext, @@ -193,9 +194,21 @@ function OrderDetail() { getAddressLabelPermission() }, []) - const getOrderStatusLabel = (status: string) => - orderStatus.find((item: OrderStatusItem) => item.systemLabel === status) - ?.customLabel || customStatus + const getOrderStatusLabel = (status: string) => { + const currentOrderStatus = orderStatus.find( + (item: OrderStatusItem) => item.systemLabel === status + ) + let activeStatusLabel = currentOrderStatus?.customLabel || customStatus + if (currentOrderStatus) { + const optionLabel = + orderStatusTranslationVariables[currentOrderStatus.systemLabel] + activeStatusLabel = + optionLabel && b3Lang(optionLabel) !== currentOrderStatus.systemLabel + ? b3Lang(optionLabel) + : activeStatusLabel + } + return activeStatusLabel + } return ( diff --git a/apps/storefront/src/pages/orderDetail/components/OrderHistory.tsx b/apps/storefront/src/pages/orderDetail/components/OrderHistory.tsx index 1766aa35..a117dbb8 100644 --- a/apps/storefront/src/pages/orderDetail/components/OrderHistory.tsx +++ b/apps/storefront/src/pages/orderDetail/components/OrderHistory.tsx @@ -11,6 +11,7 @@ import { RootState } from '@/store' import { OrderHistoryItem, OrderStatusItem } from '../../../types' import OrderStatus from '../../order/components/OrderStatus' +import { orderStatusTranslationVariables } from '../../order/shared/getOrderStatus' import { OrderDetailsContext } from '../context/OrderDetailsContext' const HistoryListContainer = styled('div')(() => ({ @@ -30,7 +31,7 @@ const HistoryListContainer = styled('div')(() => ({ export default function OrderHistory() { const b3Lang = useB3Lang() const { - state: { history = [], orderStatus: orderStatusLabel = [] }, + state: { history = [], orderStatus: orderStatusLabel = [], customStatus }, } = useContext(OrderDetailsContext) const lang = useSelector(({ lang }: RootState) => lang) @@ -41,10 +42,25 @@ export default function OrderHistory() { locale: lang, }) - const getOrderStatusLabel = (status: string) => - orderStatusLabel.find( + const getOrderStatusLabel = (status: string) => { + const currentOrderStatus = orderStatusLabel.find( (item: OrderStatusItem) => item.systemLabel === status - )?.customLabel || status + ) + + let activeStatusLabel = currentOrderStatus?.customLabel || customStatus + + if (currentOrderStatus) { + const optionLabel = + orderStatusTranslationVariables[currentOrderStatus.systemLabel] + + activeStatusLabel = + optionLabel && b3Lang(optionLabel) !== currentOrderStatus.systemLabel + ? b3Lang(optionLabel) + : activeStatusLabel + } + + return activeStatusLabel + } const columnItems: TableColumnItem[] = [ { diff --git a/apps/storefront/src/pages/pdp/PDP.tsx b/apps/storefront/src/pages/pdp/PDP.tsx index 28b2e641..50b1429e 100644 --- a/apps/storefront/src/pages/pdp/PDP.tsx +++ b/apps/storefront/src/pages/pdp/PDP.tsx @@ -23,7 +23,7 @@ import { import { globalStateSelector } from '@/store' import { B3SStorage, - getDefaultCurrencyInfo, + getActiveCurrencyInfo, getProductOptionList, getValidOptionsList, globalSnackbar, @@ -92,7 +92,7 @@ export const addProductsToShoppingList = async ({ gotoShoppingDetail, b3Lang, }: AddProductsToShoppingListParams) => { - const { currency_code: currencyCode } = getDefaultCurrencyInfo() + const { currency_code: currencyCode } = getActiveCurrencyInfo() const companyId = B3SStorage.get('B3CompanyInfo')?.id || B3SStorage.get('salesRepCompanyId') const getProducts = isB2BUser ? searchB2BProducts : searchBcProducts diff --git a/apps/storefront/src/pages/quickorder/components/QuickOrderFooter.tsx b/apps/storefront/src/pages/quickorder/components/QuickOrderFooter.tsx index a149bfd4..b70f4fcf 100644 --- a/apps/storefront/src/pages/quickorder/components/QuickOrderFooter.tsx +++ b/apps/storefront/src/pages/quickorder/components/QuickOrderFooter.tsx @@ -39,6 +39,7 @@ import { b3TriggerCartNumber, calculateProductListPrice, currencyFormat, + getActiveCurrencyInfo, getProductPriceIncTax, getValidOptionsList, snackbar, @@ -340,10 +341,13 @@ function QuickOrderFooter(props: QuickOrderFooterProps) { const getProducts = isB2BUser ? searchB2BProducts : searchBcProducts + const { currency_code: currencyCode } = getActiveCurrencyInfo() + const { productsSearch } = await getProducts({ productIds, companyId, customerGroupId, + currencyCode, }) const newProductInfo: CustomFieldItems = diff --git a/apps/storefront/src/pages/quickorder/components/QuickorderTable.tsx b/apps/storefront/src/pages/quickorder/components/QuickorderTable.tsx index 9540e6e2..1d7ad276 100644 --- a/apps/storefront/src/pages/quickorder/components/QuickorderTable.tsx +++ b/apps/storefront/src/pages/quickorder/components/QuickorderTable.tsx @@ -25,7 +25,7 @@ import { currencyFormat, displayFormat, distanceDay, - getDefaultCurrencyInfo, + getActiveCurrencyInfo, getProductPriceIncTax, snackbar, } from '@/utils' @@ -162,7 +162,7 @@ function QuickorderTable({ const b3Lang = useB3Lang() - const { currency_code: currencyCode } = getDefaultCurrencyInfo() + const { currency_code: currencyCode } = getActiveCurrencyInfo() const handleGetProductsById = async (listProducts: ListItemProps[]) => { if (listProducts.length > 0) { diff --git a/apps/storefront/src/pages/quote/QuoteDetail.tsx b/apps/storefront/src/pages/quote/QuoteDetail.tsx index bd89bf0f..8f9f3b1d 100644 --- a/apps/storefront/src/pages/quote/QuoteDetail.tsx +++ b/apps/storefront/src/pages/quote/QuoteDetail.tsx @@ -17,7 +17,7 @@ import { } from '@/shared/service/b2b' import { store, TaxZoneRates, TaxZoneRatesProps } from '@/store' import { - getDefaultCurrencyInfo, + getActiveCurrencyInfo, getSearchVal, getVariantInfoOOSAndPurchase, snackbar, @@ -69,7 +69,7 @@ function QuoteDetail() { }) const [isRequestLoading, setIsRequestLoading] = useState(false) const [isShowFooter, setIsShowFooter] = useState(false) - const { currency_code: currencyCode } = getDefaultCurrencyInfo() + const { currency_code: currencyCode } = getActiveCurrencyInfo() const [quoteDetailTax, setQuoteDetailTax] = useState(0) diff --git a/apps/storefront/src/pages/quote/QuoteDraft.tsx b/apps/storefront/src/pages/quote/QuoteDraft.tsx index 0709b60d..1b1ad8d1 100644 --- a/apps/storefront/src/pages/quote/QuoteDraft.tsx +++ b/apps/storefront/src/pages/quote/QuoteDraft.tsx @@ -37,7 +37,6 @@ import { B3LStorage, B3SStorage, getActiveCurrencyInfo, - getDefaultCurrencyInfo, snackbar, storeHash, } from '@/utils' @@ -515,8 +514,6 @@ function QuoteDraft({ setOpenPage }: QuoteDraftProps) { (item: CustomFieldItems) => item.sku === node.variantSku ) - // const salePrice = getBCPrice(+(node?.basePrice || 0), +(node?.taxPrice || 0)) - allPrice += +(node?.basePrice || 0) * +(node?.quantity || 0) allTaxPrice += +(node?.taxPrice || 0) * +(node?.quantity || 0) @@ -538,7 +535,7 @@ function QuoteDraft({ setOpenPage }: QuoteDraftProps) { } ) - const currency = getDefaultCurrencyInfo() + const currency = getActiveCurrencyInfo() const fileList = getFileList(info.fileInfo || []) diff --git a/apps/storefront/src/pages/quote/components/AddToQuote.tsx b/apps/storefront/src/pages/quote/components/AddToQuote.tsx index f4d5d96c..1cb4f2c2 100644 --- a/apps/storefront/src/pages/quote/components/AddToQuote.tsx +++ b/apps/storefront/src/pages/quote/components/AddToQuote.tsx @@ -103,8 +103,16 @@ export default function AddToQuote(props: AddToListProps) { const addToList = async (products: CustomFieldItems[]) => { const newProducts = getNewQuoteProduct(products) + const noSkuProducts = products.filter(({ sku, variantId, variants }) => { + const currentProduct = variants.find( + (item: CustomFieldItems) => + item.variant_id === variantId || item.variantId === variantId + ) + + const variantSku = currentProduct.sku - const noSkuProducts = products.filter(({ sku }) => !sku) + return !(sku || variantSku) + }) if (noSkuProducts.length > 0) { snackbar.error(b3Lang('quoteDraft.notification.cantAddProductsNoSku'), { isClose: true, @@ -154,7 +162,7 @@ export default function AddToQuote(props: AddToListProps) { addToQuote(newProducts) - snackbar.success(b3Lang('quoteDraft.notification.productPlural.'), { + snackbar.success(b3Lang('quoteDraft.notification.productPlural'), { isClose: true, }) diff --git a/apps/storefront/src/pages/quote/components/QuoteSummary.tsx b/apps/storefront/src/pages/quote/components/QuoteSummary.tsx index 02bbea5c..26f1bfad 100644 --- a/apps/storefront/src/pages/quote/components/QuoteSummary.tsx +++ b/apps/storefront/src/pages/quote/components/QuoteSummary.tsx @@ -49,7 +49,6 @@ const QuoteSummary = forwardRef((_, ref: Ref) => { const isHidePrice = getQuoteDraftShowPriceTBD(productList) setHideQuoteDraftPrice(isHidePrice) - const newQuoteSummary = productList.reduce( (summary: Summary, product: CustomFieldItems) => { const { basePrice, taxPrice: productTax = 0, quantity } = product.node diff --git a/apps/storefront/src/pages/registered/RegisterComplete.tsx b/apps/storefront/src/pages/registered/RegisterComplete.tsx index 320c016d..84d72e6f 100644 --- a/apps/storefront/src/pages/registered/RegisterComplete.tsx +++ b/apps/storefront/src/pages/registered/RegisterComplete.tsx @@ -115,7 +115,7 @@ export default function RegisterComplete(props: RegisterCompleteProps) { if (name === 'accepts_marketing_emails') { bcFields.accepts_product_review_abandoned_cart_emails = !!item?.default?.length - } else { + } else if (!item.custom) { bcFields[name] = item?.default || '' } }) @@ -199,6 +199,24 @@ export default function RegisterComplete(props: RegisterCompleteProps) { const b2bFields: CustomFieldItems = {} b2bFields.customerId = customerId || '' b2bFields.storeHash = storeHash + + // company user extra field + const b2bContactInformationList = list || [] + const companyUserExtraFieldsList = b2bContactInformationList.filter( + (item) => !!item.custom + ) + + if (companyUserExtraFieldsList.length) { + const companyUserExtraFields: Array = [] + companyUserExtraFieldsList.forEach((item: CustomFieldItems) => { + const itemExtraField: CustomFieldItems = {} + itemExtraField.fieldName = deCodeField(item.name) + itemExtraField.fieldValue = item?.default || '' + companyUserExtraFields.push(itemExtraField) + }) + b2bFields.userExtraFields = companyUserExtraFields + } + const companyInfo = companyInformation.filter( (list) => !list.custom && list.fieldType !== 'files' ) diff --git a/apps/storefront/src/pages/registered/RegisteredAccount.tsx b/apps/storefront/src/pages/registered/RegisteredAccount.tsx index 213fd28a..79c5190f 100644 --- a/apps/storefront/src/pages/registered/RegisteredAccount.tsx +++ b/apps/storefront/src/pages/registered/RegisteredAccount.tsx @@ -18,12 +18,16 @@ import { } from '@/components/outSideComponents/utils/b3CustomStyles' import { CustomStyleContext } from '@/shared/customStyleButtton' import { GlobaledContext } from '@/shared/global' -import { checkUserBCEmail, checkUserEmail } from '@/shared/service/b2b' +import { + checkUserBCEmail, + checkUserEmail, + validateBCCompanyUserExtraFields, +} from '@/shared/service/b2b' import { themeFrameSelector } from '@/store' import RegisteredStepButton from './component/RegisteredStepButton' import { RegisteredContext } from './context/RegisteredContext' -import { emailError, RegisterFields } from './config' +import { Base64, emailError, RegisterFields } from './config' import { InformationFourLabels, TipContent } from './styled' interface RegisteredAccountProps { @@ -106,6 +110,15 @@ export default function RegisteredAccount(props: RegisteredAccountProps) { ? additionalInfo[0]?.groupName : '' + const showLoading = (isShow = false) => { + dispatch({ + type: 'loading', + payload: { + isLoading: isShow, + }, + }) + } + const handleChange = (event: ChangeEvent) => { dispatch({ type: 'accountType', @@ -121,37 +134,46 @@ export default function RegisteredAccount(props: RegisteredAccountProps) { )?.name || 'email' const validateEmailValue = async (emailValue: string) => { - const isB2BUser = accountType === '1' - const fn = isB2BUser ? checkUserEmail : checkUserBCEmail - const key = isB2BUser ? 'userEmailCheck' : 'customerEmailCheck' - - const { - [key]: { userType, userInfo: { companyName = '' } = {} }, - }: CustomFieldItems = await fn({ - email: emailValue, - channelId: currentChannelId, - }) - - const isValid = isB2BUser ? [1].includes(userType) : ![2].includes(userType) + try { + showLoading(true) + const isB2BUser = accountType === '1' + const fn = isB2BUser ? checkUserEmail : checkUserBCEmail + const key = isB2BUser ? 'userEmailCheck' : 'customerEmailCheck' + + const { + [key]: { userType, userInfo: { companyName = '' } = {} }, + }: CustomFieldItems = await fn({ + email: emailValue, + channelId: currentChannelId, + }) - if (!isValid) { - setErrorTips( - b3Lang(emailError[userType], { - companyName: companyName || '', - email: emailValue, + const isValid = isB2BUser + ? [1].includes(userType) + : ![2].includes(userType) + + if (!isValid) { + setErrorTips( + b3Lang(emailError[userType], { + companyName: companyName ? `(${companyName})` : '', + email: emailValue, + }) + ) + setError(emailName, { + type: 'custom', + message: '', }) - ) - setError(emailName, { - type: 'custom', - message: '', - }) - IframeDocument?.body.scrollIntoView(true) - } else { - setErrorTips('') - } + IframeDocument?.body.scrollIntoView(true) + } else { + setErrorTips('') + } - return isValid + return isValid + } catch (error) { + return false + } finally { + showLoading(false) + } } const handleAccountToDetail = async (event: MouseEvent) => { @@ -172,6 +194,54 @@ export default function RegisteredAccount(props: RegisteredAccountProps) { return item }) + try { + showLoading(true) + if (accountType === '1') { + const extraCompanyUserInformation = newContactInfo.filter( + (item: RegisterFields) => !!item.custom + ) + const extraFields = extraCompanyUserInformation.map( + (field: RegisterFields) => ({ + fieldName: Base64.decode(field.name), + fieldValue: data[field.name] || field.default, + }) + ) + + const res = await validateBCCompanyUserExtraFields({ + extraFields, + }) + + if (res.code !== 200) { + const message = res.data?.errMsg || res.message || '' + + const messageArr = message.split(':') + + if (messageArr.length >= 2) { + const field = extraCompanyUserInformation.find( + (field: RegisterFields) => + Base64.decode(field.name) === messageArr[0] + ) + if (field) { + setError(field.name, { + type: 'manual', + message: messageArr[1], + }) + showLoading(false) + return + } + } + setErrorTips(message) + showLoading(false) + return + } + setErrorTips('') + } + } catch (error) { + console.log(error) + } finally { + showLoading(false) + } + let newAdditionalInformation: Array = [] if (additionalInfo) { newAdditionalInformation = ( diff --git a/apps/storefront/src/pages/registered/RegisteredBCToB2B.tsx b/apps/storefront/src/pages/registered/RegisteredBCToB2B.tsx index 41bb4a9c..e15af893 100644 --- a/apps/storefront/src/pages/registered/RegisteredBCToB2B.tsx +++ b/apps/storefront/src/pages/registered/RegisteredBCToB2B.tsx @@ -27,12 +27,14 @@ import { getB2BCountries, uploadB2BFile, validateBCCompanyExtraFields, + validateBCCompanyUserExtraFields, } from '../../shared/service/b2b' import { RegisteredContext } from './context/RegisteredContext' import { AccountFormFieldsItems, b2bAddressRequiredFields, + Base64, Country, deCodeField, getAccountFormFields, @@ -297,7 +299,15 @@ export default function RegisteredBCToB2B(props: RegisteredProps) { }) } + const handleInitCountryAndState = () => { + const countryValue = getValues('country') + const stateValue = getValues('state') + handleCountryChange(countryValue, stateValue) + } + useEffect(() => { + handleInitCountryAndState() + const subscription = watch((value, { name, type }) => { const { country, state } = value if (name === 'country' && type === 'change') { @@ -357,12 +367,14 @@ export default function RegisteredBCToB2B(props: RegisteredProps) { const getB2BFieldsValue = async ( data: CustomFieldItems, customerId: number | string, - fileList: any + fileList: any, + companyUserExtraFields: CustomFieldItems[] ) => { const b2bFields: CustomFieldItems = {} b2bFields.customerId = customerId || '' b2bFields.storeHash = storeHash + b2bFields.userExtraFields = companyUserExtraFields const companyInfo = bcTob2bCompanyInformation.filter( (list) => !list.custom && list.fieldType !== 'files' ) @@ -495,6 +507,70 @@ export default function RegisteredBCToB2B(props: RegisteredProps) { return false } + const handleResetBcTob2bContactInformation = (FieldName: string) => { + if (bcTob2bContactInformation) { + const newBcTob2bContactInformation = bcTob2bContactInformation.map( + (contactInformationField) => { + if (contactInformationField.name === FieldName) { + return { + ...contactInformationField, + disabled: false, + } + } + return contactInformationField + } + ) + + if (dispatch) { + dispatch({ + type: 'all', + payload: { + bcTob2bContactInformation: [...newBcTob2bContactInformation], + }, + }) + } + } + } + + const handleValidateCompanyUserExtraFields = async ( + extraFields: CustomFieldItems[] + ) => { + try { + const res = await validateBCCompanyUserExtraFields({ + extraFields, + }) + + if (res.code !== 200) { + const message = res.data?.errMsg || res.message || '' + + const messageArr = message.split(':') + + if (messageArr.length >= 2) { + const field = bcTob2bContactInformation?.find( + (field: RegisterFields) => + field.custom && Base64.decode(field.name) === messageArr[0] + ) + if (field) { + setError(field.name, { + type: 'manual', + message: messageArr[1], + }) + handleResetBcTob2bContactInformation(field.name) + showLoading(false) + return false + } + } + setErrorMessage(message) + showLoading(false) + return false + } + setErrorMessage('') + return true + } catch (error) { + return false + } + } + const handleNext = (event: MouseEvent) => { const hasAttachmentsFilesError = handleValidateAttachmentFiles() @@ -508,11 +584,38 @@ export default function RegisteredBCToB2B(props: RegisteredProps) { return } + // get company user extra field + const b2bContactInformationList = bcTob2bContactInformation || [] + const companyUserExtraFieldsList = b2bContactInformationList.filter( + (item) => !!item.custom + ) + + const companyUserExtraFields: Array = [] + if (companyUserExtraFieldsList.length) { + companyUserExtraFieldsList.forEach((item: CustomFieldItems) => { + const itemExtraField: CustomFieldItems = {} + itemExtraField.fieldName = deCodeField(item.name) + itemExtraField.fieldValue = data[item.name] || item?.default || '' + companyUserExtraFields.push(itemExtraField) + }) + } + + const isCompanyUserValidate = + await handleValidateCompanyUserExtraFields(companyUserExtraFields) + if (!isCompanyUserValidate) { + return + } + const attachmentsList = bcTob2bCompanyInformation.filter( (list) => list.fieldType === 'files' ) const fileList = await getFileUrl(attachmentsList || [], data) - await getB2BFieldsValue(data, customerId, fileList) + await getB2BFieldsValue( + data, + customerId, + fileList, + companyUserExtraFields + ) const isAuto = companyAutoApproval.enabled diff --git a/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx b/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx index ec72a96f..5308f4ec 100644 --- a/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx +++ b/apps/storefront/src/pages/shoppingListDetails/ShoppingListDetails.tsx @@ -26,7 +26,7 @@ import { } from '@/shared/service/b2b' import { calculateProductListPrice, - getDefaultCurrencyInfo, + getActiveCurrencyInfo, snackbar, } from '@/utils' import { getBCPrice } from '@/utils/b3Product/b3Product' @@ -133,10 +133,7 @@ function ShoppingListDetails({ setOpenPage }: ShoppingListDetailsProps) { navigate('/shoppingLists') } - const { - currency_code: currencyCode, - // token: currencyToken, - } = getDefaultCurrencyInfo() + const { currency_code: currencyCode } = getActiveCurrencyInfo() useEffect(() => { dispatch({ diff --git a/apps/storefront/src/pages/usermanagement/AddEditUser.tsx b/apps/storefront/src/pages/usermanagement/AddEditUser.tsx index 6c4c618a..ee0bc069 100644 --- a/apps/storefront/src/pages/usermanagement/AddEditUser.tsx +++ b/apps/storefront/src/pages/usermanagement/AddEditUser.tsx @@ -8,6 +8,7 @@ import { } from 'react' import { useForm } from 'react-hook-form' import { useB3Lang } from '@b3/lang' +import concat from 'lodash-es/concat' import { B3CustomForm, B3Dialog } from '@/components' import { GlobaledContext } from '@/shared/global' @@ -16,17 +17,23 @@ import { snackbar } from '@/utils' import { emailError, + ExtraFieldsProps, FilterProps, getUsersFiles, UsersFilesProps, UsersList, } from './config' +import getB2BUserExtraFields from './getUserExtraFields' interface AddEditUserProps { companyId: string | number renderList: () => void } +interface SelectedDataProps { + [key: string]: string | number +} + function AddEditUser( { companyId, renderList }: AddEditUserProps, ref: Ref | undefined @@ -43,6 +50,9 @@ function AddEditUser( const [addUpdateLoading, setAddUpdateLoading] = useState(false) const [usersFiles, setUsersFiles] = useState>([]) + const [userExtrafields, setUserExtrafields] = useState< + UsersFilesProps[] | [] + >([]) const b3Lang = useB3Lang() @@ -58,6 +68,35 @@ function AddEditUser( mode: 'onSubmit', }) + const handleGetUsersFiles = async () => { + const userExtrafields = await getB2BUserExtraFields() + setUserExtrafields(userExtrafields) + } + + useEffect(() => { + if (userExtrafields.length === 0) { + handleGetUsersFiles() + } + }, []) + + const handleGetExtrafieldsInfo = (selectedData: SelectedDataProps) => { + const keyValue = Object.keys(selectedData) + + const extrafields: ExtraFieldsProps[] = [] + userExtrafields.forEach((item: UsersFilesProps) => { + if (keyValue.includes(item.name)) { + const extraField = { + fieldName: item.name || '', + fieldValue: selectedData[item.name] || '', + } + + extrafields.push(extraField) + } + }) + + return extrafields + } + useEffect(() => { if (open && type === 'edit' && editData) { usersFiles.forEach((item: UsersFilesProps) => { @@ -69,6 +108,9 @@ function AddEditUser( const handleCancelClick = () => { usersFiles.forEach((item: UsersFilesProps) => { setValue(item.name, '') + if (item.isExtraFields) { + setValue(item.name, item.default || '') + } }) clearErrors() setOpen(false) @@ -92,7 +134,7 @@ function AddEditUser( setError('email', { type: 'custom', message: b3Lang(emailError[userType], { - companyName, + companyName: companyName ? `(${companyName})` : '', email: emailValue, }), }) @@ -107,13 +149,14 @@ function AddEditUser( const handleAddUserClick = () => { handleSubmit(async (data) => { setAddUpdateLoading(true) - + const extraFieldsInfo = handleGetExtrafieldsInfo(data) let message = b3Lang('userManagement.addUserSuccessfully') try { const params: Partial = { companyId, ...data, + extraFields: extraFieldsInfo, } if (type !== 'edit') { @@ -154,14 +197,31 @@ function AddEditUser( const handleOpenAddEditUserClick = (type: string, data: UsersList) => { if (type === 'edit') { - setEditData(data) + const extrafieldsInfo: ExtraFieldsProps[] = data.extraFields || [] + let newData = data + if (extrafieldsInfo && extrafieldsInfo.length > 0) { + const extrafieldsData: CustomFieldItems = {} + + extrafieldsInfo.forEach((item) => { + extrafieldsData[item.fieldName] = item.fieldValue + }) + + newData = { + ...data, + ...extrafieldsData, + } + } + + setEditData(newData) } const usersFiles = getUsersFiles( type, b3Lang, type === 'edit' ? +B3UserId === +data.id : false ) - setUsersFiles(usersFiles) + + const allUsersFiles = concat(usersFiles, userExtrafields) + setUsersFiles(allUsersFiles) setType(type) setOpen(true) } diff --git a/apps/storefront/src/pages/usermanagement/Usermanagement.tsx b/apps/storefront/src/pages/usermanagement/Usermanagement.tsx index a5b4941b..adfddc69 100644 --- a/apps/storefront/src/pages/usermanagement/Usermanagement.tsx +++ b/apps/storefront/src/pages/usermanagement/Usermanagement.tsx @@ -36,6 +36,7 @@ function Usermanagement() { phone: '', role: 0, updatedAt: 0, + extraFields: [], }) const b3Lang = useB3Lang() diff --git a/apps/storefront/src/pages/usermanagement/config.ts b/apps/storefront/src/pages/usermanagement/config.ts index 6b079d23..321d6355 100644 --- a/apps/storefront/src/pages/usermanagement/config.ts +++ b/apps/storefront/src/pages/usermanagement/config.ts @@ -1,5 +1,10 @@ import { LangFormatFunction } from '@b3/lang' +interface ExtraFieldsProps { + fieldName: string + fieldValue: string | number +} + interface UsersListItems { createdAt: number email: string @@ -9,7 +14,8 @@ interface UsersListItems { phone: string role: number updatedAt: number - [key: string]: string | null | number + extraFields: ExtraFieldsProps[] + [key: string]: string | null | number | ExtraFieldsProps[] } interface FilterProps { @@ -19,7 +25,7 @@ interface FilterProps { role: number | string companyId: number | string addChannel: boolean - [key: string]: string | null | number | boolean + [key: string]: string | null | number | boolean | ExtraFieldsProps[] } type UsersList = UsersListItems @@ -145,4 +151,10 @@ const emailError: EmailError = { export { emailError, getFilterMoreList, getUserRole, getUsersFiles } -export type { FilterProps, UserRoleProps, UsersFilesProps, UsersList } +export type { + FilterProps, + UserRoleProps, + UsersFilesProps, + UsersList, + ExtraFieldsProps, +} diff --git a/apps/storefront/src/pages/usermanagement/getUserExtraFields.ts b/apps/storefront/src/pages/usermanagement/getUserExtraFields.ts new file mode 100644 index 00000000..b4c30453 --- /dev/null +++ b/apps/storefront/src/pages/usermanagement/getUserExtraFields.ts @@ -0,0 +1,106 @@ +import { getUsersExtraFieldsInfo } from '@/shared/service/b2b' + +interface B2bExtraFieldsProps { + defaultValue: string + fieldName: string + fieldType: 0 | 1 | 2 | 3 + isRequired: boolean + labelName: string + listOfValue: null | Array + maximumLength: string | number | null + maximumValue: string | number | null + numberOfRows: string | number | null + visibleToEnduser: boolean +} + +interface FieldsOptionProps { + label: string + value: string | number +} + +interface FormattedItemsProps { + [key: string]: string | boolean | number | Array | boolean | undefined + name: string +} + +const FIELD_TYPE = { + 0: 'text', + 1: 'multiline', + 2: 'number', + 3: 'dropdown', +} + +const handleConversionExtraItemFormat = ( + userExtraFields: B2bExtraFieldsProps[] +) => { + const formattedUserExtraFields: FormattedItemsProps[] = userExtraFields.map( + (item: B2bExtraFieldsProps) => { + const { listOfValue } = item + const type = FIELD_TYPE[item.fieldType] + + const currentItems: FormattedItemsProps = { + isExtraFields: true, + name: item.fieldName, + label: item.labelName, + required: item.isRequired, + default: item.defaultValue || '', + fieldType: type, + xs: 12, + variant: 'filled', + size: 'small', + } + + switch (type) { + case 'dropdown': + if (listOfValue) { + const options: FieldsOptionProps[] = listOfValue?.map( + (option: string) => ({ + label: option, + value: option, + }) + ) + + if (options.length > 0) { + currentItems.options = options + } + } + + break + case 'number': + currentItems.max = item.maximumValue || '' + break + case 'mutiline': + currentItems.rows = item.numberOfRows || '' + break + default: + currentItems.maxLength = item.maximumLength || '' + break + } + + return currentItems + } + ) + + return formattedUserExtraFields +} + +const getB2BUserExtraFields = async () => { + let userExtraFieldsList: FormattedItemsProps[] = [] + try { + const { userExtraFields } = await getUsersExtraFieldsInfo() + const visibleFields = userExtraFields.filter( + (item: B2bExtraFieldsProps) => item.visibleToEnduser + ) + + const formattedUserExtraFields = + handleConversionExtraItemFormat(visibleFields) + + userExtraFieldsList = formattedUserExtraFields + } catch (err) { + console.error(err) + } + + return userExtraFieldsList +} + +export default getB2BUserExtraFields diff --git a/apps/storefront/src/shared/routes/routes.ts b/apps/storefront/src/shared/routes/routes.ts index 2fbfa7fa..a4784b62 100644 --- a/apps/storefront/src/shared/routes/routes.ts +++ b/apps/storefront/src/shared/routes/routes.ts @@ -297,7 +297,7 @@ const firstLevelRouting: RouteFirstLevelItem[] = [ const denyInvoiceRoles = [4, 99, 100] -const invoiceFlag = 'invoice?invoiceId' +const invoiceTypes = ['invoice?invoiceId', 'invoice?receiptId'] const { hash, pathname, href } = window.location @@ -395,7 +395,11 @@ const gotoAllowedAppPage = async ( gotoPage('/login?loginFlag=3&&closeIsLogout=1') return } - if (denyInvoiceRoles.includes(role) && href.includes(invoiceFlag)) { + + const isInvoicePage = () => + invoiceTypes.some((type: string) => href.includes(type)) + + if (denyInvoiceRoles.includes(role) && isInvoicePage()) { gotoPage('/login?loginFlag=7') return } @@ -431,7 +435,7 @@ const gotoAllowedAppPage = async ( } const flag = routes.some((item: RouteItem) => { - if (matchPath(item.path, url) || url.includes(invoiceFlag)) { + if (matchPath(item.path, url) || isInvoicePage()) { return item.permissions.includes(role) } return false diff --git a/apps/storefront/src/shared/service/b2b/api/register.ts b/apps/storefront/src/shared/service/b2b/api/register.ts index 2e7b5f29..217c20cd 100644 --- a/apps/storefront/src/shared/service/b2b/api/register.ts +++ b/apps/storefront/src/shared/service/b2b/api/register.ts @@ -15,3 +15,11 @@ export const validateBCCompanyExtraFields = ( ...data, storeHash, }) + +export const validateBCCompanyUserExtraFields = ( + data: CustomFieldItems +): CustomFieldItems => + B3Request.post('/api/v2/extra-fields/user/validate', RequestType.B2BRest, { + ...data, + storeHash, + }) diff --git a/apps/storefront/src/shared/service/b2b/graphql/product.ts b/apps/storefront/src/shared/service/b2b/graphql/product.ts index 875a41bb..5e0d7ce8 100644 --- a/apps/storefront/src/shared/service/b2b/graphql/product.ts +++ b/apps/storefront/src/shared/service/b2b/graphql/product.ts @@ -1,4 +1,9 @@ -import { B3SStorage, convertArrayToGraphql, storeHash } from '@/utils' +import { + B3SStorage, + convertArrayToGraphql, + getActiveCurrencyInfo, + storeHash, +} from '@/utils' import B3Request from '../../request/b3Fetch' @@ -177,17 +182,29 @@ export const getB2BVariantSkuByProductId = ( export const searchB2BProducts = ( data: CustomFieldItems = {} -): CustomFieldItems => - B3Request.graphqlB2B({ - query: searchProducts(data), +): CustomFieldItems => { + const { currency_code: currencyCode } = getActiveCurrencyInfo() + + return B3Request.graphqlB2B({ + query: searchProducts({ + ...data, + currencyCode: data?.currencyCode || currencyCode, + }), }) +} export const searchBcProducts = ( data: CustomFieldItems = {} -): CustomFieldItems => - B3Request.graphqlB2B({ - query: searchProducts(data), +): CustomFieldItems => { + const { currency_code: currencyCode } = getActiveCurrencyInfo() + + return B3Request.graphqlB2B({ + query: searchProducts({ + ...data, + currencyCode: data?.currencyCode || currencyCode, + }), }) +} export const getBcVariantInfoBySkus = ( data: CustomFieldItems = {} diff --git a/apps/storefront/src/shared/service/b2b/graphql/register.ts b/apps/storefront/src/shared/service/b2b/graphql/register.ts index 24683132..18ae0ab7 100644 --- a/apps/storefront/src/shared/service/b2b/graphql/register.ts +++ b/apps/storefront/src/shared/service/b2b/graphql/register.ts @@ -1,4 +1,4 @@ -import { channelId,convertArrayToGraphql, storeHash } from '../../../../utils' +import { channelId, convertArrayToGraphql, storeHash } from '../../../../utils' import B3Request from '../../request/b3Fetch' const getAccountFormFields = (type: number) => `{ @@ -110,6 +110,11 @@ const createCompanyUser = (data: any) => `mutation{ )}` : '' } + ${ + data?.userExtraFields + ? `userExtraFields: ${convertArrayToGraphql(data.userExtraFields)}` + : '' + } }) { company { id, diff --git a/apps/storefront/src/shared/service/b2b/graphql/users.ts b/apps/storefront/src/shared/service/b2b/graphql/users.ts index 63a7b065..93c75e25 100644 --- a/apps/storefront/src/shared/service/b2b/graphql/users.ts +++ b/apps/storefront/src/shared/service/b2b/graphql/users.ts @@ -1,4 +1,4 @@ -import { storeHash } from '../../../../utils' +import { convertArrayToGraphql, storeHash } from '../../../../utils' import B3Request from '../../request/b3Fetch' const getUsersQl = (data: CustomFieldItems) => `{ @@ -26,6 +26,10 @@ const getUsersQl = (data: CustomFieldItems) => `{ bcId, role, uuid, + extraFields{ + fieldName + fieldValue + } } } } @@ -42,6 +46,7 @@ const addOrUpdateUsersQl = (data: CustomFieldItems) => `mutation{ role: ${data.role} ${data?.userId ? `userId: ${data.userId}` : ''} ${data?.addChannel ? `addChannel: ${data.addChannel}` : ''} + extraFields: ${convertArrayToGraphql(data?.extraFields || [])} } ){ user{ @@ -92,11 +97,31 @@ const checkCustomerBCEmail = (data: CustomFieldItems) => `{ } }` +const getUserExtraFields = () => `{ + userExtraFields { + fieldName + fieldType + isRequired + defaultValue + maximumLength + numberOfRows + maximumValue + listOfValue + visibleToEnduser + labelName + } +}` + export const getUsers = (data: CustomFieldItems): CustomFieldItems => B3Request.graphqlB2B({ query: getUsersQl(data), }) +export const getUsersExtraFieldsInfo = (): CustomFieldItems => + B3Request.graphqlB2B({ + query: getUserExtraFields(), + }) + export const addOrUpdateUsers = (data: CustomFieldItems): CustomFieldItems => B3Request.graphqlB2B({ query: addOrUpdateUsersQl(data), diff --git a/apps/storefront/src/shared/service/b2b/index.ts b/apps/storefront/src/shared/service/b2b/index.ts index 8d767dff..4666dff7 100644 --- a/apps/storefront/src/shared/service/b2b/index.ts +++ b/apps/storefront/src/shared/service/b2b/index.ts @@ -6,6 +6,7 @@ import { createBCCompanyUser, sendSubscribersState, validateBCCompanyExtraFields, + validateBCCompanyUserExtraFields, } from './api/register' import { createB2BAddress, @@ -112,6 +113,7 @@ import { checkUserEmail, deleteUsers, getUsers, + getUsersExtraFieldsInfo, } from './graphql/users' export { @@ -209,6 +211,7 @@ export { getTaxZoneRates, getUserCompany, getUsers, + getUsersExtraFieldsInfo, guestProductsBulkUploadCSV, quoteDetailAttachFileCreate, quoteDetailAttachFileDelete, @@ -231,6 +234,7 @@ export { uploadB2BFile, validateAddressExtraFields, validateBCCompanyExtraFields, + validateBCCompanyUserExtraFields, } export { default as getProxyInfo } from './api/proxy' diff --git a/apps/storefront/src/utils/b3AddToShoppingList.ts b/apps/storefront/src/utils/b3AddToShoppingList.ts index 72819192..0d587770 100644 --- a/apps/storefront/src/utils/b3AddToShoppingList.ts +++ b/apps/storefront/src/utils/b3AddToShoppingList.ts @@ -6,27 +6,12 @@ import { conversionProductsList } from './b3Product/shared/config' export const handleGetCurrentProductInfo = async ( productId: number | string ) => { - const currencies = B3SStorage.get('currencies') const companyId = B3SStorage.get('B3CompanyInfo')?.id || B3SStorage.get('salesRepCompanyId') const customerGroupId = B3SStorage.get('B3CustomerInfo')?.customerGroupId - let currencyCode = '$' - if (currencies) { - const { currencies: currencyArr } = currencies - - const defaultCurrency = currencyArr.find( - (currency: any) => currency.is_default - ) - - const { currency_code: Code } = defaultCurrency - - currencyCode = Code - } - const { productsSearch } = await searchB2BProducts({ productIds: [+productId], - currencyCode, companyId, customerGroupId, }) diff --git a/apps/storefront/src/utils/b3CurrencyFormat.ts b/apps/storefront/src/utils/b3CurrencyFormat.ts index 8728c79f..20fba43e 100644 --- a/apps/storefront/src/utils/b3CurrencyFormat.ts +++ b/apps/storefront/src/utils/b3CurrencyFormat.ts @@ -124,11 +124,15 @@ export const currencyFormatConvert = ( } } -const currencyFormat = (price: string | number, showCurrencyToken = true) => { +const currencyFormat = ( + price: string | number, + showCurrencyToken = true, + isConversionRate = false +) => { const moneyFormat: MoneyFormat = currencyFormatInfo() try { const [integerPart, decimalPart] = ( - +price * +moneyFormat.currency_exchange_rate + isConversionRate ? +price * +moneyFormat.currency_exchange_rate : +price ) .toFixed(moneyFormat.decimal_places) .split('.') diff --git a/apps/storefront/src/utils/b3Product/b3Product.ts b/apps/storefront/src/utils/b3Product/b3Product.ts index 003bd744..7d7af45a 100644 --- a/apps/storefront/src/utils/b3Product/b3Product.ts +++ b/apps/storefront/src/utils/b3Product/b3Product.ts @@ -24,7 +24,6 @@ import { B3LStorage, B3SStorage, getActiveCurrencyInfo, - getDefaultCurrencyInfo, storeHash, } from '@/utils' @@ -320,7 +319,7 @@ const getExtraProductPricesProducts = async ( picklistIds: number[] ) => { const getProducts = isB2BUser ? searchB2BProducts : searchBcProducts - const { currency_code: currencyCode } = getDefaultCurrencyInfo() + const { currency_code: currencyCode } = getActiveCurrencyInfo() const { productsSearch: picklistProductsSearch } = await getProducts({ productIds: picklistIds, currencyCode, @@ -419,7 +418,7 @@ const getNewProductsList = async ( isB2BUser: boolean ) => { try { - const { currency_code: currencyCode } = getDefaultCurrencyInfo() + const { currency_code: currencyCode } = getActiveCurrencyInfo() if (listProducts.length > 0) { const productIds: number[] = [] listProducts.forEach((item) => { @@ -675,7 +674,8 @@ const getCalculatedProductPrice = async ( { optionList, productsSearch, sku, qty }: CalculatedProductPrice, calculatedValue?: CustomFieldItems ) => { - const { decimal_places: decimalPlaces = 2 } = getActiveCurrencyInfo() + const { decimal_places: decimalPlaces = 2, currency_code: currencyCode } = + getActiveCurrencyInfo() const { variants = [] } = productsSearch @@ -694,7 +694,7 @@ const getCalculatedProductPrice = async ( const data = { channel_id: channelId, - currency_code: getDefaultCurrencyInfo().currency_code, + currency_code: currencyCode, items, customer_group_id: customerGroupId, } @@ -821,7 +821,8 @@ const calculateProductsPrice = async ( products: ShoppingListProductItem[], calculatedValue: CustomFieldItems[] = [] ) => { - const { decimal_places: decimalPlaces = 2 } = getActiveCurrencyInfo() + const { decimal_places: decimalPlaces = 2, currency_code: currencyCode } = + getActiveCurrencyInfo() let calculatedPrices = calculatedValue const { variants, items } = formatLineItemsToGetPrices(lineItems, products) @@ -832,7 +833,7 @@ const calculateProductsPrice = async ( if (calculatedValue.length === 0) { const data = { channel_id: B3SStorage.get('B3channelId'), - currency_code: getDefaultCurrencyInfo().currency_code, + currency_code: currencyCode, customer_group_id: getCustomerGroupId(), items, } @@ -880,7 +881,8 @@ const calculateProductListPrice = async ( products: Partial[], type = '1' ) => { - const { decimal_places: decimalPlaces = 2 } = getActiveCurrencyInfo() + const { decimal_places: decimalPlaces = 2, currency_code: currencyCode } = + getActiveCurrencyInfo() try { let isError = false let i = 0 @@ -944,7 +946,7 @@ const calculateProductListPrice = async ( const data = { channel_id: channelId, - currency_code: getDefaultCurrencyInfo().currency_code, + currency_code: currencyCode, items: itemsOptions, customer_group_id: customerGroupId, } diff --git a/packages/lang/locales/en.json b/packages/lang/locales/en.json index 285d7e92..904bbdce 100644 --- a/packages/lang/locales/en.json +++ b/packages/lang/locales/en.json @@ -56,7 +56,7 @@ "global.registerFinish.blockPendingAccountOrderCreation.tip": "Your business account is pending approval. Ordering will be enabled after account approval", "global.loginText.emailAddress": "Email address", "global.emailValidate.multipleCustomer": "This email is used by multiple customers in your store. Please use another email.", - "global.emailValidate.companyUsed": "This email is used by a customer within another company ({companyName}).", + "global.emailValidate.companyUsed": "This email is used by a customer within another company. {companyName}", "global.emailValidate.alreadyExits": "This user already exists in this company.", "global.emailValidate.usedSuperAdmin": "This email is used by a super admin.", "global.emailValidate.emailLength": "Email length cannot exceed 200 characters",