diff --git a/CHANGELOG.MD b/CHANGELOG.MD index d31d90c54..adcb11b93 100644 --- a/CHANGELOG.MD +++ b/CHANGELOG.MD @@ -1,144 +1,144 @@ -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) -and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -### Fixed -- The card refund method is valid only if the customer has paid for the order with the card. -- Fix shipping value available in frontend -- Fix shipping value refunded in frontend -- Email fixes -- The total value of the products was multiplied by 100 in frontend -- The value of the product available for refund is displayed as "NAN" if the product did not have the tax set -- "Submitted by" was blank in history timeline because of a prop. -- Check to prevent users from viewing other users' return requests. - - -### Fixed -- Profile request for production environment -- Fix requests schema for older requests - -### Fixed -- Access for telesales user -- GetProfile request from FE switched back to fetch instead of axios. -- Quantity and availability of a product if there is already a return request placed for that product. - -### Fixed -- totalPrice for partial requests - -### Changes -- Get requests method has been changed to `searchDocumentsWithPaginationInfo` - -### Added -- Cache-control: no-cache on middlewares -- Navigation has been added in admin area to keep users on the same page when they open a request - -### Fixed - -- Update the refundedShippingValue in the front if it was declared via API. -- Filter correctly the available orders to request on MyReturnsPageAdd. - -### Fixed - -- Fixed orders available to show. -- Fixed API for verify package. - -### Added - -- API to verify package setting restock fee and shipping value to refund -### Fixed -- Fix build errors - -### Added - -- I18n It - -- Add validation to remove orders that have already been returned through the OMS - -### Added - -- Add the posibility of refund a partial amount for each product (Restock Fee) -- Add the posibility of refund the total or partial value of the order shipping - -### Fixed - -- Denied items does not show up in the OMS as returned anymore - -### Added - -- Update return labels to be saved as part of request -- Add ability to view shipping labels on both customer and admin sides - -### Added - -- Update status history timeline to be adaptive - -### Added - -- Add tax logic to credit card returns - -### Removed - -- Removed label creation button from customer side - -### Added - -- Added dropdown for customers to specify condition of the product they are returning - -## [2.1.0] - 2021-08-27 - -### Added - -- Added ability to deny a return request in the request status dropdown - -### Fixed - -- Fix return requests being automatically denied -- Fix inability to save max days in settings -- Fix missing Beneficiary Name on request page -- Changed zip and state fields to be optional for international returns -- Fix re-rendering on initial install - -## [2.0.0] - 2021-08-25 - -### Added - -- Add Easypost integration to create shipping labels -- Add refund method with credit cards - -## [1.1.0] - 2017-07-02 - -### Added - -- New custom return options -- New extra request comment -- New scroll to top when navigating My account section -- Fixed 'null' user's address number -- Fixed admin settings layout -- Fixed outstanding requests with missing products -- Fixed cross checking outstanding requests with eligible orders - -## [1.0.11] - 2021-06-12 - -### Added - -- New CSS Handles for the My account section - -## [1.0.10] - 2017-06-20 - -### Added - -- Fix messages warn -- Code improvement -- Improve loading time -- Different client for masterdata -- Fix products schema for older versions - -### Added - -- Auto-update schemas -- Payment method settings - display or hide payment methods +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) +and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Fixed +- The card refund method is valid only if the customer has paid for the order with the card. +- Fix shipping value available in frontend +- Fix shipping value refunded in frontend +- Email fixes +- The total value of the products was multiplied by 100 in frontend +- The value of the product available for refund is displayed as "NAN" if the product did not have the tax set +- "Submitted by" was blank in history timeline because of a prop. +- Check to prevent users from viewing other users' return requests. + + +### Fixed +- Profile request for production environment +- Fix requests schema for older requests + +### Fixed +- Access for telesales user +- GetProfile request from FE switched back to fetch instead of axios. +- Quantity and availability of a product if there is already a return request placed for that product. + +### Fixed +- totalPrice for partial requests + +### Changes +- Get requests method has been changed to `searchDocumentsWithPaginationInfo` + +### Added +- Cache-control: no-cache on middlewares +- Navigation has been added in admin area to keep users on the same page when they open a request + +### Fixed + +- Update the refundedShippingValue in the front if it was declared via API. +- Filter correctly the available orders to request on MyReturnsPageAdd. + +### Fixed + +- Fixed orders available to show. +- Fixed API for verify package. + +### Added + +- API to verify package setting restock fee and shipping value to refund +### Fixed +- Fix build errors + +### Added + +- I18n It + +- Add validation to remove orders that have already been returned through the OMS + +### Added + +- Add the posibility of refund a partial amount for each product (Restock Fee) +- Add the posibility of refund the total or partial value of the order shipping + +### Fixed + +- Denied items does not show up in the OMS as returned anymore + +### Added + +- Update return labels to be saved as part of request +- Add ability to view shipping labels on both customer and admin sides + +### Added + +- Update status history timeline to be adaptive + +### Added + +- Add tax logic to credit card returns + +### Removed + +- Removed label creation button from customer side + +### Added + +- Added dropdown for customers to specify condition of the product they are returning + +## [2.1.0] - 2021-08-27 + +### Added + +- Added ability to deny a return request in the request status dropdown + +### Fixed + +- Fix return requests being automatically denied +- Fix inability to save max days in settings +- Fix missing Beneficiary Name on request page +- Changed zip and state fields to be optional for international returns +- Fix re-rendering on initial install + +## [2.0.0] - 2021-08-25 + +### Added + +- Add Easypost integration to create shipping labels +- Add refund method with credit cards + +## [1.1.0] - 2017-07-02 + +### Added + +- New custom return options +- New extra request comment +- New scroll to top when navigating My account section +- Fixed 'null' user's address number +- Fixed admin settings layout +- Fixed outstanding requests with missing products +- Fixed cross checking outstanding requests with eligible orders + +## [1.0.11] - 2021-06-12 + +### Added + +- New CSS Handles for the My account section + +## [1.0.10] - 2017-06-20 + +### Added + +- Fix messages warn +- Code improvement +- Improve loading time +- Different client for masterdata +- Fix products schema for older versions + +### Added + +- Auto-update schemas +- Payment method settings - display or hide payment methods diff --git a/common/constants.ts b/common/constants.ts index 9e7d8f668..7f7863f29 100644 --- a/common/constants.ts +++ b/common/constants.ts @@ -6,6 +6,7 @@ export const SETTINGS_SCHEMA = { paymentCard: { type: 'boolean' }, paymentVoucher: { type: 'boolean' }, termsUrl: { type: 'string' }, + allowSMSLinkIntegration: { type: 'boolean' }, options: { type: 'array', items: { $ref: '#/$defs/options' }, @@ -29,6 +30,7 @@ export const SETTINGS_SCHEMA = { 'v-security': { allowGetAll: true, publicFilter: [ + 'allowSMSLinkIntegration', 'maxDays', 'excludedCategories', 'paymentBank', @@ -44,6 +46,7 @@ export const SETTINGS_SCHEMA = { 'v-default-fields': [ 'id', 'createdIn', + 'allowSMSLinkIntegration', 'maxDays', 'excludedCategories', 'paymentBank', @@ -56,6 +59,7 @@ export const SETTINGS_SCHEMA = { 'v-indexed': [ 'id', 'createdIn', + 'allowSMSLinkIntegration', 'maxDays', 'excludedCategories', 'paymentBank', diff --git a/docs/README.md b/docs/README.md index 4a777bf5f..8b5eab825 100644 --- a/docs/README.md +++ b/docs/README.md @@ -6,13 +6,14 @@ VTEX Return App - Open the VTEX App Store and install this app on your store, or run the following command on VTEX toolbelt: -> vtex install vtex.return-app@1.x +> vtex install vtex.return-app@2.x - From the left side access the `Returns > Requests` page. The first time you access it, the application creates the masterdata schema and settings it needs automatically. ## Settings - Go to `Returns > Returns Settings` and fill up the form with the settings you need. + - `Enable SMSLink integration`: Allow SMSLink integration. Customers will receive messages when a new return request is registered or the request reaches the states of: picked up, approved or denied. For this option you also need to install `vtex.smslink`. - `Max days:` The maximum number of days that customers can request the return of products, from the moment the order was invoiced. - `Terms and conditions URL:` The URL of the page with the return terms and conditions. The customer can access this URL from the form they fill out to request a return. - If you have the terms on conditions page on `http://example.com/terms-and-conditions` it's enough for you to type just `/terms-and-conditions` @@ -26,7 +27,7 @@ The return application serves the necessary functionalities for requesting retur #### Installation and configuration -The application can be installed using the following command in VTEX Toolbelt: `vtex install vtex.return-app@0.x` +The application can be installed using the following command in VTEX Toolbelt: `vtex install vtex.return-app@2.x` After the installation you must access the `Returns > Requests` page from the admin menu. At this point, the application creates the masterdata schema and email templates automatically. diff --git a/manifest.json b/manifest.json index 95673b9fa..5b8c0b22c 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "vendor": "vtex", "name": "return-app", - "version": "2.16.1", + "version": "2.16.2", "title": "Return app", "description": "Return app", "dependencies": { diff --git a/messages/context.json b/messages/context.json index 02420b526..466573b4b 100644 --- a/messages/context.json +++ b/messages/context.json @@ -4,6 +4,7 @@ "navigation.requestInfo": "Request Info", "navigation.labelSettings": "Returns Settings", "settings.updateSchema": "Updating Settings...", + "settings.allowSMSLinkIntegration_label": "Enable SMSLink integration", "settings.maxDays_label": "Max days:", "settings.terms_label": "Terms and conditions URL:", "settings.paymentMethods_label": "Available payment methods:", diff --git a/messages/en.json b/messages/en.json index cae2a21a6..f758dfd09 100644 --- a/messages/en.json +++ b/messages/en.json @@ -4,6 +4,7 @@ "navigation.requestInfo": "Request Info", "navigation.labelSettings": "Returns Settings", "settings.updateSchema": "Updating Settings", + "settings.allowSMSLinkIntegration_label": "Enable SMSLink integration", "settings.maxDays_label": "Max days:", "settings.terms_label": "Terms and conditions URL:", "settings.paymentMethods_label": "Available payment methods:", diff --git a/messages/it.json b/messages/it.json index b128816ff..bf40150fb 100644 --- a/messages/it.json +++ b/messages/it.json @@ -4,6 +4,7 @@ "navigation.requestInfo": "Richiedi informazioni", "navigation.labelSettings": "Impostazioni di reso", "settings.updateSchema": "Aggiornamento delle impostazioni in corso", + "settings.allowSMSLinkIntegration_label": "Abilita l'integrazione di SMSLink", "settings.maxDays_label": "Numero massimo di giorni:", "settings.terms_label": "URL dei termini e delle condizioni:", "settings.paymentMethods_label": "Metodi di pagamento disponibili:", diff --git a/messages/ro.json b/messages/ro.json index ebe4bfd86..b1fed0613 100644 --- a/messages/ro.json +++ b/messages/ro.json @@ -4,6 +4,7 @@ "navigation.requestInfo": "Cerere de retur", "navigation.labelSettings": "Setari", "settings.updateSchema": "Un moment, facem cateva actualizari pentru tine!", + "settings.allowSMSLinkIntegration_label": "Permite integrarea cu SMSLink", "settings.maxDays_label": "Numar maxim de zile:", "settings.terms_label": "URL pentru termeni si conditii:", "settings.paymentMethods_label": "Metode de plata:", diff --git a/react/admin/ReturnForm.tsx b/react/admin/ReturnForm.tsx index 4a4be9bc1..45ad8f7d8 100644 --- a/react/admin/ReturnForm.tsx +++ b/react/admin/ReturnForm.tsx @@ -94,14 +94,38 @@ class ReturnForm extends Component { showLabelError: false, labelDisabled: false, totalAmount: 0, + settings: {} } } componentDidMount(): void { this.getProfile().then() + this.getSettings() this.getFullData() } + getSettings = async () => { + // eslint-disable-next-line react/no-access-state-in-setstate + this.setState({ ...this.state, loading: true }) + await fetch( + `${fetchPath.getDocuments + schemaNames.settings}/${ + schemaTypes.settings + }/1`, + { + method: fetchMethod.get, + headers: fetchHeaders, + } + ) + .then((response) => { + return response.json() + }) + .then((json) => { + if (!json?.[0]) return + this.setState({settings: json[0] }) + }) + .catch((err) => this.setState({ error: err })) + } + getGiftCardInfo(request: any) { return `RA${request.id.split('-')[0]}` } @@ -411,6 +435,7 @@ class ReturnForm extends Component { product, registeredUser, comment, + settings } = this.state let requestData = request @@ -510,6 +535,47 @@ class ReturnForm extends Component { this.savePartial(schemaNames.request, requestBody) this.saveMasterData(schemaNames.history, statusHistoryData) + if(settings.allowSMSLinkIntegration) { + let smsLinkBody: any = { + requestId: request.id, + orderId: request.orderId, + phone: request.phoneNumber + } + + let sendSMS = true + let SMSLinkEvent = '' + + switch (statusInput) { + case requestsStatuses.denied: + SMSLinkEvent = 'request-denied' + break; + case requestsStatuses.refunded: + SMSLinkEvent = 'request-finalized' + break; + case requestsStatuses.picked: + SMSLinkEvent = 'parcel-received' + break; + default: + sendSMS = false + } + + if (sendSMS){ + smsLinkBody = { + ...smsLinkBody, + event: SMSLinkEvent, + } + try { + fetch(`${fetchPath.sendSMS}`, { + method: fetchMethod.post, + body: JSON.stringify(smsLinkBody), + headers: fetchHeaders, + }) + } catch { + // console.log(e) + } + } + } + if ( request.status === requestsStatuses.picked && statusInput === requestsStatuses.pendingVerification diff --git a/react/admin/ReturnsSettings.tsx b/react/admin/ReturnsSettings.tsx index 91f5a31c0..1d01d0d65 100644 --- a/react/admin/ReturnsSettings.tsx +++ b/react/admin/ReturnsSettings.tsx @@ -10,6 +10,7 @@ import { IconClear, Button, CheckboxGroup, + Checkbox, IconDeny, Table, Modal, @@ -33,6 +34,7 @@ const messages = defineMessages({ settingsSaved: { id: 'returns.settingsSaved' }, labelSettings: { id: 'navigation.labelSettings' }, updateSchema: { id: 'settings.updateSchema' }, + smsLinkIntegrationLabel: {id: 'settings.allowSMSLinkIntegration_label'}, maxDaysLabel: { id: 'settings.maxDays_label' }, termsLabel: { id: 'settings.terms_label' }, searchCategories: { id: 'settings.searchCategories' }, @@ -61,6 +63,7 @@ class ReturnsSettings extends Component { this.state = { id: '', updatingSchema: false, + allowSMSLinkIntegration: '', maxDays: '', termsUrl: '', categoryFilterQuery: '', @@ -161,6 +164,7 @@ class ReturnsSettings extends Component { } this.setState({ id: json[0].id, + allowSMSLinkIntegration: json[0].allowSMSLinkIntegration, maxDays: json[0].maxDays, termsUrl: json[0].termsUrl, paymentBank, @@ -299,7 +303,7 @@ class ReturnsSettings extends Component { errorMessage: '', loading: true, }) - const { maxDays, excludedCategories, termsUrl, id, payments, options } = + const { allowSMSLinkIntegration, maxDays, excludedCategories, termsUrl, id, payments, options } = this.state let hasErrors = false @@ -346,6 +350,7 @@ class ReturnsSettings extends Component { const postData = { id, + allowSMSLinkIntegration: allowSMSLinkIntegration, maxDays: parseInt(maxDays, 10), excludedCategories: JSON.stringify(excludedCategories), termsUrl, @@ -417,6 +422,7 @@ class ReturnsSettings extends Component { render() { const { + allowSMSLinkIntegration, maxDays, termsUrl, excludedCategories, @@ -469,6 +475,16 @@ class ReturnsSettings extends Component { ) : (
+
+
+ this.setState({ allowSMSLinkIntegration: !allowSMSLinkIntegration })} + /> +
+
diff --git a/react/common/fetch.tsx b/react/common/fetch.tsx index 116038c82..fbfcbe2ce 100644 --- a/react/common/fetch.tsx +++ b/react/common/fetch.tsx @@ -16,6 +16,7 @@ export const fetchPath = { getOrder: '/returns/getOrder/', renderTemplates: '/api/template-render/pvt/templates', createRefund: '/returns/createRefund/', + sendSMS: '/sms-link-app/send-sms', } export const fetchMethod = { diff --git a/react/store/MyReturnsPageAdd.tsx b/react/store/MyReturnsPageAdd.tsx index b43b3b07e..1d8199ca3 100644 --- a/react/store/MyReturnsPageAdd.tsx +++ b/react/store/MyReturnsPageAdd.tsx @@ -770,6 +770,7 @@ class MyReturnsPageAdd extends Component { iban, accountHolder, orderProducts, + settings, } = this.state orderProducts.forEach((product: any) => { @@ -796,6 +797,7 @@ class MyReturnsPageAdd extends Component { iban, accountHolder, status: requestsStatuses.new, + refundedShippingValue: 0, dateSubmitted: getCurrentDate(), type: schemaTypes.requests, } @@ -818,6 +820,24 @@ class MyReturnsPageAdd extends Component { }) .then(() => { this.showTable() + if (settings.allowSMSLinkIntegration) { + const smsLinkBody: any = { + requestId: response.DocumentId, + orderId: requestData.orderId, + phone: requestData.phoneNumber, + event: 'request-created', + } + + try { + fetch(`${fetchPath.sendSMS}`, { + method: fetchMethod.post, + body: JSON.stringify(smsLinkBody), + headers: fetchHeaders, + }) + } catch { + // console.log(e) + } + } }) } else { this.setState({