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
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from "react";
import T from "i18n-react/dist/i18n-react";
import { currencyAmountFromCents } from "openstack-uicore-foundation/lib/utils/money";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import {
Expand Down Expand Up @@ -30,7 +31,7 @@ import {
setSelectedAll,
unSelectInventoryItem
} from "../../../actions/inventory-item-actions";
import { DECIMAL_DIGITS, DEFAULT_CURRENT_PAGE } from "../../../utils/constants";
import { DEFAULT_CURRENT_PAGE } from "../../../utils/constants";

const AddFormTemplateItemDialog = ({
onClose,
Expand Down Expand Up @@ -128,23 +129,23 @@ const AddFormTemplateItemDialog = ({
"inventory_items_list_modal.early_bid_rate_column_label"
),
sortable: false,
render: (row) => `$ ${row.early_bird_rate?.toFixed(DECIMAL_DIGITS)}`
render: (row) => currencyAmountFromCents(row.early_bird_rate)
},
{
columnKey: "standard_rate",
header: T.translate(
"inventory_items_list_modal.standard_rate_column_label"
),
sortable: false,
render: (row) => `$ ${row.standard_rate?.toFixed(DECIMAL_DIGITS)}`
render: (row) => currencyAmountFromCents(row.standard_rate)
},
{
columnKey: "onsite_rate",
header: T.translate(
"inventory_items_list_modal.onsite_rate_column_label"
),
sortable: false,
render: (row) => `$ ${row.onsite_rate?.toFixed(DECIMAL_DIGITS)}`
render: (row) => currencyAmountFromCents(row.onsite_rate)
},
{
columnKey: "default_quantity",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ jest.mock("../../../../../actions/inventory-item-actions", () => ({
}))
}));

jest.mock("openstack-uicore-foundation/lib/utils/money", () => ({
currencyAmountFromCents: jest.fn()
}));

describe("InventoryPopup", () => {
it("check if title is being rendered", async () => {
const formId = "AAA";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useEffect, useState } from "react";
import PropTypes from "prop-types";
import { currencyAmountFromCents } from "openstack-uicore-foundation/lib/utils/money";
import T from "i18n-react/dist/i18n-react";
import { connect } from "react-redux";
import {
Expand Down Expand Up @@ -121,21 +122,24 @@ const SponsorFormAddItemFromInventoryPopup = ({
header: T.translate(
"sponsor_form_item_list.add_from_inventory.early_bird_rate"
),
sortable: false
sortable: false,
render: (row) => currencyAmountFromCents(row.early_bird_rate)
Comment on lines +125 to +126

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check how inventory items are normalized/transformed to understand the rate format

# Search for inventory item normalizer or entity definition
rg -n -B2 -A10 'INVENTORY_ITEM' --type=js -g '*normalizer*'

# Check the API response handling for inventory items
rg -n -C5 'getInventoryItems' --type=js -g '*actions*'

Repository: fntechgit/summit-admin

Length of output: 952


🏁 Script executed:

# Get the full implementation of getInventoryItems
rg -n -A30 'export const getInventoryItems' src/actions/inventory-item-actions.js

Repository: fntechgit/summit-admin

Length of output: 969


🏁 Script executed:

# Find the currencyAmountFromCents function definition
fd -t f -e js | xargs rg -l 'currencyAmountFromCents' | head -5

Repository: fntechgit/summit-admin

Length of output: 407


🏁 Script executed:

# Look at the component itself to understand the data context
cat -n src/pages/sponsors/sponsor-form-item-list-page/components/sponsor-form-add-item-from-inventory-popup.js | head -150

Repository: fntechgit/summit-admin

Length of output: 4975


🏁 Script executed:

# Search for other usages of currencyAmountFromCents to understand the expected input
rg -n 'currencyAmountFromCents' --type=js -B2 -A1 | head -60

Repository: fntechgit/summit-admin

Length of output: 6308


🏁 Script executed:

# Check the inventory items reducer to see how data is handled
cat -n src/reducers/inventory-items-reducer.js | head -100

Repository: fntechgit/summit-admin

Length of output: 137


🏁 Script executed:

# Look for other rate field usage in the codebase
rg -n 'early_bird_rate|standard_rate|onsite_rate' --type=js -B1 -A1 | head -80

Repository: fntechgit/summit-admin

Length of output: 7049


🏁 Script executed:

# Check which reducer is connected to the inventoryItems state
rg -n "inventoryItems" src/reducers/sponsors_inventory/inventory-item-list-reducer.js -B5 -A15 | head -80

Repository: fntechgit/summit-admin

Length of output: 2200


🏁 Script executed:

# Look at the root reducer to understand the state structure
fd -t f -e js "*root*reducer*" | xargs rg -l "inventoryItems" 2>/dev/null | head -3

Repository: fntechgit/summit-admin

Length of output: 609


🏁 Script executed:

# Check the component's mapStateToProps to see which reducer it uses
cat -n src/pages/sponsors/sponsor-form-item-list-page/components/sponsor-form-add-item-from-inventory-popup.js | tail -30

Repository: fntechgit/summit-admin

Length of output: 1096


🏁 Script executed:

# Check amountFromCents definition to understand the transformation
rg -n "export.*amountFromCents|export.*currencyAmountFromCents" --type=js

Repository: fntechgit/summit-admin

Length of output: 48


🏁 Script executed:

# Search for how rates are used when they come from the API - look for any conversion in inventory-item-actions
cat -n src/actions/inventory-item-actions.js | sed -n '98,180p'

Repository: fntechgit/summit-admin

Length of output: 2775


🏁 Script executed:

# Check if there's documentation about the rate fields or API response format
rg -n "rate" src/actions/inventory-item-actions.js -B2 -A2 | grep -E "(comment|doc|Rate|RATE)" | head -20

Repository: fntechgit/summit-admin

Length of output: 48


🏁 Script executed:

# Look for test files or examples showing the rate field format
fd -t f -e js "*test*" -o -e spec | xargs rg -l "early_bird_rate" 2>/dev/null | head -3

Repository: fntechgit/summit-admin

Length of output: 437


🏁 Script executed:

# Check if amountFromCents is the inverse of currencyAmountFromCents
rg -n "export.*amountFromCents\|const.*amountFromCents" src/reducers/sponsors/sponsor-form-items-list-reducer.js -B2 -A5

Repository: fntechgit/summit-admin

Length of output: 48


🏁 Script executed:

# Find where amountFromCents is imported from
rg -n "import.*amountFromCents" --type=js | head -10

Repository: fntechgit/summit-admin

Length of output: 768


🏁 Script executed:

# Look at the reducer file that uses amountFromCents
head -20 src/reducers/sponsors_inventory/inventory-item-reducer.js

Repository: fntechgit/summit-admin

Length of output: 933


🏁 Script executed:

# Check if there's any transformation happening in the reducer for the inventory-item-list
rg -n "RECEIVE_INVENTORY_ITEMS" src/reducers/sponsors_inventory/inventory-item-list-reducer.js -A20

Repository: fntechgit/summit-admin

Length of output: 1314


🏁 Script executed:

# Look for what openstack-uicore-foundation exports
find . -name "package.json" | xargs grep -l "openstack-uicore-foundation" | head -1

Repository: fntechgit/summit-admin

Length of output: 80


🏁 Script executed:

# Check package.json to see the version of openstack-uicore-foundation
cat package.json | grep -A2 -B2 "openstack-uicore-foundation"

Repository: fntechgit/summit-admin

Length of output: 229


🏁 Script executed:

# Compare how other similar components handle the same situation
cat -n src/pages/sponsors-global/form-templates/add-form-template-item-popup.js | sed -n '1,160p' | tail -80

Repository: fntechgit/summit-admin

Length of output: 2561


🏁 Script executed:

# Check the inventory-item-reducer for a single item to see how it transforms rates
cat -n src/reducers/sponsors_inventory/inventory-item-reducer.js | sed -n '60,100p'

Repository: fntechgit/summit-admin

Length of output: 1556


🏁 Script executed:

# Look for any transformation happening after RECEIVE_INVENTORY_ITEMS in the list reducer
cat -n src/reducers/sponsors_inventory/inventory-item-list-reducer.js | sed -n '78,110p'

Repository: fntechgit/summit-admin

Length of output: 1192


🏁 Script executed:

# Check what format other reducers expect from the inventory item API
cat -n src/reducers/sponsors_inventory/form-template-item-reducer.js | sed -n '60,100p'

Repository: fntechgit/summit-admin

Length of output: 1581


🏁 Script executed:

# Look at how sponsor-customized-form-items-list-reducer handles the transformation
cat -n src/reducers/sponsors/sponsor-customized-form-items-list-reducer.js | sed -n '78,110p'

Repository: fntechgit/summit-admin

Length of output: 1126


🏁 Script executed:

# Check if inventory-item-list-reducer should apply amountFromCents like the single-item reducer does
rg -n "import.*amountFromCents" src/reducers/sponsors_inventory/inventory-item-list-reducer.js

Repository: fntechgit/summit-admin

Length of output: 48


🏁 Script executed:

# Check if inventory-item-list-reducer should be importing and using amountFromCents
head -25 src/reducers/sponsors_inventory/inventory-item-list-reducer.js

Repository: fntechgit/summit-admin

Length of output: 1048


🏁 Script executed:

# Look at how the component in form-templates handles the same situation - check if it also fails or uses different data
rg -n "mapStateToProps" src/pages/sponsors-global/form-templates/add-form-template-item-popup.js -A5

Repository: fntechgit/summit-admin

Length of output: 373


🏁 Script executed:

# Check what state is being used by the form-templates component
rg -n "currentFormTemplateItemListState\|currentInventoryItemListState" src/reducers --type=js | head -10

Repository: fntechgit/summit-admin

Length of output: 48


Fix the rate field transformation in the reducer, not the component.

The inventory-item-list-reducer.js is missing the rate field transformation that other similar reducers apply. When inventory items are received from the API (lines 87-89), the early_bird_rate, standard_rate, and onsite_rate fields should be transformed in the reducer—not in the component's render function.

Compare with sponsor-customized-form-items-list-reducer.js (lines 95-97), which correctly applies the transformation at the reducer level. The component render functions should receive already-formatted data.

Update src/reducers/sponsors_inventory/inventory-item-list-reducer.js to import currencyAmountFromCents and transform the rate fields in the RECEIVE_INVENTORY_ITEMS case:

import { currencyAmountFromCents } from "openstack-uicore-foundation/lib/utils/money";

// In RECEIVE_INVENTORY_ITEMS case:
const inventoryItems = payload.response.data.map((a) => ({
  id: a.id,
  code: a.code,
  name: a.name,
  images: a.images,
  is_archived: a.is_archived,
  early_bird_rate: currencyAmountFromCents(a.early_bird_rate),
  standard_rate: currencyAmountFromCents(a.standard_rate),
  onsite_rate: currencyAmountFromCents(a.onsite_rate),
  checked: false
}));

Then remove the formatting calls from the component's render functions (lines 126, 134, 142) and render the values directly.

🧰 Tools
🪛 GitHub Actions: jest

[error] 126-126: cents must be an integer number. Error originates from money.js when rendering currency via currencyAmountFromCents(row.early_bird_rate). Likely a non-integer value is being passed to currency formatter during inventory popup render.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@src/pages/sponsors/sponsor-form-item-list-page/components/sponsor-form-add-item-from-inventory-popup.js`
around lines 125 - 126, Update the RECEIVE_INVENTORY_ITEMS branch in the
inventory-item-list-reducer.js reducer to import currencyAmountFromCents from
"openstack-uicore-foundation/lib/utils/money" and map each incoming item so
early_bird_rate, standard_rate, and onsite_rate are set to
currencyAmountFromCents(a.early_bird_rate),
currencyAmountFromCents(a.standard_rate), and
currencyAmountFromCents(a.onsite_rate) respectively (keep other fields like id,
code, name, images, is_archived, checked as before); then remove the
currencyAmountFromCents calls from the render functions in
sponsor-form-add-item-from-inventory-popup.js so the component renders the
already-formatted early_bird_rate, standard_rate, and onsite_rate values
directly.

},
{
columnKey: "standard_rate",
header: T.translate(
"sponsor_form_item_list.add_from_inventory.standard_rate"
),
sortable: false
sortable: false,
render: (row) => currencyAmountFromCents(row.standard_rate)
},
{
columnKey: "onsite_rate",
header: T.translate(
"sponsor_form_item_list.add_from_inventory.onsite_rate"
),
sortable: false
sortable: false,
render: (row) => currencyAmountFromCents(row.onsite_rate)
},
{
columnKey: "hasImage",
Expand Down