Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Seller Quotes] feat: get seller quotes paginated api #61

Open
wants to merge 37 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
344c77f
feat: add new markeplace splitting quotes on graphql
brunass Nov 26, 2024
a9ece27
feat: checking new field quotesManagedBy when value is SELLER
tiago-freire Nov 30, 2024
d40f705
docs: update CHANGELOG
tiago-freire Dec 2, 2024
58ff10b
feat: add configuration for quote creation
brunass Dec 4, 2024
3cae023
feat: add adjustment for quote seller
brunass Dec 6, 2024
df48022
chore: fix prettier errors
tiago-freire Dec 6, 2024
85622cb
fix: returning ids separated by commas when multiple quotes
tiago-freire Dec 6, 2024
b3a2c6c
fix: check config and default settings with marketplace option
tiago-freire Dec 9, 2024
b3450d2
Merge branch 'quotes-b2b-marketplace-splitting' of github.com:cubos-v…
tiago-freire Dec 9, 2024
ffeadeb
feat: new fields for quotes managed by seller
tiago-freire Dec 9, 2024
1d8b309
feat: new fields to save parent quote; change getQuotes query to filt…
tiago-freire Dec 10, 2024
3613262
feat: create client to notify seller quote
tiago-freire Dec 10, 2024
f81db01
feat: add changelog
brunass Dec 10, 2024
9af7ee0
feat: verify and notify seller quote
tiago-freire Dec 11, 2024
caccc46
chore: removes console.log from SellerQuotesClient
tiago-freire Dec 11, 2024
5c5771f
Merge branch 'feat/splitting-quote-by-seller' of github.com:cubos-vte…
tiago-freire Dec 11, 2024
34901e0
docs: update CHANGELOG and prettier fix on markdown
tiago-freire Dec 14, 2024
70d1c4d
fix: right splitting of seller quotes
tiago-freire Dec 14, 2024
e2730f8
Merge branch 'quotes-b2b-marketplace-splitting' of github.com:cubos-v…
tiago-freire Dec 14, 2024
69d2076
feat: refactor on creating seller quote map; avoid double check of se…
tiago-freire Dec 15, 2024
92ef22e
Merge branch 'feat/notify-seller-quote' of github.com:cubos-vtex/b2b-…
tiago-freire Dec 15, 2024
fbb6529
refactor: seller quotes client constants
tiago-freire Dec 15, 2024
021b359
feat: send creationDate on notify seller quote
tiago-freire Dec 15, 2024
a69ae20
feat: provides a route for seller get a quote by id at marketplace
tiago-freire Dec 15, 2024
eeac6ab
docs: update CHANGELOG
tiago-freire Dec 15, 2024
9a7c792
refactor: separating get seller quote into smaller functions
tiago-freire Dec 17, 2024
139e696
refactor: function to get org anc cost center names
tiago-freire Dec 17, 2024
25be1ce
refactor: create service class for seller quotes
tiago-freire Dec 17, 2024
f6a1117
fix: removing approvedBySeller field from quote entity
tiago-freire Dec 17, 2024
9483253
Merge branch 'feat/notify-seller-quote' of github.com:cubos-vtex/b2b-…
tiago-freire Dec 17, 2024
babbb9a
refactor: renaming seller quotes service to controller
tiago-freire Dec 18, 2024
440e180
feat: get seller quotes paginated
guidobernal-cubos Dec 18, 2024
f0d1c55
Merge branch 'feat/get-seller-quote' into feat/get-seller-quotes-pagi…
guidobernal-cubos Dec 18, 2024
5d6c1c5
feat: use seller quote controller
guidobernal-cubos Dec 18, 2024
3541144
docs: add changelog
guidobernal-cubos Dec 18, 2024
d5673ff
chore: fix misspell
guidobernal-cubos Dec 18, 2024
42de274
fix: use array destructuring
guidobernal-cubos Dec 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,51 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Provides a route for seller get paginated list of quotes at marketplace

### Added

- Add field quotesManagedBy on appSettings to handle splitting quotes
- Process splitting quote by seller if it accepts to manage quotes
- Notify seller with quote reference data as payload
- Provides a route for seller get a quote by id at marketplace

## [2.6.4] - 2024-10-31

### Fixed

- Only update Status, LastUpdate and UpdateHistory, in expired quotes

## [2.6.3] - 2024-10-30

### Fixed

- Set viewedByCustomer value False when value is null

## [2.6.2] - 2024-10-02

### Added

- Add audit access metrics to all graphql APIs

## [2.6.1] - 2024-09-09

### Fixed

- Set viewedByCustomer value corectly on quote creation

## [2.6.0] - 2024-09-04

### Added

- Add getQuoteEnabledForUser query to be used by the b2b-quotes app

## [2.5.4] - 2024-08-20

### Fixed

- Use listUsersPaginated internally instead of deprecated listUsers

## [2.5.3] - 2024-06-10
Expand Down Expand Up @@ -76,15 +93,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [2.3.1] - 2023-09-13

### Fixed

- Use the account to get the token in the header and send it to clear the cart and order

## [2.3.0] - 2023-08-14

### Added

- Send metrics to Analytics (Create Quote and Send Message events)
- Send use quote metrics to Analytics
- Send use quote metrics to Analytics

### Removed

- [ENGINEERS-1247] - Disable cypress tests in PR level

### Changed
Expand Down
6 changes: 6 additions & 0 deletions graphql/appSettings.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ type AppSettings {
}
type AdminSetup {
cartLifeSpan: Int
quotesManagedBy: QuotesManagedBy!
}
input AppSettingsInput {
cartLifeSpan: Int
quotesManagedBy: QuotesManagedBy
}
enum QuotesManagedBy {
MARKETPLACE
SELLER
}
3 changes: 3 additions & 0 deletions graphql/quote.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ type Quote {
viewedBySales: Boolean
viewedByCustomer: Boolean
salesChannel: String
seller: String
parentQuote: String
hasChildren: Boolean
}

type QuoteUpdate {
Expand Down
62 changes: 62 additions & 0 deletions node/clients/SellerQuotesClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import type { InstanceOptions, IOContext } from '@vtex/api'
import { ExternalClient } from '@vtex/api'

const SELLER_CLIENT_OPTIONS: InstanceOptions = {
retries: 5,
timeout: 5000,
exponentialTimeoutCoefficient: 2,
exponentialBackoffCoefficient: 2,
initialBackoffDelay: 100,
}

const BASE_PATH = 'b2b-seller-quotes/_v/0'

const ROUTES = {
verifyQuoteSettings: 'verify-quote-settings',
notifyNewQuote: 'notify-new-quote',
}

export default class SellerQuotesClient extends ExternalClient {
constructor(ctx: IOContext, options?: InstanceOptions) {
super('', ctx, {
...options,
...SELLER_CLIENT_OPTIONS,
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
VtexIdclientAutCookie: ctx.authToken,
},
})
}

private getRoute(sellerAccount: string, path: string) {
const subdomain = this.context.production
? sellerAccount
: `${this.context.workspace}--${sellerAccount}`

return `http://${subdomain}.myvtex.com/${BASE_PATH}/${path}`
}

public async verifyQuoteSettings(sellerAccount: string) {
return this.http.get<VerifyQuoteSettingsResponse>(
this.getRoute(sellerAccount, ROUTES.verifyQuoteSettings)
)
}

public async notifyNewQuote(
sellerAccount: string,
quoteId: string,
creationDate: string
) {
const payload: SellerQuoteNotifyInput = {
quoteId,
creationDate,
marketplaceAccount: this.context.account,
}

return this.http.postRaw(
this.getRoute(sellerAccount, ROUTES.notifyNewQuote),
payload
)
}
}
5 changes: 5 additions & 0 deletions node/clients/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import OrdersClient from './OrdersClient'
import Organizations from './organizations'
import StorefrontPermissions from './storefrontPermissions'
import VtexId from './vtexId'
import SellerQuotesClient from './SellerQuotesClient'

export const getTokenToHeader = (ctx: IOContext) => {
// provide authToken (app token) as an admin token as this is a call
Expand Down Expand Up @@ -86,4 +87,8 @@ export class Clients extends IOClients {
public get identity() {
return this.getOrSet('identity', Identity)
}

public get sellerQuotes() {
return this.getOrSet('sellerQuotes', SellerQuotesClient)
}
}
21 changes: 21 additions & 0 deletions node/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ export const QUOTE_FIELDS = [
'viewedBySales',
'viewedByCustomer',
'salesChannel',
'seller',
'parentQuote',
'hasChildren',
]

export const routes = {
Expand Down Expand Up @@ -134,6 +137,18 @@ export const schema = {
title: 'Viewed by Sales',
type: 'boolean',
},
seller: {
title: 'Seller',
type: ['null', 'string'],
},
parentQuote: {
title: 'Parent quote',
type: ['null', 'string'],
},
hasChildren: {
title: 'Has children',
type: ['null', 'boolean'],
},
},
'v-cache': false,
'v-default-fields': [
Expand All @@ -145,6 +160,9 @@ export const schema = {
'items',
'subtotal',
'status',
'seller',
'parentQuote',
'hasChildren',
],
'v-immediate-indexing': true,
'v-indexed': [
Expand All @@ -157,5 +175,8 @@ export const schema = {
'organization',
'costCenter',
'salesChannel',
'seller',
'parentQuote',
'hasChildren',
],
}
10 changes: 9 additions & 1 deletion node/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {
ClientsConfig,
EventContext,
IOContext,
ParamsContext,
RecorderState,
ServiceContext,
Expand All @@ -11,6 +12,7 @@ import { Clients } from './clients'
import { orderHandler } from './middlewares/order'
import { resolvers } from './resolvers'
import { schemaDirectives } from './resolvers/directives'
import type SellerQuotesController from './resolvers/utils/sellerQuotesController'

const TIMEOUT_MS = 5000

Expand Down Expand Up @@ -39,7 +41,13 @@ const clients: ClientsConfig<Clients> = {

declare global {
// We declare a global Context type just to avoid re-writing ServiceContext<Clients, State> in every handler and resolver
type Context = ServiceContext<Clients>
type Context = ServiceContext<Clients> & {
vtex: IOContext & {
sellerQuotesController?: SellerQuotesController
}
}

type NextFn = () => Promise<unknown>

// The shape of our State object found in `ctx.state`. This is used as state bag to communicate between middlewares.
interface State {
Expand Down
12 changes: 0 additions & 12 deletions node/metrics/createQuote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,6 @@ type UserData = {
roleId: string
}

type SessionData = {
namespaces: {
profile: {
id: { value: string }
email: { value: string }
}
account: {
accountName: { value: string }
}
}
}

type CreateQuoteMetricParam = {
sessionData: SessionData
sendToSalesRep: boolean
Expand Down
2 changes: 1 addition & 1 deletion node/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"ramda": "^0.25.0",
"atob": "^2.1.2",
"axios": "0.27.2",
"@vtex/api": "6.47.0"
"@vtex/api": "6.48.0"
},
"devDependencies": {
"@types/atob": "^2.1.2",
Expand Down
Loading