[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/admin/navigation.json from the return-app VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "section": "orders",
  "titleId": "admin/return-app.navigation.label",
  "path": "/admin/returns/requests",
  "subSectionItems": [
    {
      "labelId": "admin/navigation.labelRequests",
      "path": "/admin/returns/requests"
    },
    {
      "labelId": "admin/return-app.settings.navigation.label",
      "path": "/admin/returns/settings"
    }
  ]
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/admin/routes.json from the return-app VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "admin.app.return-list": {
    "component": "AdminReturnList",
    "path": "/admin/app/returns/requests/"
  },
  "admin.app.return-settings": {
    "component": "AdminReturnSettings",
    "path": "/admin/app/returns/settings/"
  },
  "admin.app.return-details": {
    "component": "AdminReturnDetails",
    "path": "/admin/app/returns/:id/details/"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/docs/README.md from the return-app VTEX app.

[Assistant]
Here's the implementation:

```markdown
# Return App V3

##  ⚠ Maintenance ⚠
*Starting June 1st 2023, this application will no longer be maintained by VTEX.*

---

## Description

The **Return App** gives merchants the option to allow customers to request a return for their items and it gives them the ability to manage the Return Request Process on their store.

## Features

### Store: Returns

A specific section under **My Account** on each store.
Here a customer will be able to visualize the history, status and details of their created returns. As well as creating a new **Return Request**.

### Admin: Return Request List

In this section of the merchant's admin, merchants are capable of visualizing and managing all the return requests created by their customers.

### Admin: Return Settings

In this section of the merchant's admin, merchants control what are the conditions of allowing the return process for a given item or items per customer.

- **Max Days**: when an order creation date is older than the Max Days to return, user won't be able to select that order for a return
- **Terms and Conditions**: link to the Terms and conditions offered by the store. (not provided by the app)
- **Excluded categories**: List of categories to be excluded for the return process. Any item that belongs to any of these categories, will not be allowed to be returned. The store user will see a message stating that that item is not allowed to be returned.
- **Return Payment Options**:

  -- Same as Order: Payment will be refunded to the same payment method used in the order.
  -- Automatically refund requests - Automatically refund any payment method when the configuration to refund is set to be same as order.

  -- Allowed to choose: customer will select any of the refund options selected by the store.
  **Disclaimer**: Requests that were set to refund via credit card trigger the automatic refund.

**Disclaimer**: For the cases that the return app creates a refund, the return invoice ([invoice type input](https://developers.vtex.com/vtex-rest-api/reference/invoicenotification)) will be created in the OMS with the return request id as the invoice number.

- **Custom Return Reasons**: Allows the store to define their own custom return reasons. This setting will overwrite the default reasons.
  The custom Return Reasons can be translated manually by the admin.
  |Default return reason|
  |---------|
  |Accidental Order|
  |Better Price|
  |Performance|
  |Incompatible|
  |Item Damaged|
  |Missed Delivery|
  |Missing Parts|
  |Box Damaged|
  |Different Product|
  |Defective|
  |Arrived in addition|
  |No Longer Needed|
  |Unauthorized purchase|
  |Different from website|

- **Other Option**: toggle this to include a generic other return request reason. The store user can input any generic value if this one is chosen.
- **Allow PickUp Points**: allow the customer to set a pick up point to drop off the items to return. It uses the geocoordinates from the order to find the closest pickup points.
- **Proportional shipping value**: the shipping value to be refunded per item will be automatically calculated based on the item value percentage of the total order value.
- **Item condition selector**: require the store user to select the condition of the items

### Transactional Emails

The app leverages the capabilites of VTEX Message Center to notify the customers when a return request is created and when the status of their return changes.

When creating a return request for the first time, the app creates a default template `oms-return-request-confirmation_{locale}` that is modifiable on the Message Center to suit each store needs.
the locale will be filled with the locale the store user had when browsing the store.

Additional to the confirmation template, on successful Return Request Status update, the app also creates a `oms-return-request-status-update_{locale}`.

Both templates will always be created in English, it is responsability of the store to translate them to the desired locale.

## API

### Create Return Request

To create a Return Request make a POST request to the following endpoint:
`https://{accountName}.myvtex.com/_v/return-request`
with an example body in the form of:

```
{
    "items": [{
        "orderItemIndex": 0,
        "quantity": 1,
        "returnReason": {
            "reason": "Wrong type"
        },
        "condition": "newWithBox"
    }],
    "orderId": "1240221188059-01",
    "refundPaymentData": {
        "refundPaymentMethod": "sameAsPurchase"
    },
    "pickupReturnData": {
        "addressId:"",
        "addressType": "CUSTOMER_ADDRESS",
        "address": "Rua Haddock Lobo",
        "city": "São Paulo",
        "state": "SP",
        "country": "Br",
        "zipCode": "01403003"
    },
    "customerProfileData": {
        "name": "Filadelfo Braz",
        "email": "filadelfo.braz+test@gmail.com",
        "phoneNumber": "123432122"
    },
    "userComment": "This is a test from API",
    "locale": "pt-PT"
}
```

| Field                                 | Description                                                           | isRequired |
| ------------------------------------- | --------------------------------------------------------------------- | ---------- |
| orderId                               | `string` orderId to where the Return Request is being made to         | true       |
| items                                 | array of individual itemObject to be returned                         | true       |
| items orderItemIndex                  | `integer` Index of the item in the Order object form the OMS          | true       |
| items quantity                        | `integer` number to be returned for the given `orderItemIndex`        | true       |
| items condition                       | `enum` values: newWithBox, newWithoutBox, usedWithBox, usedWithoutBox | false      |
| items returnReason                    | `object` with reason to return the item                               | true       |
| items returnReason reason             | `string` reason to return                                             | true       |
| items returnReason otherReason        | `string` Description of the reason when it is `otherReason`           | false      |
| customerProfileData                   | `object` with customer information                                    | true       |
| customerProfileData name              | `string` Customer name for the return request                         | true       |
| customerProfileData email             | `string` customer's email for the return request                      | true       |
| customerProfileData phoneNumber       | `string` customer's phone number for the return request               | true       |
| pickupReturnData                      | `object` with information where the items should be picked up         | true       |
| pickupReturnData addressId            | `string` id of the customer's address can be empty string             | true       |
| pickupReturnData address              | `string`customer address                                              | true       |
| pickupReturnData city                 | `string` city of the address                                          | true       |
| pickupReturnData country              | `string` country of the address                                       | true       |
| pickupReturnData zipCode              | `string` postal code of the address                                   | true       |
| pickupReturnData addressType          | `enum` possible values: PICKUP_POINT, CUSTOMER_ADDRESS                | true       |
| refundPaymentData                     | `object` with refund information                                      | true       |
| refundPaymentData refundPaymentMethod | `enum` possible values: bank, card, giftCard, sameAsPurchase          | true       |
| refundPaymentData iban                | `string`required when refundPaymentMethod is set as bank              | false      |
| refundPaymentData accountHolderName   | `string` required when refundPaymentMethod is set as bank             | false      |
| userComment                           | `string` comment to be added to the creation                          | false      |
| locale                                | `string` locale for the customer to visualize the return              | true       |

A successful creation of a Return Request should return a status 201 with a response in the form of:

```
{
    "requestId": "requestId"
}
```

### Update a Return Request Status

Make a PUT request to the following endpoint:
`https://{accountName}.myvtex.com/_v/return-request/{requestId}`
with the following example body:

```
{
    "status":"packageVerified",
    "comment":{
        "value":"Test comment",
        "visibleForCustomer": false
    },
    "refundData":{
        "items":[{
            "orderItemIndex":0,
            "quantity":1,
            "restockFee":12
        }],
        "refundedShippingValue":1
    }
}
```

| Field                            | Description                                                                                | isRequired |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | ---------- |
| status                           | `enum` possible values: new, processing, pickedUpFromClient,pendingVerification, packageVerified, amountRefunded, denied, cancelled | true       |
| comment                          | `object` only required if not updating status                                                                                | false      |
| comment value                    | `string` only required if not updating status                                                                                | true       |
| comment visibleForCustomer       | `boolean` the comment will be shown to the customer. Default false                                                                  | false      |
| refundData                       | `object` only considered when status sent is `packagedVerified`                                                                     | false      |
| refundData items                 | `array` of `objects` with items approved to be returned                                                                             | true       |
| refundData items orderItemIndex  | `integer`Index of the item in the Order object form the OMS                                                                         | true       |
| refundData items quantity        | `integer` number to be returned for the given `orderItemIndex`                                                                      | true       |
| refundData items restockFee      | `integer` discount to be applied to the amount to be refunded, can be zero                                                          | true       |
| refundData refundedShippingValue | `integer` shipping amount to be refunded, can be zero                                                                               | true       |

To update the request to the next possible status, one just needs to pass a payload with the key status and the status as its value.
It's possible to send the comment payload with all the status. When sending the status packageVerified it's necessary to send the refundData object.

The request can be denied up to the pickedUpFromClient status. After that, it's only possible to deny a request by passing quantity zero to all items when sending the status packageVerified.

When sending the status packageVerified, the next status will be automatically set to packageVerified or denied based on the information inside refundData.items.

When sending the status amountRefunded, the app will refund the payment method when the store user paid the order using credit card, and has selected to be refunded via credit card or the store forces refunds in the same method as the purchase.

**Add comments without updating status**
To add a comment to a request, ones only needs to send the payload with status equals to the current one and pass the comment object.

### Retrieve a Return Request

To get a Return Request make a GET request to the following endpoint:
`https://{accountName}.myvtex.com/_v/return-request/{requestId}`

### Retrieve Return Request List

To retrieve a List of Return Requests make a GET request to the following endpoint:
`https://{accountName}.myvtex.com/_v/return-request`
The search params available are:

- \_page `integer`
- \_perPage `integer`
- \_status `enum`
- \_sequenceNumber `string`
- \_id `string`
- \_dateSubmitted `string` e.g: \_dateSubmitted=2022-06-12,2022-07-13
- \_orderId `string`
- \_userEmail `string`

By default, the requests will only have a summary of the request. If you want to get all the fields for the requests, you can pass another search param:

- \_allFields `string` (any truthy value)

## Customization

In order to apply CSS customizations in this and other blocks, follow the instructions given in the recipe on [Using CSS Handles for store customization](https://vtex.io/docs/recipes/style/using-css-handles-for-store-customization).

| CSS Handles COMMON                   |
| ------------------------------------ |
| 'contactDetailsCommonContainer'      |
| 'currentRequestStatusContainer'      |
| 'itemDetailsListContainer'           |
| 'itemVerificationDeniedContainer'    |
| 'itemVerificationApprovedContainer'  |
| 'itemVerificationPartiallyContainer' |
| 'itemVerificationNewContainer'       |
| 'commonPickupContainer'              |
| 'refundMethodDetailContainer'        |
| 'approvedValuesContainer'            |
| 'requestedValuesContainer'           |
| 'returnValuesContainer'              |
| 'totalContainer'                     |
| 'totalWrapperContainer'              |
| 'statusHistoryContainer'             |
| 'jumpToPageContainer'                |
| 'listTableContainer'                 |
| 'listTableFilterContainer'           |
| 'mobileReturnListContainer'          |
| 'controlGridVisibility'              |
| 'controlGridVisibilityButtons'       |
| 'emptyList'                          |
| 'returnList'                         |
| 'returnListSingle'                   |
| 'returnListDouble'                   |
| 'returnListItem'                     |
| 'returnListItemHeader'               |
| 'returnListItemImage'                |
| 'returnListItemInfo'                 |
| 'returnListItemInfoDate'             |
| 'returnListItemInfoIdContainer'      |
| 'returnListItemInfoStatus'           |

| CSS Handles STORE                  |
| ---------------------------------- |
| 'contactPickupContainer'           |
| 'addressContainer'                 |
| 'addressHeaderWrapper'             |
| 'pickupAddressTitle'               |
| 'tooltipToggleWrapper'             |
| 'addressInputContainer'            |
| 'cityInputContainer'               |
| 'stateInputContainer'              |
| 'zipCodeInputContainer'            |
| 'countryInputContainer'            |
| 'submitDetailsContainer'           |
| 'contactAddressWrapper'            |
| 'paymentCommentWrapper'            |
| 'confirmationActionsContainer'     |
| 'backButtonWrapper'                |
| 'submitButtonWrapper'              |
| 'confirmContactContainer'          |
| 'confirmContactTitle'              |
| 'confirmContactText'               |
| 'confirmPaymentContainer'          |
| 'confirmPaymentTitle'              |
| 'accountHolderWrapper'             |
| 'ibanWrapper'                      |
| 'accountHolderText'                |
| 'confirmPaymentValue'              |
| 'ibanText'                         |
| 'refundPaymentText'                |
| 'confirmPickupContainer'           |
| 'confirmPickupTitle'               |
| 'confirmPickupText'                |
| 'contactDetailsContainer'          |
| 'contactDetailsTitle'              |
| 'contactNameInputWrapper'          |
| 'contactEmailInputWrapper'         |
| 'contactPhoneInputWrapper'         |
| 'detailsRowContainer'              |
| 'detailsTdWrapper'                 |
| 'productSectionWrapper'            |
| 'productText'                      |
| 'productImageWrapper'              |
| 'productImage'                     |
| 'itemsDetailText'                  |
| 'itemsListContainer'               |
| 'itemsListTheadWrapper'            |
| 'paymentMethodContainer'           |
| 'paymentBankWrapper'               |
| 'pickupPointContainer'             |
| 'conditionDropdwonContainer'       |
| 'otherReasonOptionContainer'       |
| 'returnDetailsContainer'           |
| 'orderIdDetailsWrapper'            |
| 'creationDateDetailsWrapper'       |
| 'returnInfoTableContainer'         |
| 'returnInfoTheadContainer'         |
| 'returnInfoTableText'              |
| 'returnInfoBodyContainer'          |
| 'itemsListTheadWrapper'            |
| 'paymentMethodContainer'           |
| 'paymentBankWrapper'               |
| 'pickupPointContainer'             |
| 'conditionDropdwonContainer'       |
| 'otherReasonOptionContainer'       |
| 'returnDetailsContainer'           |
| 'orderIdDetailsWrapper'            |
| 'creationDateDetailsWrapper'       |
| 'returnInfoTableContainer'         |
| 'returnInfoTheadContainer'         |
| 'returnInfoTableText'              |
| 'returnInfoBodyContainer'          |
| 'returnInfoTrBodyWrapper'          |
| 'returnInfoBodyImgWrapper'         |
| 'returnInfoReasonConditionWrapper' |
| 'termsAndConditionsContainer'      |
| 'termsAndConditionsLink'           |
| 'userCommentDetailsContainer'      |
| 'cardItemsWrapper'                 |
| 'itemDetailsListWrapper'           |
| 'cardWrapper'                      |
| 'statusWrapper'                    |
| 'productImageWrapper'              |
| 'productImage'                     |
| 'productDetailsWrapper'            |
| 'productNameWrapper'               |
| 'productName'                      |
| 'productRefWrapper'                |
| 'productReasonWrapper'             |
| 'productConditionWrapper'          |
| 'productSellerWrapper'             |
| 'productQuantityWrapper'           |
| 'productSellingPriceWrapper'       |
| 'productTaxWrapper'                |
| 'productTotalWrapper'              |
| 'productKey'                       |
| 'productValue'                     |
| 'productText'                      |
| 'quantityWrapper'                  |
| 'quantityKey'                      |
| 'quantityValue'                    |
| 'availableToReturnWrapper'         |
| 'availableToReturnKey'             |
| 'availableToReturnValue'           |
| 'quantitySelectorWrapper'          |
| 'reasonWrapper'                    |
| 'conditionWrapper'                 |
| 'highlightedFormMessage'           |

## Known issues

- When a store has a process to create return invoices ([invoice type input](https://developers.vtex.com/vtex-rest-api/reference/invoicenotification)) outside the return app, the app will consider those items and they will not be able to be returned via the app. However when an item is already committed in a return request and an invoice is created considering that item with a invoice number different than the return request id, there will be more processed items to return then invoices items - It can be seen using the query `orderToReturnSummary` on GraphQL.

- When installing the app in a workspace - or creating a new one - the app will not behavior as expected. This is due to the masterdata builder not creating a schema for that workspace automatically. To fix that, one can just link the app in the workspace using the toolbelt. Doing so, there will be a new masterdata schema related to that workspace and the app should work fine.

    ### Workaround

    To avoid the issue with the Masterdata builder when installing a new version of the APP in the master environment follow these steps:

    1. Create a PROD WS within the account you will install the APP.
    2. Install the new version of the APP in this PROD workspace: `vtex install vtex.return-app@3.x.x`
    3. Create a DEV WS, and link the APP latest version to the workspace: `vtex link`
    4. Check if the documents are on the listing page of the PROD WS. `/admin/returns/requests/`
    5. If they are, then you are safe to install on the Master environment.

---

Documentation for v2 [here](https://github.com/vtex-apps/return-app/tree/v2).

v3 consists on a major change from v2, please do not refer to v2 documents for v3.

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/graphql/schema.graphql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
type Query {
  returnAppSettings: ReturnAppSettings @cacheControl(maxAge: ZERO)
  categoryTreeName: [CategoryInfo]! @cacheControl(maxAge: MEDIUM)
  """
  storeUserEmail: If not passed, resolver will try to parse it from session cookie.
  """
  ordersAvailableToReturn(
    page: Int!
    storeUserEmail: String
  ): OrdersToReturnList
    @withUserProfile
    @cacheControl(scope: PRIVATE, maxAge: SHORT)
  """
  storeUserEmail: If not passed, resolver will try to parse it from session cookie.
  """
  orderToReturnSummary(
    orderId: ID!
    storeUserEmail: String
  ): OrderToReturnSummary
    @withUserProfile
    @cacheControl(scope: PRIVATE, maxAge: SHORT)
  returnRequest(requestId: ID!): ReturnRequestResponse
    @withUserProfile
    @cacheControl(scope: PRIVATE, maxAge: SHORT)
  returnRequestList(
    filter: ReturnRequestFilters
    page: Int!
    perPage: Int
  ): ReturnRequestList
    @withUserProfile
    @cacheControl(scope: PRIVATE, maxAge: SHORT)
  nearestPickupPoints(lat: String!, long: String!): NearPickupPointQueryResponse
}

type Mutation {
  createReturnRequest(returnRequest: ReturnRequestInput!): returnRequestCreated
    @withUserProfile
  saveReturnAppSettings(settings: ReturnAppSettingsInput!): Boolean
  updateReturnRequestStatus(
    requestId: ID!
    status: Status!
    comment: ReturnRequestCommentInput
    refundData: RefundDataInput
  ): ReturnRequestResponse @withUserProfile
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/service.json from the return-app VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "memory": 512,
  "ttl": 60,
  "timeout": 5000,
  "minReplicas": 2,
  "maxReplicas": 4,
  "routes": {
    "returnRequests": {
      "path": "/_v/return-request",
      "public": true
    },
    "returnRequest": {
      "path": "/_v/return-request/:requestId",
      "public": true
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/package.json from the return-app VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "@vtex/api": "6.48.0",
    "@vtex/clients": "^2.21.0",
    "co-body": "^6.0.0",
    "graphql": "^14.0.0",
    "graphql-tools": "^4.0.0",
    "html-template-tag": "^4.0.1"
  },
  "devDependencies": {
    "@types/co-body": "^0.0.3",
    "@types/jest": "^24.0.18",
    "@types/node": "^12.0.0",
    "@vtex/api": "6.48.0",
    "@vtex/test-tools": "^1.0.0",
    "@vtex/tsconfig": "^0.6.0",
    "tslint": "^6.1.3",
    "tslint-config-vtex": "^2.1.0",
    "vtex.catalog-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.catalog-graphql@1.102.3/public/@types/vtex.catalog-graphql",
    "vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.css-handles@0.4.4/public/@types/vtex.css-handles",
    "vtex.easypost": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.easypost@0.2.0/public/@types/vtex.easypost",
    "vtex.format-currency": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.format-currency@0.4.1/public/@types/vtex.format-currency",
    "vtex.my-account": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.my-account@1.25.0/public/@types/vtex.my-account",
    "vtex.my-account-commons": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.my-account-commons@1.6.1/public/@types/vtex.my-account-commons",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.132.4/public/@types/vtex.render-runtime",
    "vtex.return-app": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.return-app@3.8.0/public/@types/vtex.return-app",
    "vtex.styleguide": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styleguide@9.146.4/public/@types/vtex.styleguide",
    "vtex.tenant-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.tenant-graphql@0.1.2/public/@types/vtex.tenant-graphql"
  },
  "scripts": {
    "lint": "tsc --noEmit --pretty && tslint -c tslint.json --fix './**/*.ts'"
  },
  "version": "3.11.0"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/index.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  ClientsConfig,
  ServiceContext,
  RecorderState,
  ParamsContext,
} from '@vtex/api'
import { Service, method, LRUCache } from '@vtex/api'

import { Clients } from './clients'
import { errorHandler } from './middlewares/errorHandler'
import { mutations, queries, resolvers } from './resolvers'
import { schemaDirectives } from './directives'
import { auth } from './middlewares/auth'
import { createReturn } from './middlewares/createReturn'
import { getRequest } from './middlewares/getRequest'
import { getRequestList } from './middlewares/getRequestList'
import { updateRequestStatus } from './middlewares/updateRequestStatus'

const TIMEOUT_MS = 5000
const catalogMemoryCache = new LRUCache<string, any>({ max: 5000 })

const clients: ClientsConfig<Clients> = {
  implementation: Clients,
  options: {
    default: {
      retries: 2,
      timeout: TIMEOUT_MS,
    },
    catalog: {
      memoryCache: catalogMemoryCache,
    },
  },
}

declare global {
  type Context = ServiceContext<Clients, State>

  interface State extends RecorderState {
    // Added in the state via graphql directive or auth middleware when request has vtexidclientautcookie
    userProfile?: UserProfile
    // Added in the state via auth middleware when request has appkey and apptoken.
    appkey?: string
  }
}

export default new Service<Clients, State, ParamsContext>({
  clients,
  routes: {
    returnRequests: method({
      POST: [errorHandler, auth, createReturn],
      GET: [errorHandler, auth, getRequestList],
    }),
    returnRequest: method({
      GET: [errorHandler, auth, getRequest],
      PUT: [errorHandler, auth, updateRequestStatus],
    }),
  },
  graphql: {
    resolvers: {
      ...resolvers,
      Mutation: {
        ...mutations,
      },
      Query: {
        ...queries,
      },
    },
    schemaDirectives: {
      ...schemaDirectives,
    },
  },
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/pages/pages.json from the return-app VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "extensions": {
    "my-account-portal/routes/vtex.return-app": {
      "component": "ExtensionRouter"
    },
    "my-account-portal/menu-links-after/vtex.return-app": {
      "component": "ExtensionLinks"
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/react/AdminReturnDetails.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { AdminReturnDetails } from './admin/AdminReturnDetails'
import './styles.global.css'

export default AdminReturnDetails

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/react/AdminReturnSettings.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { RMASettingsWrapper } from './admin/AdminReturnSettings'

export default RMASettingsWrapper

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/react/package.json from the return-app VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "dependencies": {
    "@apollo/client": "^3.5.8",
    "@types/faker": "^4.1.5",
    "apollo-client": "^2.6.4",
    "axios": "^0.20.0",
    "classnames": "^2.2.6",
    "debounce": "^1.2.0",
    "faker": "^4.1.0",
    "graphql": "15.5.0",
    "graphql-tag": "^2.10.1",
    "ramda": "^0.24.1",
    "react": "^16.12.0",
    "react-apollo": "^3.1.5",
    "react-dom": "^16.12.0",
    "react-html-parser": "^2.0.2",
    "react-intl": "^3.12.0",
    "react-router-dom": "^4.3.1"
  },
  "devDependencies": {
    "@types/graphql": "14.2.2",
    "@types/node": "^11.12.1",
    "@types/react": "^16.8.22",
    "@types/react-intl": "^3.0.0",
    "@types/react-router": "^5.1.18",
    "@vtex/test-tools": "^0.3.2",
    "@vtex/tsconfig": "^0.6.0",
    "prop-types": "^15.7.2",
    "vtex.catalog-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.catalog-graphql@1.102.3/public/@types/vtex.catalog-graphql",
    "vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.css-handles@0.4.4/public/@types/vtex.css-handles",
    "vtex.easypost": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.easypost@0.2.0/public/@types/vtex.easypost",
    "vtex.format-currency": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.format-currency@0.4.1/public/@types/vtex.format-currency",
    "vtex.my-account": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.my-account@1.25.0/public/@types/vtex.my-account",
    "vtex.my-account-commons": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.my-account-commons@1.6.1/public/@types/vtex.my-account-commons",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.132.4/public/@types/vtex.render-runtime",
    "vtex.return-app": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.return-app@3.8.0/public/@types/vtex.return-app",
    "vtex.styleguide": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.styleguide@9.146.4/public/@types/vtex.styleguide",
    "vtex.tenant-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.tenant-graphql@0.1.2/public/@types/vtex.tenant-graphql"
  },
  "version": "3.11.0"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/react/styles.global.css from the return-app VTEX app.

[Assistant]
Here's the implementation:

```css
.status-icon {
  padding-top: 3px;
  padding-left: 3px;
  margin-right: 20px;
}

.status-icon-not-visited {
  width: 30px;
  height: 30px;
  border: 3px solid #134cd8;
  border-radius: 50%;
  display: inline-block;
  box-sizing: border-box;
  padding-top: 3px;
  padding-left: 3px;
  background: #fff;
  margin-right: 20px;
  margin-left: 3px;
}

.status-icon-checked {
  background: #134cd8;
}

.status-denied {
  border: 1px solid red;
  background: #f21515a1;
}

ul.status {
  background-image: linear-gradient(gray 33%, rgba(255, 255, 255, 0) 0%);
  background-position: left;
  background-size: 2px 6px;
  background-repeat: repeat-y;
  list-style-type: none;
  margin-left: 15px;
  min-height: 20px;
  padding-top: 0;
  padding-bottom: 0;
}

div.timeline:last-of-type ul.last-of {
  background-image: none;
}

.return-itemsList-body tr {
  border-bottom: 1px solid #e3e4e6;
}

.return-itemsList-body tr:last-child {
  border-bottom: none;
}

.create-return-request__container .vtex-pageHeader__container {
  padding: 0 0 2rem 0;
}

/* Based on https://github.com/vtex-apps/render-runtime/blob/ed5640d59e023f6cfa743b5aa58b654035b870cb/react/utils/withDevice.tsx#L29 */
@media screen and (max-width: 639px) {
  .return-detail__container .vtex-pageHeader__container {
    padding: 0 0 2rem 0;
  }

  .return-detail__container .styleguide__box,
  .create-return-request__container .styleguide__box {
    padding: 1rem;
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/react/AdminReturnList.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import AdminReturnList from './admin/AdminReturnList'

export default AdminReturnList

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/react/StoreReturnApp.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import StoreReturnAppRouter from './store/StoreReturnAppRouter'
import './styles.global.css'

export default StoreReturnAppRouter

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/react/StoreMyReturnsLink.tsx from the return-app VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { FC, ReactElement } from 'react'
import React from 'react'
import { FormattedMessage } from 'react-intl'

interface RenderProps {
  name: ReactElement | string
  path: string
}

interface Props {
  render: (paths: RenderProps[]) => ReactElement
}

const StoreMyReturnsLink: FC<Props> = ({ render }) => {
  return render([
    {
      name: <FormattedMessage id="store/return-app.link" />,
      path: '/my-returns',
    },
  ])
}

export default StoreMyReturnsLink

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/store/interfaces.json from the return-app VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "my-account-link.my-returns-link": {
    "component": "StoreMyReturnsLink"
  },
  "my-account-link.my-returns-app": {
    "component": "StoreReturnApp"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/store/plugins.json from the return-app VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "my-account-menu > my-account-link": "my-account-link.my-returns-link",
  "my-account-pages > my-account-page": "my-account-link.my-returns-app"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/graphql/types/ReturnAppSettings.graphql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
type ReturnAppSettings {
  maxDays: Int!
  excludedCategories: [String!]!
  paymentOptions: PaymentOptions!
  termsUrl: String!
  customReturnReasons: [CustomReturnReason!]
  options: ReturnOption
}

type PaymentOptions {
  enablePaymentMethodSelection: Boolean
  allowedPaymentTypes: PaymentType!
  automaticallyRefundPaymentMethod: Boolean
}

type PaymentType {
  bank: Boolean
  card: Boolean
  giftCard: Boolean
}

type CustomReturnReason {
  reason: String!
  maxDays: Int!
  translations: [CustomReturnReasonTranslation!]
}

type CustomReturnReasonTranslation {
  locale: String!
  translation: String!
}

type ReturnOption {
  enableOtherOptionSelection: Boolean
  enablePickupPoints: Boolean
  enableProportionalShippingValue: Boolean
  enableSelectItemCondition: Boolean
  enableHighlightFormMessage: Boolean
}

input ReturnAppSettingsInput {
  maxDays: Int!
  excludedCategories: [String!]!
  paymentOptions: PaymentOptionsInput!
  termsUrl: String!
  customReturnReasons: [CustomReturnReasonInput!]
  options: ReturnOptionInput
}

input PaymentOptionsInput {
  enablePaymentMethodSelection: Boolean
  allowedPaymentTypes: PaymentTypeInput!
  automaticallyRefundPaymentMethod: Boolean
}

input PaymentTypeInput {
  bank: Boolean
  card: Boolean
  giftCard: Boolean
}

input CustomReturnReasonInput {
  reason: String!
  maxDays: Int!
  translations: [CustomReturnReasonTranslationInput!]
}

input CustomReturnReasonTranslationInput {
  locale: String!
  translation: String!
}

input ReturnOptionInput {
  enableOtherOptionSelection: Boolean
  enablePickupPoints: Boolean
  enableProportionalShippingValue: Boolean
  enableSelectItemCondition: Boolean
  enableHighlightFormMessage: Boolean
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/graphql/types/ReturnRequest.graphql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
input ReturnRequestInput {
  orderId: String!
  items: [ReturnRequestItemInput!]!
  customerProfileData: CustomerProfileDataInput!
  pickupReturnData: PickupReturnDataInput!
  refundPaymentData: RefundPaymentDataInput!
  userComment: String
  locale: String!
}

input ReturnRequestItemInput {
  orderItemIndex: Int!
  quantity: Int!
  condition: ItemCondition
  returnReason: ReturnReasonInput!
}

input ReturnReasonInput {
  reason: String!
  otherReason: String
}

enum ItemCondition {
  unspecified
  newWithBox
  newWithoutBox
  usedWithBox
  usedWithoutBox
}

input CustomerProfileDataInput {
  name: String!
  """
  email: If it is not provided, the email from session will be used. When calling from store front, it's ok not to pass it, but calling from GraphQL IDE or Postman, it's required.
  """
  email: String
  phoneNumber: String!
}

input PickupReturnDataInput {
  addressId: String!
  address: String!
  city: String!
  state: String!
  country: String!
  zipCode: String!
  addressType: AddressType!
}

enum AddressType {
  PICKUP_POINT
  CUSTOMER_ADDRESS
}

input RefundPaymentDataInput {
  refundPaymentMethod: RefundPaymentMethod!
  iban: String
  accountHolderName: String
}

enum RefundPaymentMethod {
  bank
  card
  giftCard
  sameAsPurchase
}

type ReturnRequestResponse {
  id: ID!
  orderId: String!
  refundableAmount: Int!
  sequenceNumber: String!
  createdIn: String!
  status: Status!
  dateSubmitted: String!
  userComment: String
  refundableAmountTotals: [RefundableAmountTotal!]!
  customerProfileData: CustomerProfileData!
  pickupReturnData: PickupReturnData!
  refundPaymentData: RefundPaymentData!
  items: [ReturnRequestItem!]!
  refundData: RefundData
  refundStatusData: [RefundStatusData!]!
  cultureInfoData: CultureInfoData!
}

enum Status {
  new
  processing
  pickedUpFromClient
  pendingVerification
  packageVerified
  amountRefunded
  denied
  cancelled
}

type CustomerProfileData {
  userId: String!
  name: String!
  email: String!
  phoneNumber: String!
}

type PickupReturnData {
  addressId: String!
  address: String!
  city: String!
  state: String!
  country: String!
  zipCode: String!
  addressType: AddressType!
  returnLabel: String
}

type RefundPaymentData {
  refundPaymentMethod: RefundPaymentMethod!
  iban: String
  accountHolderName: String
  automaticallyRefundPaymentMethod: Boolean
}

type ReturnRequestItem {
  orderItemIndex: Int!
  quantity: Int!
  condition: ItemCondition!
  returnReason: ReturnReason!
  """
  id: SKU id
  """
  id: String!
  sellingPrice: Int!
  tax: Int!
  name: String!
  localizedName: String
  imageUrl: String!
  unitMultiplier: Float!
  sellerId: String!
  sellerName: String!
  productId: String!
  refId: String!
}

type ReturnReason {
  reason: String!
  otherReason: String
}

type RefundData {
  invoiceNumber: String!
  invoiceValue: Int!
  refundedItemsValue: Int!
  refundedShippingValue: Int!
  giftCard: GiftCard
  items: [RefundItem!]!
}

type GiftCard {
  id: String!
  redemptionCode: String!
}

type RefundItem {
  orderItemIndex: Int!
  quantity: Int!
  restockFee: Int!
  price: Int!
}

type RefundStatusData {
  status: Status!
  submittedBy: String
  createdAt: String!
  comments: [RefundStatusComment!]!
}

type RefundStatusComment {
  comment: String!
  createdAt: String!
  role: UserRole!
  visibleForCustomer: Boolean
  submittedBy: String!
}

input ReturnRequestFilters {
  status: Status
  sequenceNumber: String
  id: String
  """
  createdIn: It uses the field dateSubmitted in the return request schema to search for documents.
  The field createdIn is auto generated when the document is created, not reflecting the real value for documents migrated from older versions.
  """
  createdIn: DateRangeInput
  orderId: String
  """
  userId: If not passed, resolver will try to get it from cookie session
  """
  userId: String
  userEmail: String
}

input DateRangeInput {
  from: String!
  to: String!
}

type ReturnRequestList {
  list: [ReturnRequestResponse!]!
  paging: Pagination!
}

input RefundDataInput {
  items: [RefundItemInput!]!
  refundedShippingValue: Int!
}

input RefundItemInput {
  orderItemIndex: Int!
  quantity: Int!
  restockFee: Int!
}

input ReturnRequestCommentInput {
  value: String!
  visibleForCustomer: Boolean!
}

type RefundableAmountTotal {
  id: RefundableAmountId!
  value: Int!
}

enum RefundableAmountId {
  items
  shipping
  tax
}

enum UserRole {
  adminUser
  storeUser
}

type CultureInfoData {
  currencyCode: String!
  locale: String!
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/graphql/types/PickupPoints.graphql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
type NearPickupPointQueryResponse {
  items: [CheckoutPickupPoint!]!
}

type CheckoutPickupPoint {
  pickupPoint: PickupPoint!
}

type PickupPoint {
  friendlyName: String!
  address: CheckoutAddress!
  id: String!
}

type CheckoutAddress {
  addressType: String!
  addressId: String!
  isDisposable: Boolean!
  postalCode: String!
  city: String!
  state: String!
  country: String!
  street: String!
  number: String!
  neighborhood: String
  complement: String
  reference: String
  geoCoordinates: [Float]!
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/graphql/types/OrderToReturn.graphql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
type OrdersToReturnList {
  list: [OrderToReturnSummary]
  paging: Pagination
}

type OrderToReturnSummary {
  orderId: String!
  creationDate: String!
  """
  Items invoiced / sent to costumer with items details.
  """
  invoicedItems: [InvoicedItem!]!
  """
  Items committed to return or already returned (invoiced as Input) that cannot be considered to be returned anymore.
  The itemIndex property is used to identify the item in the list of invoiced items.
  """
  processedItems: [ProcessedItem!]!
  """
  Items forbidden to be return.
  The itemIndex property is used to identify the item in the list of invoiced items.
  """
  excludedItems: [excludedItem!]!
  clientProfileData: ClientProfileData!
  shippingData: ShippingData!
  paymentData: PaymentData!
}

type Pagination {
  total: Int!
  pages: Int!
  currentPage: Int!
  perPage: Int!
}

type InvoicedItem {
  id: String!
  productId: String!
  quantity: Int!
  name: String!
  localizedName: String
  imageUrl: String!
  """
  The index of the item in the Order.
  """
  orderItemIndex: Int!
}

type ProcessedItem {
  itemIndex: Int!
  quantity: Int!
}

type excludedItem {
  itemIndex: Int!
  reason: ExcludedReason!
}

type ExcludedReason {
  key: ExcludedReasonEnum!
  value: String!
}

enum ExcludedReasonEnum {
  EXCLUDED_CATEGORY
}

enum OrderToReturnValidation {
  OUT_OF_MAX_DAYS
  ORDER_NOT_INVOICED
}

type ClientProfileData {
  name: String!
  email: String!
  phoneNumber: String!
}

type ShippingData {
  addressId: String!
  address: String!
  city: String!
  state: String!
  country: String!
  zipCode: String!
  addressType: AddressType!
  geoCoordinates: [Float]!
}

type PaymentData {
  canRefundCard: Boolean!
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/graphql/types/ProductReturned.graphql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
input ProductReturnedInput {
  imageUrl: String!
  skuId: String!
  sku: String!
  productId: String!
  ean: String!
  brandId: String!
  brandName: String!
  skuName: String!
  unitPrice: Int!
  quantity: Int!
  goodProducts: Int!
  reason: String!
  reasonCode: String!
  condition: String!
}

type ProductReturned {
  id: ID!
  createdIn: String!
  refundId: String!
  orderId: String!
  userId: String!
  imageUrl: String!
  skuId: String!
  sku: String!
  productId: String!
  ean: String!
  brandId: String!
  brandName: String!
  skuName: String!
  manufacturerCode: String!
  unitPrice: Int!
  quantity: Int!
  totalPrice: Int!
  goodProducts: Int!
  reason: String!
  reasonCode: String!
  condition: String!
  status: String!
  dateSubmitted: String!
  type: String!
}

type returnRequestCreated {
  returnRequestId: String!
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/graphql/types/Category.graphql from the return-app VTEX app.

[Assistant]
Here's the implementation:

```graphql
type CategoryInfo {
  id: String!
  name: String!
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/masterdata/returnRequest/schema.json from the return-app VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "properties": {
    "orderId": {
      "type": "string"
    },
    "refundableAmount": {
      "type": "integer"
    },
    "sequenceNumber": {
      "type": "string"
    },
    "status": { "$ref": "#/$defs/status" },
    "refundableAmountTotals": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "enum": ["items", "shipping", "tax"]
          },
          "value": {
            "type": "integer"
          }
        },
        "required": ["id", "value"]
      }
    },
    "customerProfileData": {
      "type": "object",
      "properties": {
        "userId": {
          "type": "string"
        },
        "name": {
          "type": "string"
        },
        "email": {
          "type": "string",
          "format": "email"
        },
        "phoneNumber": { "type": "string", "maxLength": 50 }
      },
      "required": ["userId", "name", "phoneNumber", "email"]
    },
    "pickupReturnData": {
      "type": "object",
      "properties": {
        "addressId": {
          "type": "string"
        },
        "address": {
          "type": "string"
        },
        "city": {
          "type": "string"
        },
        "state": {
          "type": "string"
        },
        "country": {
          "type": "string"
        },
        "zipCode": {
          "type": "string"
        },
        "addressType": {
          "type": "string",
          "enum": ["PICKUP_POINT", "CUSTOMER_ADDRESS"]
        },
        "returnLabel": {
          "type": "string"
        }
      },
      "required": [
        "addressId",
        "address",
        "city",
        "state",
        "country",
        "zipCode",
        "addressType"
      ]
    },
    "refundPaymentData": {
      "type": "object",
      "properties": {
        "refundPaymentMethod": {
          "type": "string",
          "enum": ["bank", "card", "giftCard", "sameAsPurchase"]
        },
        "iban": {
          "type": ["string", "null"]
        },
        "accountHolderName": {
          "type": ["string", "null"]
        },
        "automaticallyRefundPaymentMethod": {
          "type": ["boolean", "null"]
        }
      },
      "required": ["refundPaymentMethod"]
    },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "orderItemIndex": { "type": "integer" },
          "id": { "type": "string" },
          "name": { "type": "string" },
          "localizedName": { "type": ["string", "null"] },
          "sellingPrice": { "type": "integer" },
          "tax": { "type": "integer" },
          "quantity": { "type": "integer" },
          "imageUrl": { "type": "string" },
          "unitMultiplier": { "type": "number" },
          "sellerId": { "type": "string" },
          "sellerName": { "type": "string" },
          "productId": { "type": "string" },
          "refId": { "type": "string" },
          "returnReason": {
            "type": "object",
            "properties": {
              "reason": {
                "type": "string",
                "required": true
              },
              "otherReason": {
                "type": ["string", "null"]
              }
            },
            "required": ["reason"]
          },
          "condition": {
            "type": "string",
            "enum": [
              "unspecified",
              "newWithBox",
              "newWithoutBox",
              "usedWithBox",
              "usedWithoutBox"
            ]
          }
        },
        "required": [
          "orderItemIndex",
          "id",
          "name",
          "sellingPrice",
          "tax",
          "quantity",
          "imageUrl",
          "unitMultiplier",
          "sellerId",
          "productId",
          "refId",
          "returnReason",
          "condition"
        ]
      }
    },
    "dateSubmitted": { "type": "string", "format": "date-time" },
    "refundData": {
      "type": ["object", "null"],
      "properties": {
        "invoiceNumber": { "type": "string" },
        "invoiceValue": { "type": "integer" },
        "refundedItemsValue": { "type": "integer" },
        "refundedShippingValue": { "type": "integer" },
        "giftCard": {
          "type": "object",
          "properties": {
            "id": {
              "type": "string"
            },
            "redemptionCode": {
              "type": "string"
            }
          },
          "required": ["id", "redemptionCode"]
        },
        "items": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "orderItemIndex": { "type": "integer" },
              "id": { "type": "string" },
              "price": { "type": "integer" },
              "quantity": { "type": "integer" },
              "restockFee": { "type": "integer" }
            },
            "required": [
              "orderItemIndex",
              "id",
              "price",
              "quantity",
              "restockFee"
            ]
          }
        }
      },
      "required": [
        "invoiceNumber",
        "invoiceValue",
        "refundedItemsValue",
        "items"
      ]
    },
    "refundStatusData": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "status": { "$ref": "#/$defs/status" },
          "submittedBy": { "type": "string" },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "comments": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "comment": { "type": "string" },
                "createdAt": {
                  "type": "string",
                  "format": "date-time"
                },
                "role": {
                  "type": "string",

                  "enum": ["adminUser", "storeUser"]
                },
                "submittedBy": { "type": "string" },
                "visibleForCustomer": { "type": "boolean" }
              },
              "required": [
                "comment",
                "createdAt",
                "role",
                "submittedBy",
                "visibleForCustomer"
              ]
            }
          }
        },
        "required": ["status", "submittedBy", "createdAt", "comments"]
      }
    },
    "cultureInfoData": {
      "type": "object",
      "properties": {
        "currencyCode": {
          "type": "string"
        },
        "locale": {
          "type": "string"
        }
      },
      "required": ["currencyCode", "locale"]
    }
  },
  "$defs": {
    "status": {
      "type": "string",
      "enum": [
        "new",
        "processing",
        "pickedUpFromClient",
        "pendingVerification",
        "packageVerified",
        "amountRefunded",
        "denied",
        "cancelled"
      ]
    }
  },
  "required": [
    "orderId",
    "refundableAmount",
    "sequenceNumber",
    "status",
    "refundableAmountTotals",
    "customerProfileData",
    "pickupReturnData",
    "refundPaymentData",
    "items",
    "refundData",
    "refundStatusData",
    "dateSubmitted",
    "cultureInfoData"
  ],
  "v-cache": false,
  "v-default-fields": [
    "id",
    "createdIn",
    "orderId",
    "sequenceNumber",
    "dateSubmitted",
    "status"
  ],
  "v-indexed": [
    "id",
    "createdIn",
    "orderId",
    "customerProfileData",
    "status",
    "sequenceNumber",
    "dateSubmitted"
  ],
  "v-immediate-indexing": true
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/directives/withUserProfile.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { GraphQLField } from 'graphql'
import { defaultFieldResolver } from 'graphql'
import { SchemaDirectiveVisitor } from 'graphql-tools'

import { getUserProfileFromSession } from '../utils/getUserProfileFromSession'

const VTEX_SESSEION = 'vtex_session'

export class WithUserProfile extends SchemaDirectiveVisitor {
  public visitFieldDefinition(field: GraphQLField<unknown, Context>) {
    const { resolve = defaultFieldResolver } = field

    field.resolve = async (root, args, ctx, info) => {
      const {
        cookies,
        clients: { session },
      } = ctx

      const sessionCookie = cookies.get(VTEX_SESSEION)

      const userProfile = await getUserProfileFromSession(
        session,
        sessionCookie
      )

      ctx.state.userProfile = userProfile

      return resolve(root, args, ctx, info)
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/directives/index.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { WithUserProfile } from './withUserProfile'

export const schemaDirectives = {
  withUserProfile: WithUserProfile,
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/clients/checkout.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import { JanusClient } from '@vtex/api'
import type { NearPickupPointQueryResponse } from 'vtex.return-app'

export default class Checkout extends JanusClient {
  constructor(ctx: IOContext, options?: InstanceOptions) {
    super(ctx, {
      ...options,
      headers: {
        ...(options?.headers ?? {}),
        'Content-Type': 'application/json',
        Accept: 'application/json',
        'X-Vtex-Use-Https': 'true',
      },
    })
  }

  public getNearestPickupPoints = async (
    lat: string,
    long: string
  ): Promise<NearPickupPointQueryResponse> => {
    return this.http.get(
      `/api/checkout/pub/pickup-points?geoCoordinates=${lat};${long}`,
      {
        metric: 'checkout-nearestPickupPoints',
      }
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/clients/vtexId.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { IOContext, InstanceOptions } from '@vtex/api'
import { JanusClient } from '@vtex/api'

interface VtexIdLoginResponse {
  authStatus: string
  token: string
  expires: number
}

interface AuthenticatedUser {
  userId: string
  user: string
  userType: string
}

export class VtexId extends JanusClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    super(context, {
      ...options,
      headers: {
        ...options?.headers,
        'x-vtex-user-agent': context.userAgent,
      },
    })
  }

  public login({
    appkey,
    apptoken,
  }: {
    appkey: string
    apptoken: string
  }): Promise<VtexIdLoginResponse> {
    return this.http.post(
      '/api/vtexid/apptoken/login',
      {
        appkey,
        apptoken,
      },
      {
        metric: 'vtexid-login',
      }
    )
  }

  public getAuthenticatedUser(
    authToken: string
  ): Promise<AuthenticatedUser | null> {
    return this.http.get('/api/vtexid/pub/authenticated/user/', {
      metric: 'vtexid-get-authenticated-user',
      params: {
        authToken,
      },
    })
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/clients/oms.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import type { NotificationResponse, NotificationInput } from '@vtex/clients'
import { OMS } from '@vtex/clients'

const baseURL = '/api/oms'

const routes = {
  orders: `${baseURL}/pvt/orders`,
  invoice: (orderId: string) => `${baseURL}/pvt/orders/${orderId}/invoice`,
}

interface OrderList {
  // This API returns more than orderId, but we only need the orderId so far
  list: Array<{ orderId: string; creationDate: string }>
  paging: {
    total: number
    pages: number
    currentPage: number
    perPage: number
  }
}

type InputInvoiceFields = Omit<
  NotificationInput,
  'invoiceKey' | 'invoiceUrl' | 'courier' | 'trackingNumber' | 'trackingUrl'
>

interface OrderListParams {
  clientEmail: string
  orderBy: 'creationDate,desc'
  f_status: 'invoiced'
  f_creationDate: string
  page: number
  per_page: 10
}

export class OMSCustom extends OMS {
  constructor(ctx: IOContext, options?: InstanceOptions) {
    super(ctx, {
      ...options,
    })
  }

  public listOrdersWithParams(params?: OrderListParams) {
    return this.http.get<OrderList>(routes.orders, {
      headers: {
        VtexIdClientAutCookie: this.context.authToken,
      },
      metric: 'oms-list-order-with-params',
      ...(params ? { params } : {}),
    })
  }

  public createInvoice(orderId: string, invoice: InputInvoiceFields) {
    return this.http.post<NotificationResponse>(
      routes.invoice(orderId),
      invoice,
      {
        headers: {
          VtexIdClientAutCookie: this.context.adminUserAuthToken,
        },
        metric: 'oms-create-invoice',
      }
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/clients/giftCard.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { IOContext, InstanceOptions } from '@vtex/api'
import { JanusClient } from '@vtex/api'

interface GiftCardInfo {
  relationName: string
  caption: string
  expiringDate: string
  balance: number
  profileId: string
  discount: boolean
}

interface CreateGiftCardResponse {
  id: string
  redemptionToken: string
  redemptionCode: string
  balance: number
  relationName: string
  emissionDate: string
  expiringDate: string
  caption: string
  discount: boolean
  transaction: {
    href: string
  }
}

interface UpdateGiftCard {
  description: string
  value: number
}

interface GiftCardCreditResponse {
  id: string
  redemptionCode: string
  balance: number
  emissionDate: string
  expiringDate: string
  multipleCredits: boolean
  multipleRedemptions: boolean
  restrictedToOwner: boolean
  statusId: number
}

interface GiftCardResponse {
  id: string
  redemptionCode: string
  redemptionToken: string
  balance: number
  emissionDate: string
  expiringDate: string
  discount: boolean
  transaction: {
    href: string
  }
}

export class GiftCard extends JanusClient {
  constructor(ctx: IOContext, options?: InstanceOptions) {
    super(ctx, {
      ...options,
      headers: {
        VtexIdClientAutCookie: ctx.adminUserAuthToken ?? ctx.authToken,
      },
    })
  }

  public createGiftCard = async (giftCardInfo: GiftCardInfo) =>
    this.http.post<CreateGiftCardResponse>('/api/giftcards', giftCardInfo, {
      metric: 'giftcard-create',
    })

  public updateGiftCard = async (
    giftCardId: string,
    giftCardInfo: UpdateGiftCard
  ) =>
    this.http.post<GiftCardCreditResponse>(
      `/api/gift-card-system/pvt/giftCards/${giftCardId}/credit`,
      giftCardInfo,
      { metric: 'giftcard-update' }
    )

  public getGiftCard = async (giftCardId: string) =>
    this.http.get<GiftCardResponse>(`/api/giftcards/${giftCardId}`, {
      metric: 'giftcard-get',
    })
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/clients/catalogGQL.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import { AppGraphQLClient } from '@vtex/api'
import type { SKU } from '@vtex/api/lib/clients/apps/catalogGraphQL/sku'

const CATALOG_GRAPHQL_APP = 'vtex.catalog-graphql@1.x'

type SKUname = Pick<SKU, 'name'>

export const GET_SKU_TRANSLATION_QUERY = `
  query getSKUTranslation($identifier: SKUUniqueIdentifier) {
    sku(identifier: $identifier) {
      name
    }
  }
`

/**
 * A slimmer version of the original node client.
 * We only require specific fields when translating.
 */
export class CatalogGQL extends AppGraphQLClient {
  constructor(ctx: IOContext, opts?: InstanceOptions) {
    super(CATALOG_GRAPHQL_APP, ctx, {
      ...opts,
      headers: {
        ...opts?.headers,
        cookie: `VtexIdclientAutCookie=${ctx.authToken}`,
        'x-vtex-locale': ctx.locale ?? '',
        'X-Vtex-Tenant': ctx.account,
      },
    })
  }

  public getSKUTranslation = async (id: string) => {
    const variables = {
      identifier: {
        field: 'id',
        value: id,
      },
    }

    const { data } = await this.graphql.query<
      { sku: SKUname },
      typeof variables
    >({
      inflight: true,
      query: GET_SKU_TRANSLATION_QUERY,
      variables,
    })

    return data?.sku.name
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/clients/index.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { IOClients, Sphinx } from '@vtex/api'
import { vbaseFor, masterDataFor } from '@vtex/clients'
import { ReturnAppSettings, ReturnRequest } from 'vtex.return-app'

import { Catalog } from './catalog'
import { OMSCustom as OMS } from './oms'
import { GiftCard } from './giftCard'
import { MailClient } from './mail'
import Checkout from './checkout'
import { VtexId } from './vtexId'
import { CatalogGQL } from './catalogGQL'

const ReturnAppSettings = vbaseFor<string, ReturnAppSettings>('appSettings')
const ReturnRequest = masterDataFor<ReturnRequest>(
  'returnRequest',
  undefined,
  1
)

export class Clients extends IOClients {
  public get oms() {
    return this.getOrSet('oms', OMS)
  }

  public get appSettings() {
    return this.getOrSet('appSettings', ReturnAppSettings)
  }

  public get catalog() {
    return this.getOrSet('catalog', Catalog)
  }

  public get catalogGQL() {
    return this.getOrSet('catalogGQL', CatalogGQL)
  }

  public get returnRequest() {
    return this.getOrSet('returnRequest', ReturnRequest)
  }

  public get giftCard() {
    return this.getOrSet('giftCard', GiftCard)
  }

  public get mail() {
    return this.getOrSet('mail', MailClient)
  }

  public get checkout() {
    return this.getOrSet('checkout', Checkout)
  }

  public get vtexId() {
    return this.getOrSet('vtexId', VtexId)
  }

  public get sphinx() {
    return this.getOrSet('sphinx', Sphinx)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/clients/catalog.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import { JanusClient } from '@vtex/api'

export class Catalog extends JanusClient {
  constructor(ctx: IOContext, options?: InstanceOptions) {
    super(ctx, {
      ...options,
    })
  }

  public getCategoryTree = async (): Promise<CategoryTree[]> =>
    this.http.get('/api/catalog_system/pub/category/tree/100', {
      metric: 'catalog-get-category-tree',
    })
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/clients/mail.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { InstanceOptions, IOContext } from '@vtex/api'
import { JanusClient } from '@vtex/api'

import type {
  StatusUpdateMailData,
  ConfirmationMailData,
  Template,
} from '../typings/mailClient'

const MAIL_SERVICE_PATH = '/api/mail-service/pvt/sendmail'
const TEMPLATE_RENDER_PATH = '/api/template-render/pvt/templates'

export class MailClient extends JanusClient {
  constructor(context: IOContext, options?: InstanceOptions) {
    super(context, {
      ...options,
      headers: {
        VtexIdClientAutCookie: context.authToken,
      },
    })
  }

  public sendMail(
    mailData: StatusUpdateMailData | ConfirmationMailData
  ): Promise<string> {
    return this.http.post(MAIL_SERVICE_PATH, mailData, {
      metric: 'mail-post-send',
    })
  }

  public getTemplate(name: string): Promise<Template> {
    return this.http.get(`${TEMPLATE_RENDER_PATH}/${name}`, {
      metric: 'mail-get-template',
    })
  }

  public publishTemplate(template: Template): Promise<any> {
    return this.http.post(TEMPLATE_RENDER_PATH, template, {
      headers: {
        ...this.options?.headers,
        VtexIdClientAutCookie: this.context.adminUserAuthToken,
      },
      metric: 'mail-post-template',
    })
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/typings/mailClient.d.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ReturnRequestItem, Status } from 'vtex.return-app'

export type ReturnRequestConfirmation = string

export type ReturnRequestStatusUpdate = string

export interface ConfirmationMailData {
  templateName: ReturnRequestConfirmation
  jsonData: {
    data: {
      status: Status['new']
      name: string
      DocumentId: string
      email: string
      phoneNumber: string
      country: string
      locality: string
      address: string
      paymentMethod: string
    }
    products: ReturnRequestItem[]
    refundStatusData: ReturnRequest['refundStatusData']
  }
}

export interface StatusUpdateMailData {
  templateName: ReturnRequestStatusUpdate
  jsonData: {
    data: {
      status: Status
      name: string
      DocumentId: string
      email: string
      paymentMethod: string
      iban: string
      refundedAmount: number
    }
    products: ReturnRequest['items']
    refundStatusData: ReturnRequest['refundStatusData']
  }
}

export interface Template {
  AccountId: string | null
  AccountName: string | null
  ApplicationId: string | null
  Description: string | null
  FriendlyName: string
  IsDefaultTemplate: boolean
  IsPersisted: boolean
  IsRemoved: boolean
  Name: string
  Type: string
  Templates: {
    email: {
      To: string
      CC: string | null
      BCC: string | null
      Subject: string
      Message: string
      Type: string
      ProviderId: string
      ProviderName: string | null
      IsActive: boolean
      withError: boolean
    }
    sms: {
      Type: string
      ProviderId: string | null
      ProviderName: string | null
      IsActive: boolean
      withError: boolean
      Parameters: string[]
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/typings/vtex.return-app.d.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface UserProfile {
  email: string
  userId: string
  firstName?: string
  lastName?: string
  role: 'admin' | 'store-user'
}

interface SessionData {
  id: string
  namespaces: {
    profile: ProfileSession
    authentication: AuthenticationSession
  }
}

interface ProfileSession {
  id?: {
    value: string
  }
  email?: {
    value: string
  }
  firstName?: {
    value: string
  }
  lastName?: {
    value: string
  }
}

interface AuthenticationSession {
  adminUserEmail?: {
    value: string
  }
  adminUserId?: {
    value: string
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/typings/catalog.d.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface CategoryTree {
  id: string
  name: string
  hasChildren: boolean
  children: CategoryTree[]
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/middlewares/createReturn.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { UserInputError } from '@vtex/api'
import { json } from 'co-body'

import { createReturnRequestService } from '../services/createReturnRequestService'

export async function createReturn(ctx: Context) {
  const { req } = ctx

  const body = await json(req)

  const { locale } = body

  if (!locale) {
    throw new UserInputError('Locale is required.')
  }

  ctx.vtex.locale = locale

  ctx.body = await createReturnRequestService(ctx, body)
  ctx.status = 201
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/middlewares/errorHandler.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
export async function errorHandler(ctx: Context, next: () => Promise<void>) {
  const {
    vtex: { logger },
  } = ctx

  try {
    await next()
  } catch (error) {
    logger.error({
      message: error.message,
      error,
    })

    ctx.status = error.status || error.response?.status || 500
    ctx.body = { error: error.message }
    ctx.app.emit('error', error, ctx)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/middlewares/updateRequestStatus.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { json } from 'co-body'

import { updateRequestStatusService } from '../services/updateRequestStatusService'

export async function updateRequestStatus(ctx: Context) {
  const {
    req,
    vtex: {
      route: { params },
    },
  } = ctx

  const { requestId } = params as { requestId: string }

  const body = await json(req)

  const updatedRequest = await updateRequestStatusService(ctx, {
    ...body,
    requestId,
  })

  ctx.body = updatedRequest
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/middlewares/getRequest.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { returnRequestService } from '../services/returnRequestService'

export async function getRequest(ctx: Context) {
  const { requestId } = ctx.vtex.route.params as { requestId: string }

  ctx.set('Cache-Control', 'no-cache')

  ctx.body = await returnRequestService(ctx, requestId)
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/middlewares/getRequestList.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Status } from 'vtex.return-app'

import { returnRequestListService } from '../services/returnRequestListService'

export async function getRequestList(ctx: Context) {
  const { query } = ctx

  const {
    _page,
    _perPage,
    _status,
    _sequenceNumber,
    _id,
    _dateSubmitted,
    _orderId,
    _userEmail,
    _allFields,
  } = query

  const [from, to] = (_dateSubmitted as string | undefined)?.split(',') ?? []

  const getAllFields = Boolean(_allFields)

  ctx.set('Cache-Control', 'no-cache')

  ctx.body = await returnRequestListService(
    ctx,
    {
      page: _page ? Number(_page) : 1,
      perPage: _perPage ? Number(_perPage) : 25,
      filter: {
        status: _status as Status | undefined,
        sequenceNumber: _sequenceNumber as string | undefined,
        id: _id as string | undefined,
        createdIn: _dateSubmitted ? { from, to } : undefined,
        orderId: _orderId as string | undefined,
        userEmail: _userEmail as string | undefined,
      },
    },
    getAllFields
  )
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/middlewares/auth.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { AuthenticationError } from '@vtex/api'

export async function auth(ctx: Context, next: () => Promise<void>) {
  const {
    header,
    clients: { vtexId, sphinx },
    state,
  } = ctx

  const appkey = header['x-vtex-api-appkey'] as string | undefined
  const apptoken = header['x-vtex-api-apptoken'] as string | undefined
  const authCookie = header.vtexidclientautcookie as string | undefined

  if (authCookie) {
    const authenticatedUser = await vtexId.getAuthenticatedUser(authCookie)

    // When the auth cookie is invalid, the API returns null
    if (authenticatedUser) {
      const isAdmin = await sphinx.isAdmin(authenticatedUser.user)

      const { user, userId } = authenticatedUser

      state.userProfile = {
        userId,
        email: user,
        role: isAdmin ? 'admin' : 'store-user',
      }

      if (isAdmin) {
        ctx.vtex.adminUserAuthToken = authCookie
      }
    }
  }

  if (appkey && apptoken) {
    // If appkey and apptoken are not valid, the method throws a 401 error
    const { token } = await vtexId.login({ appkey, apptoken })

    state.appkey = appkey
    ctx.vtex.adminUserAuthToken = token
  }

  const { userProfile, appkey: appKeyState } = state

  // Either userProfile or appKeyState must be on state to continue
  if (!userProfile && !appKeyState) {
    throw new AuthenticationError('Request failed with status code 401')
  }

  await next()
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/canReturnAllItems.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { OrderDetailResponse } from '@vtex/clients'
import type { MasterDataEntity } from '@vtex/clients/build/clients/masterData/MasterDataEntity'
import type {
  ReturnRequestItemInput,
  ReturnAppSettings,
  ReturnRequest,
} from 'vtex.return-app'
import { ResolverError } from '@vtex/api'

import { createOrdersToReturnSummary } from './createOrdersToReturnSummary'
import type { CatalogGQL } from '../clients/catalogGQL'

interface CanReturnAllItemsSetup {
  order: OrderDetailResponse
  excludedCategories: ReturnAppSettings['excludedCategories']
  returnRequestClient: MasterDataEntity<ReturnRequest>
  catalogGQL: CatalogGQL
}

export const canReturnAllItems = async (
  itemsToReturn: ReturnRequestItemInput[],
  {
    order,
    excludedCategories,
    returnRequestClient,
    catalogGQL,
  }: CanReturnAllItemsSetup
) => {
  // we pass email as email because we won't use the email form the return object here
  const { invoicedItems, excludedItems, processedItems } =
    await createOrdersToReturnSummary(order, 'email', {
      excludedCategories,
      returnRequestClient,
      catalogGQL,
    })

  const excludedItemsIndexMap = new Map<number, boolean>()

  for (const excludedItem of excludedItems) {
    excludedItemsIndexMap.set(excludedItem.itemIndex, true)
  }

  const processedItemsQuantityIndexMap = new Map<number, number>()

  for (const processedItem of processedItems) {
    processedItemsQuantityIndexMap.set(
      processedItem.itemIndex,
      processedItem.quantity
    )
  }

  const itemAvailableMap = new Map<number, number>()

  for (let i = 0; i < invoicedItems.length; i++) {
    const { orderItemIndex, quantity } = invoicedItems[i]
    const isExcluded = excludedItemsIndexMap.get(i) ?? false
    const quantityAvailable = isExcluded
      ? 0
      : quantity - (processedItemsQuantityIndexMap.get(i) ?? 0)

    itemAvailableMap.set(orderItemIndex, quantityAvailable)
  }

  const cannotReturn = []

  for (const itemToReturn of itemsToReturn) {
    const { quantity, orderItemIndex } = itemToReturn
    const availableToReturn = itemAvailableMap.get(orderItemIndex)

    // if quantity available to return is undefined or zero or less than the quantity requested, throw error
    if (!availableToReturn || availableToReturn < quantity) {
      cannotReturn.push(orderItemIndex)
    }
  }

  if (cannotReturn.length > 0) {
    throw new ResolverError(
      `Items with index ${cannotReturn.join(
        ', '
      )} are not available to be returned`,
      400
    )
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/mapItemIndexAndQuantity.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ItemPackage } from '@vtex/clients'

export const mapItemIndexAndQuantity = (
  itemPackages: Array<
    Omit<ItemPackage, 'description' | 'price' | 'unitMultiplier'>
  >
): Map<number, number> => {
  const itemIndexAndQuantityMap = new Map<number, number>()

  for (const invoicedItem of itemPackages) {
    const { itemIndex, quantity } = invoicedItem

    if (itemIndexAndQuantityMap.has(itemIndex)) {
      const currentQuantity = itemIndexAndQuantityMap.get(itemIndex) as number

      itemIndexAndQuantityMap.set(itemIndex, currentQuantity + quantity)
    } else {
      itemIndexAndQuantityMap.set(itemIndex, quantity)
    }
  }

  return itemIndexAndQuantityMap
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/validateReturnReason.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  ReturnRequestItemInput,
  CustomReturnReason,
} from 'vtex.return-app'
import { ResolverError, UserInputError } from '@vtex/api'

import { isWithinMaxDaysToReturn } from './dateHelpers'

export const validateReturnReason = (
  itemsToReturn: ReturnRequestItemInput[],
  orderCreationDate: string,
  customReturnReasons?: CustomReturnReason[] | null
) => {
  itemsToReturn.forEach(({ returnReason: { reason }, orderItemIndex }) => {
    if (!reason) {
      throw new UserInputError(
        `Item index ${orderItemIndex} has no return reason. Reason cannot be empty.`
      )
    }
  })

  if (!customReturnReasons || customReturnReasons.length === 0) {
    return
  }

  const maxDaysPercustomReasonMap = new Map<string, number>()

  for (const customReason of customReturnReasons) {
    const { maxDays, reason, translations } = customReason

    maxDaysPercustomReasonMap.set(reason, maxDays)

    for (const { translation } of translations ?? []) {
      maxDaysPercustomReasonMap.set(translation, maxDays)
    }
  }

  for (const item of itemsToReturn) {
    const {
      orderItemIndex,
      returnReason: { reason },
    } = item

    if (reason === 'otherReason') {
      continue
    }

    const maxDayForReason = maxDaysPercustomReasonMap.get(reason)

    if (!maxDayForReason) {
      throw new ResolverError(
        `Order Item index ${orderItemIndex} doesn't have a valid return reason`,
        400
      )
    }

    if (!isWithinMaxDaysToReturn(orderCreationDate, maxDayForReason)) {
      throw new ResolverError(
        `Order Item index ${orderItemIndex} is not within max days for the reason ${reason}`,
        400
      )
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/getUserProfileFromSession.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Session } from '@vtex/api'
import { ResolverError } from '@vtex/api'

const createUserProfile = (sessionData: SessionData): UserProfile => {
  const {
    namespaces: { profile, authentication },
  } = sessionData

  const email = profile.email?.value ?? authentication.adminUserEmail?.value
  const userId = profile.id?.value ?? authentication.adminUserId?.value

  const role = authentication.adminUserId ? 'admin' : 'store-user'

  if (!email || !userId) {
    throw new ResolverError('Invalid session data')
  }

  const { firstName, lastName } = profile

  const firstNameValue = firstName?.value ?? ''
  const lastNameValue = lastName?.value ?? ''

  return {
    email,
    userId,
    role,
    firstName: firstNameValue,
    lastName: lastNameValue,
  }
}

export const getUserProfileFromSession = async (
  session: Session,
  sessionCookie: string | undefined
) => {
  if (!sessionCookie) throw new Error('No session cookie provided')

  const { sessionData } = (await session.getSession(sessionCookie, [
    'profile.id',
    'profile.email',
    'profile.firstName',
    'profile.lastName',
    'authentication.adminUserEmail',
    'authentication.adminUserId',
  ])) as {
    sessionData: SessionData
    sessionToken: string
  }

  return createUserProfile(sessionData)
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/validateItemCondition.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ReturnRequestItemInput } from 'vtex.return-app'
import { UserInputError } from '@vtex/api'

export const validateItemCondition = (
  itemsToReturn: ReturnRequestItemInput[],
  considerCondition?: boolean | null
) => {
  considerCondition &&
    itemsToReturn.forEach(({ condition }, orderItemIndex) => {
      if (!condition || condition === 'unspecified') {
        throw new UserInputError(
          `Item index ${orderItemIndex} has no Item condition. Account settings state that Item condition cannot be unspecified.`
        )
      }
    })
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/createItemsToReturn.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { UserInputError } from '@vtex/api'
import type {
  OrderItemDetailResponse,
  PriceTag,
  SellerDetail,
} from '@vtex/clients'
import type { ReturnRequestItemInput, ReturnRequestItem } from 'vtex.return-app'

import type { CatalogGQL } from '../clients/catalogGQL'
import { translateItemName } from './translateItems'

interface ItemMetadata {
  Items: Array<{
    Id: string
    ImageUrl: string
  }>
}

const calculateItemTax = ({
  tax,
  priceTags,
  quantity,
  sellingPrice,
}: {
  tax: number
  priceTags: PriceTag[]
  quantity: number
  sellingPrice: number
}): number => {
  if (tax) return tax

  const taxHubItems = priceTags.filter((priceTag) =>
    priceTag.name.includes('TAXHUB')
  )

  if (taxHubItems.length === 0) return 0

  const taxValueFromTaxHub = taxHubItems.reduce((acc, priceTag) => {
    const { isPercentual, value, rawValue } = priceTag
    // value for TAXHUB is total (not per unit).
    // When it's percentual, the rawValue is the % to be applied. Since we divide the total ammount per quantity in the return, we
    const taxValue = isPercentual ? rawValue * sellingPrice * quantity : value

    return acc + taxValue
  }, 0)

  return parseFloat((taxValueFromTaxHub / quantity).toFixed(0))
}

export const createItemsToReturn = async ({
  itemsToReturn,
  orderItems,
  sellers,
  itemMetadata,
  catalogGQL,
}: {
  itemsToReturn: ReturnRequestItemInput[]
  orderItems: OrderItemDetailResponse[]
  sellers: SellerDetail[]
  itemMetadata: ItemMetadata
  catalogGQL: CatalogGQL
}): Promise<ReturnRequestItem[]> => {
  return Promise.all(
    itemsToReturn.map(async (item) => {
      const orderItem = orderItems[item.orderItemIndex]

      if (!orderItem) {
        throw new UserInputError(
          `Item index ${item.orderItemIndex} doesn't exist on order`
        )
      }

      const {
        id,
        sellingPrice,
        tax,
        priceTags,
        quantity,
        name,
        imageUrl,
        unitMultiplier,
        seller,
        refId,
        productId,
      } = orderItem

      const sellerName =
        sellers.find((sellerInfo) => sellerInfo.id === seller)?.name ?? ''

      const productImage =
        imageUrl ??
        itemMetadata.Items.find((itemMeta) => itemMeta.Id === id)?.ImageUrl ??
        ''

      return {
        ...item,
        id,
        sellingPrice,
        tax: calculateItemTax({ tax, priceTags, quantity, sellingPrice }),
        name,
        localizedName: await translateItemName(id, name, catalogGQL),
        imageUrl: productImage,
        unitMultiplier,
        sellerId: seller,
        refId: refId ?? '',
        productId,
        sellerName,
        condition: item.condition ? item.condition : 'unspecified',
      }
    })
  )
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/validateCanUseDropoffPoints.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { PickupReturnDataInput } from 'vtex.return-app'
import { ResolverError, UserInputError } from '@vtex/api'

export const validateCanUsedropoffPoints = (
  pickupReturnData: PickupReturnDataInput,
  isPickupPointsEnabled?: boolean | null
) => {
  if (!pickupReturnData) {
    throw new UserInputError('Missing pickupReturnData')
  }

  const { addressType } = pickupReturnData

  if (addressType === 'PICKUP_POINT' && !isPickupPointsEnabled) {
    throw new ResolverError('Dropoff points are not enabled')
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/getInvoicedItems.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ItemPackage, PackageDetail } from '@vtex/clients'

type InvoiceType = 'Output' | 'Input'

export const getInvoicedItems = (
  packageDetails: PackageDetail[],
  invoiceType: InvoiceType
): ItemPackage[] => {
  const invoices = packageDetails.filter(({ type }) => type === invoiceType)

  const invoicedItemsRaw = invoices.map(
    ({ items: invoicedItems }) => invoicedItems
  )

  const invoicedItemsFlatten = invoicedItemsRaw.reduce((acc, invoicedItems) => {
    return [...acc, ...invoicedItems]
  }, [])

  return invoicedItemsFlatten
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/handleRefund.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Status, Maybe, ReturnRequest, GiftCard } from 'vtex.return-app'
import { ResolverError } from '@vtex/api'

import type { OMSCustom } from '../clients/oms'
import type { GiftCard as GiftCardClient } from '../clients/giftCard'

const getOneYearLaterDate = (createdAt: string) => {
  const date = new Date(createdAt)
  const year = date.getFullYear()
  const month = date.getMonth()
  const day = date.getDate()
  const oneYearLater = new Date(year + 1, month, day)

  return oneYearLater.toISOString()
}

interface HandleRefundProps {
  currentStatus: Status
  previousStatus?: Status
  refundPaymentData: ReturnRequest['refundPaymentData']
  orderId: string
  createdAt: string
  userEmail: string
  refundInvoice: ReturnRequest['refundData']
  clients: {
    omsClient: OMSCustom
    giftCardClient: GiftCardClient
  }
}

export const handleRefund = async ({
  currentStatus,
  previousStatus,
  refundPaymentData,
  orderId,
  createdAt,
  refundInvoice,
  clients,
  userEmail,
}: HandleRefundProps): Promise<Maybe<{ giftCard: GiftCard }>> => {
  // To avoid handling the amountRefunded after it has been already done, we check the previous status.
  // If the current status is already amountRefunded, it means the refund has already been done and we don't need to do it again.
  const shouldHandle =
    currentStatus === 'amountRefunded' &&
    previousStatus !== 'amountRefunded' &&
    refundInvoice

  if (!shouldHandle) {
    return null
  }

  const { omsClient, giftCardClient } = clients

  const { refundPaymentMethod, automaticallyRefundPaymentMethod } =
    refundPaymentData ?? {}

  if (refundPaymentMethod === 'giftCard') {
    try {
      const { id, redemptionCode } = await giftCardClient.createGiftCard({
        relationName: refundInvoice?.invoiceNumber as string,
        caption: 'Gift Card from Return Request',
        expiringDate: getOneYearLaterDate(createdAt),
        balance: 0,
        profileId: userEmail,
        discount: true,
      })

      const giftCardIdSplit = id.split('_')

      const giftCardId = giftCardIdSplit[giftCardIdSplit.length - 1]

      await giftCardClient.updateGiftCard(giftCardId, {
        description: 'Initial Charge',
        value: refundInvoice?.invoiceValue as number,
      })

      return {
        giftCard: { id: giftCardId, redemptionCode },
      }
    } catch (error) {
      throw new ResolverError('Error creating/updating gift card')
    }
  }

  const refundPayment =
    refundPaymentMethod === 'card' ||
    (refundPaymentMethod === 'sameAsPurchase' &&
      automaticallyRefundPaymentMethod)

  if (refundPayment) {
    try {
      await omsClient.createInvoice(orderId, {
        type: 'Input',
        issuanceDate: createdAt,
        invoiceNumber: refundInvoice?.invoiceNumber as string,
        invoiceValue: refundInvoice?.invoiceValue as number,
        items:
          refundInvoice?.items?.map((item) => {
            return {
              id: item.id as string,
              price: (item.price as number) - (item.restockFee as number),
              quantity: item.quantity as number,
            }
          }) ?? [],
      })

      return null
    } catch (error) {
      throw new ResolverError('Error creating refund invoice')
    }
  }

  return null
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of return-app/node/utils/transformShippingData.ts from the return-app VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ShippingDetail } from '@vtex/clients'
import type { ShippingData } from 'vtex.return-app'

export const transformShippingData = (
  shippingData: ShippingDetail
): ShippingData => {
  const { address } = shippingData

  const complement = address.complement ?? ''

  /**
   * Order has type pickup for pickup orders.
   * Orders delivered into the customer address has type `residential`
   * TODO: Map other address types
   */
  const addressType =
    address.addressType === 'pickup' ? 'PICKUP_POINT' : 'CUSTOMER_ADDRESS'

  return {
    addressId: address.addressId ?? '',
    country: address.country,
    city: address.city,
    address: `${address.street}, ${address.number ?? ''} ${complement}`.trim(),
    state: address.state,
    zipCode: address.postalCode,
    addressType,
    // @ts-expect-error geoCoordinates is not typed in the OMS client project
    geoCoordinates: address.geoCoordinates,
  }
}

```