Skip to content
Open
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
18 changes: 18 additions & 0 deletions src/actions/__tests__/sponsor-reports-actions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
getSponsorAssetSponsor,
exportPurchaseDetailsCsv,
exportPurchaseDetailsLinesCsv,
LINES_ORDER_BY_ITEM,
exportSponsorAssetCsv,
exportSponsorAssetSectionCsv,
REQUEST_PURCHASE_DETAILS,
Expand Down Expand Up @@ -1021,6 +1022,23 @@ describe("sponsor-reports-actions", () => {
expect(params).not.toHaveProperty("order");
expect(filename).toBe("purchase-details-lines-summit-42.csv");
});

it("exportPurchaseDetailsLinesCsv passes an ordering alias through to the query", async () => {
await exportPurchaseDetailsLinesCsv(
{ status: "Paid" },
LINES_ORDER_BY_ITEM
)(dispatch, getState);
const [url, params] = getCSV.mock.calls[0];
expect(url).toBe(
"http://test-api/api/v1/summits/42/reports/purchase-details/lines/csv"
);
// item_code is declared in the endpoint's ordering_fields; the warehouse
// sheet needs every line for one item grouped together.
expect(params.order).toBe("item_code");
expect(params["filter[]"]).toEqual(
expect.arrayContaining(["status==Paid"])
);
});
});

// ─── exportSponsorAssetCsv / exportSponsorAssetSectionCsv ───────────────────
Expand Down
26 changes: 22 additions & 4 deletions src/actions/sponsor-reports-actions.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ export const PURCHASE_DETAILS_BY_ITEM_READ_ERROR =
"PURCHASE_DETAILS_BY_ITEM_READ_ERROR";
export const SET_PURCHASE_DETAILS_BY_ITEM_PAGING =
"SET_PURCHASE_DETAILS_BY_ITEM_PAGING";
export const SET_PURCHASE_DETAILS_BY_ITEM_SORT =
"SET_PURCHASE_DETAILS_BY_ITEM_SORT";

// Ordering alias on the lines endpoint (ordering_fields.item_code). Groups every
// line for one item together — the shape the warehouse pull sheet needs.
export const LINES_ORDER_BY_ITEM = "item_code";

// Per-thunk sequence-token factory guarding against stale-response commits.
// Two concurrent invocations of the same thunk (different filters/page/sponsor)
Expand Down Expand Up @@ -596,6 +602,16 @@ export const setPurchaseDetailsByItemPaging =
);
};

// Client-side sort of the derived item rows — no server ordering exists for this
// rollup. Same pure-dispatch shape as the paging sibling above.
export const setPurchaseDetailsByItemSort =
({ order, orderDir }) =>
(dispatch) => {
dispatch(
createAction(SET_PURCHASE_DETAILS_BY_ITEM_SORT)({ order, orderDir })
);
};

// Orders CSV export — owns URL + params + filename (cf. exportEventRsvpsCSV).
// Keeps the on-screen sort so the exported rows match what the user sees.
// No page/perPage → buildPurchaseQuery emits neither; backend exports the full
Expand All @@ -618,17 +634,19 @@ export const exportPurchaseDetailsCsv =
);
};

// Per-line CSV export — no order param (backend default ordering keeps sponsor
// groups intact; see lines query comment in the page).
// Per-line CSV export. `order` is an ordering alias declared by the endpoint
// (sponsor | order_date | item_code | quantity); omit it to keep the backend
// default, which groups by sponsor name. The By Item view passes item_code so
// every line for one item lands together — the warehouse pull sheet.
export const exportPurchaseDetailsLinesCsv =
(filters = {}) =>
(filters = {}, order = null) =>
async (dispatch, getState) => {
const { currentSummit } = getState().currentSummitState;
if (!currentSummit?.id) return Promise.resolve();
const accessToken = await getAccessTokenSafely();
const params = {
access_token: accessToken,
...buildPurchaseLinesQuery(filters, {})
...buildPurchaseLinesQuery({ ...filters, order }, {})
};
return dispatch(
getCSV(
Expand Down
Loading
Loading