Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
82 changes: 63 additions & 19 deletions imports/plugins/core/orders/server/no-meteor/queries/orders.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,35 @@ import ReactionError from "@reactioncommerce/reaction-error";
* @param {Object} context - an object containing the per-request state
* @param {Object} params - request parameters
* @param {String} params.accountId - Account ID to search orders for
* @param {String} params.orderStatus - Workflow status to limit search results
* @param {String} params.shopIds - Shop IDs for the shops that owns the orders
* @param {Object} params.filters - Filters to apply to a list of orders
* @param {Array.<String>} params.shopIds - Shop IDs for the shops that owns the orders
* @returns {Promise<Object>|undefined} - An Array of Order documents, if found
*/
export default async function orders(context, { filter, orderStatus, shopIds } = {}) {
export default async function orders(context, { filters, shopIds } = {}) {
const { collections, shopsUserHasPermissionFor, userHasPermission } = context;
const { Orders } = collections;

let query = {};
const query = {};
let createdAtFilter = {};
let fulfillmentStatusFilter = {};
let paymentStatusFilter = {};
let searchFieldFilter = {};
let statusFilter = {};

// Add a date range filter if provided, the filter will be
// applied to the createdAt database field.
if (filters && filters.createdAt) {
const { createdAt } = filters;
// Both fields are optional
const gteProp = createdAt.gte ? { $gte: createdAt.gte } : {};
const lteProp = createdAt.lte ? { $lte: createdAt.lte } : {};
createdAtFilter = {
createdAt: {
...gteProp,
...lteProp
}
};
}

// If an admin wants all orders for an account, we force it to be limited to the
// shops for which they're allowed to see orders.
Expand All @@ -34,15 +54,39 @@ export default async function orders(context, { filter, orderStatus, shopIds } =
query.shopId = { $in: shopIdsUserHasPermissionFor };
}

// Use `filter` to filter out results on the server
if (filter) {
const regexMatch = { $regex: escapeRegExp(filter), $options: "i" };
query = {
// Add fulfillment status if provided
if (filters && filters.fulfillmentStatus) {
const prefix = filters.fulfillmentStatus === "new" ? "" : "coreOrderWorkflow/";
fulfillmentStatusFilter = {
"shipping.workflow.status": `${prefix}${filters.fulfillmentStatus}`
};
}

// Add payment status filters if provided
if (filters && filters.paymentStatus) {
paymentStatusFilter = {
"payments.status": filters.paymentStatus
};
}

// Add order status filter if provided
if (filters && filters.status) {
const prefix = filters.status === "new" ? "" : "coreOrderWorkflow/";
statusFilter = {
"workflow.status": { $eq: `${prefix}${filters.status}` }
};
}

// Use `filters` to filters out results on the server
if (filters && filters.searchField) {
const { searchField } = filters;
const regexMatch = { $regex: escapeRegExp(searchField), $options: "i" };
searchFieldFilter = {
$or: [
// Exact matches
{ _id: filter }, // exact match the order id
{ referenceId: filter }, // exact match the reference id
{ email: filter }, // exact match the email
{ _id: searchField }, // exact match the order id
{ referenceId: searchField }, // exact match the reference id
{ email: searchField }, // exact match the email

// Regex match names as they include the whole name in one field
{ "payments.address.fullName": regexMatch },
Expand All @@ -51,14 +95,14 @@ export default async function orders(context, { filter, orderStatus, shopIds } =
};
}

// If orderStatus array is provided, only return orders with statuses in Array
// Otherwise, return all orders
if (Array.isArray(orderStatus) && orderStatus.length > 0) {
query = {
"workflow.status": { $in: orderStatus },
...query
};
}
// Build the final query
query.$and = [{
...createdAtFilter,
...fulfillmentStatusFilter,
...paymentStatusFilter,
...searchFieldFilter,
...statusFilter
}];

return Orders.find(query);
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,19 @@ import { decodeShopOpaqueId } from "@reactioncommerce/reaction-graphql-xforms/sh
* @summary Get an order by its reference ID
* @param {Object} parentResult - unused
* @param {ConnectionArgs} args - An object of all arguments that were sent by the client
* @param {String} args.filter - filter by _id, referenceId, email and name
* @param {String} args.orderStatus - workflow status to limit search results
* @param {Object} args.filters - An Object of filters to apply
* @param {String} args.shopIds - shop IDs to check for orders from
* @param {Object} context - An object containing the per-request state
* @param {Object} info Info about the GraphQL request
* @returns {Promise<Object>|undefined} An Order object
*/
export default async function orders(parentResult, args, context, info) {
const { filter, orderStatus, shopIds: opaqueShopIds, ...connectionArgs } = args;
const { filters, shopIds: opaqueShopIds, ...connectionArgs } = args;

const shopIds = opaqueShopIds && opaqueShopIds.map(decodeShopOpaqueId);

const query = await context.queries.orders(context, {
filter,
orderStatus,
filters,
shopIds
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,8 @@ extend type Query {

"Get all orders for a single account, optionally limited to certain shop IDs and certain orderStatus"
orders(
"A filter string"
filter: String

"Limit to orders with one of these statuses"
orderStatus: [String]
"Filters to apply to a list of orders"
filters: OrderFilterInput

"Provide a list of shop IDs from which you want to get orders from"
shopIds: [ID]
Expand Down Expand Up @@ -986,3 +983,66 @@ type UpdateOrderFulfillmentGroupPayload {
"The updated order"
order: Order!
}

"Available order fulfillment statuses"
enum OrderFulfillmentStatus {
"An order that has been completed"
completed

"Newly created order that needs processing"
new

"An order that is currently being processed"
processing
}

"Order payment status"
enum OrderPaymentStatus {
"Payments that have been successfully processed"
completed

"A payment intent has been created"
created
}

"Order status"
enum OrderStatus {
"Canceled order"
canceled

"A completed order"
completed

"A new order that needs processing"
new

"An order that is being processed"
processing
}

"Input for the createdAt database field"
input CreatedAtInput {
"Start date, inclusive"
gte: DateTime

"End date, inclusive"
lte: DateTime
}

"Input type for filters to by applied to an Orders list"
input OrderFilterInput {
"A createdAt date range to filter by"
createdAt: CreatedAtInput

"An order's fulfillment status"
fulfillmentStatus: OrderFulfillmentStatus

"An order's payment status"
paymentStatus: OrderPaymentStatus

"Keywords typed by the user in the search input field"
searchField: String

"The order's status to filter by"
status: OrderStatus
}