From 7b87f90dacbaaa70ec4a64f2f00074e7caa3eaca Mon Sep 17 00:00:00 2001 From: aripot007 <32022176+aripot007@users.noreply.github.com> Date: Sun, 17 Mar 2024 22:09:33 +0100 Subject: [PATCH] Search orders by name (#73) * Add option to search by account name or nickname to /transactions * Add search bar to /comptoir/c/transactions page * Increase pagination buttons size in Transactions component * Reset page number when changing searched name * Add account name on transaction popup --- backend/api/transactions.go | 9 ++++- backend/autogen/bar.gen.go | 22 ++++++++--- backend/internal/db/database.go | 4 +- backend/internal/db/mongo/transaction_misc.go | 38 ++++++++++++++++++- bar.openapi.yml | 6 +++ frontend/src/lib/api/api.ts | 22 +++++++---- .../comptoir/transactionPopup.svelte | 1 + .../components/comptoir/transactions.svelte | 35 +++++++++++------ .../comptoir/c/transactions/+page.svelte | 6 ++- 9 files changed, 111 insertions(+), 32 deletions(-) diff --git a/backend/api/transactions.go b/backend/api/transactions.go index 62f9610..3ca1d54 100644 --- a/backend/api/transactions.go +++ b/backend/api/transactions.go @@ -147,7 +147,12 @@ func (s *Server) GetTransactions(c echo.Context, params autogen.GetTransactionsP state = string(*params.State) } - count, err := s.DBackend.CountAllTransactions(c.Request().Context(), state) + var name string + if params.Name != nil { + name = string(*params.Name) + } + + count, err := s.DBackend.CountAllTransactions(c.Request().Context(), state, name) if err != nil { logrus.Error(err) return Error500(c) @@ -156,7 +161,7 @@ func (s *Server) GetTransactions(c echo.Context, params autogen.GetTransactionsP // Make sure the last page is not empty dbpage, page, limit, maxPage := autogen.Pager(params.Page, params.Limit, &count) - data, err := s.DBackend.GetAllTransactions(c.Request().Context(), dbpage, limit, state) + data, err := s.DBackend.GetAllTransactions(c.Request().Context(), dbpage, limit, state, name) if err != nil { logrus.Error(err) return Error500(c) diff --git a/backend/autogen/bar.gen.go b/backend/autogen/bar.gen.go index c86a21d..ef970f2 100644 --- a/backend/autogen/bar.gen.go +++ b/backend/autogen/bar.gen.go @@ -890,6 +890,9 @@ type GetTransactionsParams struct { // State Filter by state State *TransactionState `form:"state,omitempty" json:"state,omitempty" bson:"state"` + + // Name Filter by account name + Name *string `form:"name,omitempty" json:"name,omitempty" bson:"name"` } // GetTransactionsItemsParams defines parameters for GetTransactionsItems. @@ -3012,6 +3015,13 @@ func (w *ServerInterfaceWrapper) GetTransactions(ctx echo.Context) error { return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter state: %s", err)) } + // ------------- Optional query parameter "name" ------------- + + err = runtime.BindQueryParameter("form", true, false, "name", ctx.QueryParams(), ¶ms.Name) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter name: %s", err)) + } + // Invoke the callback with all the unmarshaled arguments err = w.Handler.GetTransactions(ctx, params) return err @@ -10145,12 +10155,12 @@ var swaggerSpec = []string{ "UolJynB41ywn80pWIZmX7ZaUzIDeqwefqv1iwlp6xYQdpgwsKNdRCIoGDuGtGkUvq4EfiHcIIsZ79xLY", "TQIrAhMHVlZn8hmB4hnpTIpVJK+scJ2XruP15E/wIecZWziTKAoYDkIBjMMbyqujygbAJGoiz38v1EGb", "Ed5OnjFZeFxXs/pP6q+2gBR59twgALIA+azUOdA2a2CNtM1g28h5tDpfP1yGeb9Zhtm1V2treMU5nBQk", - "ScDr3UPTJfIKkwgS+tpmrux0TOnmHTvrOMDQUJydY/h4Vh/P6m2CJpvAWOmqHHRIH1Qc5MaoQSxmCYZa", - "paPT4W4hP0T2kG2eD3ZlPvuZoGecPWcc0ZJ3Jcl1TpLeSW/KWHrS7yc4BMkUU3by4+DHQY9vh0U55RXg", - "8QiQNwwmMMQzBFD4+AZB1gdp3L9/a2nAaz/CB5yM34wJr9bTYKsGoSZAhJ7iYE4h+Y7qmqiMssjekuUT", - "re7Wlg6K8DHzGVrq1Ly0v1RDU926US7l4BWBIAlmGMHH1+X7e7aeioTLRdxGjISdQqc4rUQzxNDWixBU", - "AUYBBQms6UAKBxsE+ns3Iuolf+YzH1tWsWJCRhVjosKKudKW3SMoesgCCp+/Pv9fAAAA//8VzZI33JgB", - "AA==", + "ScDr3UPTJfIKkwgS+tpmrux0TOnmHTvrOMDQUOxwjpE9t7k7Rws+XNaHy740k8NY6aqYdchOVJwTx6hB", + "6mb5i1qFr9PZcSEmRHKSbcqIrsxnP3L0jLPnjCNa8q4kuc5J0jvpTRlLT/r9BIcgmWLKTn4c/Djo8V2v", + "KKe8AjweAfKGwQSGeIYACh/fIMj6II37928tDXjtR/iAk/GbMeHVehps1RjXBIjIVhzMKSTfUV3RlUEc", + "2VO1fKLVTdnSQRGdZr5yS52al/aXauSrWzfKYx28IhAkwQwj+Pi6fD3Q1lORz7kIC4mRMIPoFKeVYIkY", + "2noRgirAKKAggTUdSOFgg0B/TkcE1eSviOZjyypWTMigZUxU1DLXCbNrCkUPWbzi89fn/wsAAP//v4hf", + "zjuZAQA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/backend/internal/db/database.go b/backend/internal/db/database.go index 671d901..d1e4bba 100644 --- a/backend/internal/db/database.go +++ b/backend/internal/db/database.go @@ -115,9 +115,9 @@ type DBackend interface { GetTransactions(ctx context.Context, account string, page uint64, size uint64, state string) ([]*models.Transaction, error) CountTransactions(ctx context.Context, account string, state string) (uint64, error) - GetAllTransactions(ctx context.Context, page uint64, size uint64, state string) ([]*models.Transaction, error) + GetAllTransactions(ctx context.Context, page uint64, size uint64, state string, name string) ([]*models.Transaction, error) + CountAllTransactions(ctx context.Context, state string, name string) (uint64, error) GetAllActiveTransactionsItems(ctx context.Context, name string) ([]autogen.TransactionItem, error) - CountAllTransactions(ctx context.Context, state string) (uint64, error) // Restock's CRUD CreateRestock(ctx context.Context, t *models.Restock) error diff --git a/backend/internal/db/mongo/transaction_misc.go b/backend/internal/db/mongo/transaction_misc.go index 1463f4c..6e687a1 100644 --- a/backend/internal/db/mongo/transaction_misc.go +++ b/backend/internal/db/mongo/transaction_misc.go @@ -56,7 +56,7 @@ func (b *Backend) CountTransactions(ctx context.Context, accountID string, state return uint64(count), nil } -func (b *Backend) GetAllTransactions(ctx context.Context, page uint64, size uint64, state string) ([]*models.Transaction, error) { +func (b *Backend) GetAllTransactions(ctx context.Context, page uint64, size uint64, state string, name string) ([]*models.Transaction, error) { ctx, cancel := b.TimeoutContext(ctx) defer cancel() @@ -66,6 +66,23 @@ func (b *Backend) GetAllTransactions(ctx context.Context, page uint64, size uint filter["state"] = state } + if name != "" { + filter["$or"] = []bson.M{ + { + "account_name": bson.M{ + "$regex": name, + "$options": "i", + }, + }, + { + "account_nick_name": bson.M{ + "$regex": name, + "$options": "i", + }, + }, + } + } + // Get "size" transactions from "page" using aggregation var transactions []*models.Transaction cursor, err := b.db.Collection(TransactionsCollection).Find(ctx, filter, options.Find().SetSkip(int64(page*size)).SetLimit(int64(size)).SetSort(bson.M{"created_at": -1})) @@ -81,7 +98,7 @@ func (b *Backend) GetAllTransactions(ctx context.Context, page uint64, size uint return transactions, nil } -func (b *Backend) CountAllTransactions(ctx context.Context, state string) (uint64, error) { +func (b *Backend) CountAllTransactions(ctx context.Context, state string, name string) (uint64, error) { ctx, cancel := b.TimeoutContext(ctx) defer cancel() @@ -91,6 +108,23 @@ func (b *Backend) CountAllTransactions(ctx context.Context, state string) (uint6 filter["state"] = state } + if name != "" { + filter["$or"] = []bson.M{ + { + "account_name": bson.M{ + "$regex": name, + "$options": "i", + }, + }, + { + "account_nick_name": bson.M{ + "$regex": name, + "$options": "i", + }, + }, + } + } + count, err := b.db.Collection(TransactionsCollection).CountDocuments(ctx, filter) if err != nil { return 0, err diff --git a/bar.openapi.yml b/bar.openapi.yml index 079775b..29e6ac1 100644 --- a/bar.openapi.yml +++ b/bar.openapi.yml @@ -1150,6 +1150,12 @@ paths: schema: type: string $ref: "#/components/schemas/TransactionState" + - name: name + in: query + description: Filter by account name + required: false + schema: + type: string responses: "200": description: "" diff --git a/frontend/src/lib/api/api.ts b/frontend/src/lib/api/api.ts index 23240b8..f1e33af 100644 --- a/frontend/src/lib/api/api.ts +++ b/frontend/src/lib/api/api.ts @@ -8111,10 +8111,11 @@ export const TransactionsApiAxiosParamCreator = function (configuration?: Config * @param {number} [page] Page number * @param {number} [limit] Number of transactions per page * @param {TransactionState} [state] Filter by state + * @param {string} [name] Filter by account name * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getTransactions: async (page?: number, limit?: number, state?: TransactionState, options: AxiosRequestConfig = {}): Promise => { + getTransactions: async (page?: number, limit?: number, state?: TransactionState, name?: string, options: AxiosRequestConfig = {}): Promise => { const localVarPath = `/transactions`; // use dummy base URL string because the URL constructor only accepts absolute URLs. const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL); @@ -8141,6 +8142,10 @@ export const TransactionsApiAxiosParamCreator = function (configuration?: Config localVarQueryParameter['state'] = state; } + if (name !== undefined) { + localVarQueryParameter['name'] = name; + } + setSearchParams(localVarUrlObj, localVarQueryParameter); @@ -8424,11 +8429,12 @@ export const TransactionsApiFp = function(configuration?: Configuration) { * @param {number} [page] Page number * @param {number} [limit] Number of transactions per page * @param {TransactionState} [state] Filter by state + * @param {string} [name] Filter by account name * @param {*} [options] Override http request option. * @throws {RequiredError} */ - async getTransactions(page?: number, limit?: number, state?: TransactionState, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { - const localVarAxiosArgs = await localVarAxiosParamCreator.getTransactions(page, limit, state, options); + async getTransactions(page?: number, limit?: number, state?: TransactionState, name?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> { + const localVarAxiosArgs = await localVarAxiosParamCreator.getTransactions(page, limit, state, name, options); return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration); }, /** @@ -8544,11 +8550,12 @@ export const TransactionsApiFactory = function (configuration?: Configuration, b * @param {number} [page] Page number * @param {number} [limit] Number of transactions per page * @param {TransactionState} [state] Filter by state + * @param {string} [name] Filter by account name * @param {*} [options] Override http request option. * @throws {RequiredError} */ - getTransactions(page?: number, limit?: number, state?: TransactionState, options?: any): AxiosPromise { - return localVarFp.getTransactions(page, limit, state, options).then((request) => request(axios, basePath)); + getTransactions(page?: number, limit?: number, state?: TransactionState, name?: string, options?: any): AxiosPromise { + return localVarFp.getTransactions(page, limit, state, name, options).then((request) => request(axios, basePath)); }, /** * Get all items in active transactions (ordered items) @@ -8664,12 +8671,13 @@ export class TransactionsApi extends BaseAPI { * @param {number} [page] Page number * @param {number} [limit] Number of transactions per page * @param {TransactionState} [state] Filter by state + * @param {string} [name] Filter by account name * @param {*} [options] Override http request option. * @throws {RequiredError} * @memberof TransactionsApi */ - public getTransactions(page?: number, limit?: number, state?: TransactionState, options?: AxiosRequestConfig) { - return TransactionsApiFp(this.configuration).getTransactions(page, limit, state, options).then((request) => request(this.axios, this.basePath)); + public getTransactions(page?: number, limit?: number, state?: TransactionState, name?: string, options?: AxiosRequestConfig) { + return TransactionsApiFp(this.configuration).getTransactions(page, limit, state, name, options).then((request) => request(this.axios, this.basePath)); } /** diff --git a/frontend/src/lib/components/comptoir/transactionPopup.svelte b/frontend/src/lib/components/comptoir/transactionPopup.svelte index d4d5699..6bd799e 100644 --- a/frontend/src/lib/components/comptoir/transactionPopup.svelte +++ b/frontend/src/lib/components/comptoir/transactionPopup.svelte @@ -182,6 +182,7 @@ - Close the popup -->
+

Commande de : {transaction.account_name}

{#each newTransaction.items as item, i} diff --git a/frontend/src/lib/components/comptoir/transactions.svelte b/frontend/src/lib/components/comptoir/transactions.svelte index ec687db..40c7917 100644 --- a/frontend/src/lib/components/comptoir/transactions.svelte +++ b/frontend/src/lib/components/comptoir/transactions.svelte @@ -12,6 +12,7 @@ let transactions: Array = []; let maxItemPerTransaction: number = 6; let interval: number; + let searchName: string | undefined; let page: number = 0; let maxPage: number = 0; @@ -45,7 +46,7 @@ function reloadTransactions() { transactionsApi() - .getTransactions(page, amount, st, { withCredentials: true }) + .getTransactions(page, amount, st, searchName, { withCredentials: true }) .then((res) => { page = res.data.page ?? 0; maxPage = res.data.max_page ?? 0; @@ -83,11 +84,23 @@ {/if} -
-
-
-
Transactions
-
+
+
+
+
+
Transactions
+ { + // @ts-ignore + searchName = e.target.value.toLowerCase(); + page = 1; + reloadTransactions(); + }} + /> +
+
Filtre :
-
Montant
+
Montant
-
+
{#each transactions as transaction} -
{page}/{maxPage}
-
+
diff --git a/frontend/src/routes/comptoir/c/transactions/+page.svelte b/frontend/src/routes/comptoir/c/transactions/+page.svelte index 4601c01..ce511cb 100644 --- a/frontend/src/routes/comptoir/c/transactions/+page.svelte +++ b/frontend/src/routes/comptoir/c/transactions/+page.svelte @@ -99,7 +99,7 @@ {#if changePassword} (changePassword = false)} /> {:else} -
+