Skip to content

Conversation

@bodhish
Copy link
Member

@bodhish bodhish commented Jan 2, 2026

Proposed Changes

This pull request introduces significant improvements to the invoice editing experience, particularly around managing discounts. The main enhancements include enabling users to apply or clear global discounts across all invoice items easily, improving discount selection logic, and refining form validation for discounts. Additionally, new translation strings have been added to support these features.

Invoice discount management improvements:

  • Added the ability to apply any global discount to all invoice items at once via a dropdown in the discounts column header, and to clear all discounts from all items with a single action. Success toasts are shown for both actions. (EditInvoiceTable.tsx) [1] [2]
  • Updated discount selection logic so that available discounts are now sourced from facility-wide global discounts rather than per-item definitions, ensuring consistency and simplifying the UI. (EditInvoiceTable.tsx) [1] [2] [3] [4] [5] [6]

Form validation and schema adjustments:

  • Modified the discount schema to allow a factor and amount of zero (previously only values greater than zero were allowed), and clarified validation messages for the amount field. (EditInvoiceTable.tsx)

Translation and UI updates:

  • Added new translation strings for "Apply to All", "All discounts cleared", and "Discount added to all applicable items" to support the new discount management features. (en.json) [1] [2] [3]
  • Updated UI imports and components to support the dropdown menu for bulk discount actions. (EditInvoiceTable.tsx) [1] [2] [3]

These changes make it much easier and more intuitive for users to manage discounts on invoices, especially when dealing with multiple items.

Tagging: @ohcnetwork/care-fe-code-reviewers

Merge Checklist

  • Add specs that demonstrate the bug or test the new feature.
  • Update product documentation.
  • Ensure that UI text is placed in I18n files.
  • Prepare a screenshot or demo video for the changelog entry and attach it to the issue.
  • Request peer reviews.
  • Complete QA on mobile devices.
  • Complete QA on desktop devices.
  • Add or update Playwright tests for related changes

Summary by CodeRabbit

Release Notes

  • New Features
    • Global discounts can now be applied to all invoice items at once via a dedicated dropdown menu in the Discounts section.
    • Added ability to clear all applied discounts across invoice items with a single action.
    • Global discounts are now sourced from facility settings for consistent discount management.

✏️ Tip: You can customize this high-level summary in your review settings.

@bodhish bodhish requested review from a team and Copilot January 2, 2026 18:30
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 2, 2026

Walkthrough

The changes introduce global discount functionality by adding translation keys for discount operations and refactoring the EditInvoiceTable component to apply discounts from facility settings to all items, including new handlers for applying and clearing discounts.

Changes

Cohort / File(s) Summary
Localization Updates
public/locale/en.json
Added three new translation keys: "all_discounts_cleared", "apply_to_all", "global_discount_applied" for discount UI messaging.
Global Discount Implementation
src/components/Billing/Invoice/EditInvoiceTable.tsx
Refactored discount logic to use facility-level global discounts instead of per-item discounts. Added dropdown menu in Discounts header with "Apply to All" and "Clear All" actions. Introduced handleApplyGlobalDiscount and handleClearAllDiscounts handlers. Integrated useCurrentFacility hook. Updated priceComponentSchema validation to allow factor ≥ 0 and amount ≥ 0.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and concisely summarizes the primary change—adding global discount support to invoice editing.
Description check ✅ Passed The description comprehensively covers all changes with technical details, references, and follows the required template structure including merge checklist.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bodhi/apply-global-discounts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enhances invoice discount management by enabling bulk discount operations. Users can now apply facility-wide global discounts to all invoice items at once or clear all discounts with a single action, improving efficiency when managing multiple invoice items.

Key changes:

  • Added dropdown menu in the discounts column header with "Apply to All" functionality for each global discount and a "Clear All" option
  • Migrated discount selection from per-item charge definitions to facility-wide global discounts for consistency
  • Relaxed discount validation to allow zero values

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.

File Description
src/components/Billing/Invoice/EditInvoiceTable.tsx Added bulk discount operations, migrated to facility-wide discounts, and updated validation schema
public/locale/en.json Added translation strings for new bulk discount features

.refine((val) => !val || Number(val) > 0, {
message: "Amount must be greater than 0",
.refine((val) => !val || Number(val) >= 0, {
message: "Amount must be a valid number",
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The error message 'Amount must be a valid number' is misleading. The validation is checking if the amount is >= 0, not whether it's a valid number (the Number() conversion handles that). Consider a more specific message like 'Amount must be 0 or greater' or 'Amount cannot be negative' to accurately reflect what's being validated.

Suggested change
message: "Amount must be a valid number",
message: "Amount cannot be negative",

Copilot uses AI. Check for mistakes.
const globalDiscounts = [
...(facility?.discount_monetary_components || []),
...(facility?.instance_discount_monetary_components || []),
].filter((d) => d != null);
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

Use strict equality !== null instead of loose equality != null. The loose equality check will filter out both null and undefined, which may hide potential issues. If filtering both is intentional, consider using d != null with a comment explaining why, or explicitly check for both: d !== null && d !== undefined.

Suggested change
].filter((d) => d != null);
].filter((d) => d !== null && d !== undefined);

Copilot uses AI. Check for mistakes.
Comment on lines +318 to +326
const handleApplyGlobalDiscount = (discountKey: string) => {
const items = form.getValues("items");

// Find the discount definition from the global discounts
const discountDefinition = globalDiscounts.find(
(d) => getDiscountComponentKey(d) === discountKey,
);

if (!discountDefinition) return;
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The handleApplyGlobalDiscount function lacks test coverage for its core logic: finding discount definitions, checking for existing discounts, and applying discounts to multiple items. Consider adding tests to verify behavior when discounts are already applied, when discount definitions are not found, and when successfully applying to all items.

Copilot uses AI. Check for mistakes.
Comment on lines +361 to +367
const handleClearAllDiscounts = () => {
const items = form.getValues("items");
items.forEach((_, itemIndex) => {
form.setValue(`items.${itemIndex}.discounts`, []);
});
toast.success(t("all_discounts_cleared"));
};
Copy link

Copilot AI Jan 2, 2026

Choose a reason for hiding this comment

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

The handleClearAllDiscounts function lacks test coverage. Add tests to verify that all discounts are correctly cleared from all items and that the success toast is displayed.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e86ac89 and ebd92cc.

📒 Files selected for processing (2)
  • public/locale/en.json
  • src/components/Billing/Invoice/EditInvoiceTable.tsx
🧰 Additional context used
📓 Path-based instructions (13)
public/locale/**/*.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use i18n Locale files with English Locale files in public/locale/en.json - non-English languages managed via Crowdin only

Files:

  • public/locale/en.json
**/*

📄 CodeRabbit inference engine (CLAUDE.md)

Use 2-space indentation

Files:

  • public/locale/en.json
  • src/components/Billing/Invoice/EditInvoiceTable.tsx
**/*.{ts,tsx,js,jsx,json,css,scss,html}

📄 CodeRabbit inference engine (AGENTS.md)

Use 2-space indentation

Files:

  • public/locale/en.json
  • src/components/Billing/Invoice/EditInvoiceTable.tsx
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx}: Write concise, technical TypeScript code with accurate examples
Use TypeScript for all code; prefer interfaces over types
Avoid enums; use maps instead
Use TanStack Query for data fetching from the API along with query and mutate utilities for the queryFn and mutationFn
Use raviger for routing

**/*.{ts,tsx}: Use TypeScript with strict mode and ES2022 target
Use interface for defining object types in TypeScript
Avoid explicit any type in TypeScript
Use proper nullability annotations in TypeScript types
Use dedicated error handlers and TypeScript strict null checks

**/*.{ts,tsx}: Use TypeScript for all new code
Prefer interfaces over types for object definitions in TypeScript
Avoid using any type; use proper type definitions in TypeScript
Use type inference where possible in TypeScript
Use TanStack Query for API data management
Prefer React Context for global state management

**/*.{ts,tsx}: Use TanStack Query with the query and mutate utilities from @/Utils/request/
Use appropriate query keys following the resource pattern for TanStack Query
Leverage TanStack Query built-in features for pagination and debouncing
Implement proper error handling using the global error handler for TanStack Query operations
Use useQuery hook with queryKey and queryFn parameters, where queryFn wraps the API route with the query() utility
Use useMutation hook with mutationFn parameter wrapping API routes with the mutate() utility, and implement onSuccess callbacks to invalidate related queries
Support path parameters in TanStack Query using the pathParams option in query/mutate utilities
Support query parameters in TanStack Query using the queryParams option in query/mutate utilities
Use the silent: true option to suppress global error notifications when custom error handling is needed

**/*.{ts,tsx}: Use TypeScript with strict mode and ES2022 target
Use interface for defining object types
Avoid explicit any types and maint...

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.cursorrules)

**/*.{ts,tsx,js,jsx}: Use functional and declarative programming patterns; avoid classes
Prefer iteration and modularization over code duplication
Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError)
Use the "function" keyword for pure functions
Avoid unnecessary curly braces in conditionals; use concise syntax for simple statements

**/*.{ts,tsx,js,jsx}: Use path aliases for imports from src (@/*)
Use double quotes for strings
Semicolons are required at end of statements
Order imports as: 3rd-party → library → CAREUI → UI → components → hooks → utils → relative
Use PascalCase for component and class names
Use camelCase for variable and function names

**/*.{ts,tsx,js,jsx}: Use path aliases @/* for imports from src directory
Use double quotes for strings
Require semicolons at end of statements
Order imports: 3rd-party → library → CAREUI → UI → components → hooks → utils → relative
Use PascalCase for component and class names
Use camelCase for variable and function names

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
**/*.{tsx,jsx}

📄 CodeRabbit inference engine (.cursorrules)

Use declarative JSX

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{ts,tsx}: Use strict TypeScript configuration for medical data safety in all TypeScript source files
All literal strings must use i18next for multi-language support in healthcare interfaces
Use comprehensive error boundaries and user-friendly error messages for medical workflow debugging without exposing PHI
Follow ESLint configured rules for React hooks, accessibility, and code quality
Use @tanstack/react-query for server state management in API client code
Localize date and time formats for medical timestamps using locale-aware formatting functions
Use date-fns for date handling and manipulation with locale awareness for medical timestamps

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
src/components/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/components/**/*.{ts,tsx}: Implement WCAG 2.1 AA accessibility compliance in medical applications with screen reader compatibility and keyboard navigation
Include medical use cases, accessibility notes, and WCAG compliance documentation in component documentation
Follow established React component patterns and folder structure organized by feature and domain

src/components/**/*.{ts,tsx}: Use path aliases: @/components/, @/types/, @/lib/, @/pages/ for imports
Follow import order: External packages → @/components/ui/@/components/@/CAREUI/@/types/@/lib/ → relative imports
Use named exports from lucide-react for icons (e.g., import { SettingsIcon } from "lucide-react")
Import useTranslation from react-i18next for internationalization
Use React 19.1.1 hooks pattern - Functional components only
Always define TypeScript Props interfaces (e.g., PatientInfoCardProps) for component props
Use handle prefix for event handlers (e.g., handleSubmit, handleTagsUpdate, handlePatientSelect)
Use shadcn/ui components as primary UI system (Button, Card, Badge, etc.) from @/components/ui/
Use healthcare-specific CAREUI custom components (Calendar, WeekdayCheckbox, Zoom) from @/CAREUI/
Use buttonVariants from @/components/ui/button with CVA patterns for button styling
Follow <Card><CardHeader> pattern for consistent card layouts
Use PatientRead type from @/types/emr/patient/patient for patient data handling
Implement TagAssignmentSheet with TagEntityType for patient/facility tags
Use PatientHoverCard for patient info overlays
Use Badge components to display patient status, facility capacity, medication dosage with color variants
Use cva() from class variance authority for variant-based component styling
Use cn() from @/lib/utils for conditional class composition
Follow Tailwind CSS 4.1.3 color system: primary-700, gray-900, red-500 pattern with dark mode variants
Use Tailwind shadow system: shadow-sm, shadow-xs for el...

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
src/**/*.{ts,tsx,css}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Prettier for consistent code formatting across the healthcare application

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
src/**/*.{tsx,ts}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

src/**/*.{tsx,ts}: Use React 19.1.1 features and patterns following React 19 Documentation for healthcare application development
Use shadcn/ui as primary component system and CAREUI for healthcare-specific components
Use framer-motion for animations in healthcare UI interfaces

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
src/**/*.{tsx,css}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use Tailwind CSS 4.1.3 utility classes with custom healthcare-specific design system for styling

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
**/*.tsx

📄 CodeRabbit inference engine (.cursor/rules/02-coding-standards.mdc)

**/*.tsx: Use functional components with proper type definitions in React
One component per file is preferred
Prefer default exports for React components
Follow the component naming pattern: ComponentName.tsx for React components
Use Tailwind CSS for styling
Use Shadcn UI components when available
Use local state for component-specific data
Use PascalCase for component file names (e.g., AuthWizard.tsx)

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
**/*.{tsx,ts}

📄 CodeRabbit inference engine (.cursor/rules/04-ui-components.mdc)

**/*.{tsx,ts}: Use Shadcn UI components as the primary component library
Follow the component documentation for proper usage
Customize components using Tailwind CSS
Use navigate and useRedirect from raviger for navigation and redirects
Use Tailwind's responsive classes and follow mobile-first approach
Implement proper ARIA attributes for accessibility
Ensure keyboard navigation works in components
Define component props using TypeScript interfaces
Use translation keys from src/Locale/ for internationalization
Support RTL languages in components
Use proper date/time formatting for multiple language support

Files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
🧠 Learnings (26)
📚 Learning: 2025-01-14T09:50:51.248Z
Learnt from: rajku-dev
Repo: ohcnetwork/care_fe PR: 9887
File: src/components/Users/CreateUserForm.tsx:86-92
Timestamp: 2025-01-14T09:50:51.248Z
Learning: When suggesting new validation messages in code, always check and add corresponding translation keys to the locale files (e.g., public/locale/en.json) to maintain internationalization support.

Applied to files:

  • public/locale/en.json
📚 Learning: 2025-01-14T09:50:51.248Z
Learnt from: rajku-dev
Repo: ohcnetwork/care_fe PR: 9887
File: src/components/Users/CreateUserForm.tsx:86-92
Timestamp: 2025-01-14T09:50:51.248Z
Learning: When suggesting new validation messages or error strings in code, always ensure corresponding translation keys are added to the locale files (e.g., public/locale/en.json).

Applied to files:

  • public/locale/en.json
📚 Learning: 2025-01-15T04:16:14.978Z
Learnt from: rithviknishad
Repo: ohcnetwork/care_fe PR: 9956
File: src/pages/Patient/index.tsx:71-71
Timestamp: 2025-01-15T04:16:14.978Z
Learning: In this project, translations are only added to the English locale (en.json) through pull requests. Other locale files are managed through Crowdin and should not be modified directly in PRs.

Applied to files:

  • public/locale/en.json
📚 Learning: 2025-11-25T13:50:10.786Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T13:50:10.786Z
Learning: Applies to public/locale/**/*.json : Use i18n Locale files with English Locale files in `public/locale/en.json` - non-English languages managed via Crowdin only

Applied to files:

  • public/locale/en.json
📚 Learning: 2025-11-25T13:49:43.065Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .cursorrules:0-0
Timestamp: 2025-11-25T13:49:43.065Z
Learning: Applies to {en.json,components/**/*.{ts,tsx}} : Add and reuse proper translations for the components in the en.json file

Applied to files:

  • public/locale/en.json
📚 Learning: 2025-01-15T04:16:14.978Z
Learnt from: rithviknishad
Repo: ohcnetwork/care_fe PR: 9956
File: src/pages/Patient/index.tsx:71-71
Timestamp: 2025-01-15T04:16:14.978Z
Learning: In this project, new translation strings must only be added to the English locale (en.json) through pull requests. Translations for other languages (ta.json, mr.json, ml.json, hi.json, kn.json, etc.) are managed through Crowdin (https://crowdin.com/project/ohccarefe) and should not be modified directly in PRs.

Applied to files:

  • public/locale/en.json
📚 Learning: 2025-08-26T06:35:18.610Z
Learnt from: Denyme24
Repo: ohcnetwork/care_fe PR: 13514
File: src/pages/Facility/settings/billing/discount/discount-components/DiscountComponentSettings.tsx:111-119
Timestamp: 2025-08-26T06:35:18.610Z
Learning: In src/pages/Facility/settings/billing/discount/discount-components/DiscountComponentSettings.tsx, the Input component uses className="w-full lg:w-[250px]" instead of matching the Discount Codes section's lg:w-[300px] due to specific responsiveness issues on medium screen sizes.

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-09-02T04:58:06.800Z
Learnt from: Denyme24
Repo: ohcnetwork/care_fe PR: 13238
File: src/pages/Facility/settings/billing/discount/discount-components/DiscountMonetaryComponentForm.tsx:63-67
Timestamp: 2025-09-02T04:58:06.800Z
Learning: In the care_fe project's discount forms (DiscountMonetaryComponentForm.tsx), maintainers prefer using path: ["factor", "amount"] for cross-field validation rather than dynamic path binding like path: [valueType]. The approach of adding per-field FormMessage components for either/or validation was previously rejected by maintainers.

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:50:10.786Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T13:50:10.786Z
Learning: Applies to src/**/*{[Ff]orm,[Ii]nput,[Ff]ield}*.{ts,tsx} : Use react-hook-form with zod validation for medical data integrity in form components

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:50:54.683Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/instructions/common.instructions.md:0-0
Timestamp: 2025-11-25T13:50:54.683Z
Learning: Applies to src/common/**/validation.tsx : Use zod for form validation schemas in validation.tsx

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:51:32.224Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/instructions/hooks.instructions.md:0-0
Timestamp: 2025-11-25T13:51:32.224Z
Learning: Applies to src/hooks/**/*.{ts,tsx} : Use `useState` for local state and `tanstack/react-query` for server state in custom hooks

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:52:51.914Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/instructions/react-components.instructions.md:0-0
Timestamp: 2025-11-25T13:52:51.914Z
Learning: Applies to src/components/**/*.{ts,tsx} : Import `useTranslation` from `react-i18next` for internationalization

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:54:24.075Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .cursor/rules/03-data-fetching.mdc:0-0
Timestamp: 2025-11-25T13:54:24.075Z
Learning: Applies to **/*.{ts,tsx} : Use `useMutation` hook with `mutationFn` parameter wrapping API routes with the `mutate()` utility, and implement `onSuccess` callbacks to invalidate related queries

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-01-31T22:13:06.153Z
Learnt from: AdityaJ2305
Repo: ohcnetwork/care_fe PR: 10345
File: src/components/Resource/ResourceDetailsUpdate.tsx:132-145
Timestamp: 2025-01-31T22:13:06.153Z
Learning: The migration from useTanStackQueryInstead to useQuery in React components requires:
1. Updating types to use UseQueryResult instead of custom hook return type
2. Replacing loading with isLoading property
3. Using queryKey array for cache management
4. Using queryFn with query utility function

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-03-30T12:22:58.576Z
Learnt from: hrit2773
Repo: ohcnetwork/care_fe PR: 11447
File: src/components/Questionnaire/QuestionnaireEditor.tsx:1055-1069
Timestamp: 2025-03-30T12:22:58.576Z
Learning: In the QuestionnaireEditor component, React Hook Form's onChange handlers are intentionally overridden with custom updateField calls to maintain component-specific state management instead of relying on React Hook Form's internal state.

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:50:10.786Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-25T13:50:10.786Z
Learning: Custom React hooks for healthcare workflows must follow hooks.instructions.md

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:52:33.081Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/instructions/providers.instructions.md:0-0
Timestamp: 2025-11-25T13:52:33.081Z
Learning: Applies to src/Providers/**/*.{ts,tsx} : Integrate with tanstack/react-query for server state management in providers

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:50:46.407Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/instructions/careui.instructions.md:0-0
Timestamp: 2025-11-25T13:50:46.407Z
Learning: Applies to src/CAREUI/**/*.{ts,tsx} : Integrate CAREUI components with React Query for real-time data from medical API endpoints

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:51:23.408Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/instructions/context.instructions.md:0-0
Timestamp: 2025-11-25T13:51:23.408Z
Learning: Applies to src/context/**/FacilityContext.tsx : Implement Facility Context for department location and resource availability

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:51:23.408Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/instructions/context.instructions.md:0-0
Timestamp: 2025-11-25T13:51:23.408Z
Learning: Applies to src/context/**/ShortcutContext.tsx : Implement ShortcutContext with medical workflow keyboard shortcuts for rapid clinical actions and emergency protocol shortcuts for rapid response scenarios, including accessibility shortcuts for clinical environments

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2024-11-12T12:46:55.920Z
Learnt from: Jacobjeevan
Repo: ohcnetwork/care_fe PR: 9080
File: src/components/Users/LinkedFacilities.tsx:42-42
Timestamp: 2024-11-12T12:46:55.920Z
Learning: In the `LinkedFacilities` component (`src/components/Users/LinkedFacilities.tsx`), when using `FacilitySelect` which supports an array of `FacilityModel` items, and restricting selection to just one, it's acceptable to keep the `facility` state typed as `any` to maintain compatibility.

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-09-22T19:02:08.124Z
Learnt from: Denyme24
Repo: ohcnetwork/care_fe PR: 13799
File: src/pages/Scheduling/components/CreateScheduleTemplateSheet.tsx:115-122
Timestamp: 2025-09-22T19:02:08.124Z
Learning: In the care_fe project's form components (like CreateScheduleTemplateSheet.tsx), maintainers use the union/refine pattern (z.union([z.number().min(1), z.undefined()]).refine()) for numeric fields instead of z.number({ required_error, invalid_type_error }) because their forms initialize with undefined values and use onChange handlers that convert invalid inputs back to undefined. This pattern maintains consistency with existing form architecture and avoids requiring refactoring of initialization and input handling logic.

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:50:54.683Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/instructions/common.instructions.md:0-0
Timestamp: 2025-11-25T13:50:54.683Z
Learning: Applies to src/common/**/validation.tsx : Form validation should use zod schemas with appropriate min/max constraints for vital signs (temperature: 95-110, heart rate: 30-200, blood pressure: 60-250 systolic / 40-150 diastolic)

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-11-25T13:53:20.837Z
Learnt from: CR
Repo: ohcnetwork/care_fe PR: 0
File: .github/instructions/typescript-types.instructions.md:0-0
Timestamp: 2025-11-25T13:53:20.837Z
Learning: Applies to src/types/**/*.{ts,tsx} : Zod schema definitions must match corresponding TypeScript interfaces, including validation rules (min/max for strings/numbers, regex for phone numbers, nativeEnum for enums), and export inferred types

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-12-17T19:47:58.152Z
Learnt from: AdityaJ2305
Repo: ohcnetwork/care_fe PR: 14821
File: src/components/Location/LocationNavigation.tsx:161-163
Timestamp: 2025-12-17T19:47:58.152Z
Learning: To ensure the remove-unused-i18n.js cleanup script detects i18n keys, avoid wrapping keys inside a ternary expression passed directly to t(). Instead, call t() separately in each branch of a conditional, e.g. condition ? t("key1") : t("key2"), or compute the key in a variable before passing to t(). For LocationNavigation.tsx (and similar TSX files in the repo), prefer explicit separate i18n calls per branch or a shared precomputed key to guarantee all keys are statically detectable by the script.

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
📚 Learning: 2025-12-22T10:16:36.690Z
Learnt from: Jacobjeevan
Repo: ohcnetwork/care_fe PR: 14804
File: src/pages/Facility/services/pharmacy/DispensesView.tsx:117-135
Timestamp: 2025-12-22T10:16:36.690Z
Learning: In the care_fe repository, prefer the native HTML title attribute for simple tooltips over using shadcn/ui Tooltip components. Use Tooltip components only when the tooltip requires richer content, interactivity, or accessibility enhancements that cannot be achieved with a plain title. For simple cases, add a title attribute to the element (e.g., <span title="...">). If a Tooltip is used, ensure it is accessible and necessary, and avoid duplicating content available in the title attribute.

Applied to files:

  • src/components/Billing/Invoice/EditInvoiceTable.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build
  • GitHub Check: Test
  • GitHub Check: CodeQL-Build
🔇 Additional comments (8)
public/locale/en.json (3)

600-600: New toast string for clearing discounts looks good

"all_discounts_cleared": "All discounts cleared" is clear, concise, and matches existing wording patterns for completion toasts.

Based on learnings, adding this only in en.json is correct.


660-660: Bulk action label apply_to_all is appropriate

"apply_to_all": "Apply to All" is a good, self-explanatory label for the global discount dropdown action and aligns with neighboring action strings.

Based on learnings, this is an appropriate new i18n key in en.json.


2424-2424: global_discount_applied message matches the new feature semantics

"global_discount_applied": "Discount added to all applicable items" reads well for a success toast and correctly scopes to “applicable” items, which matches expected billing behavior.

Based on learnings, using a dedicated key here is the right i18n approach.

src/components/Billing/Invoice/EditInvoiceTable.tsx (5)

494-513: LGTM! Well-structured discount display logic.

The conditional logic correctly handles multiple scenarios:

  • No global discounts available and no applied discounts → show "no discounts" message
  • Global discounts available → show add button if more can be added
  • Applied discounts → render discount rows

This approach properly handles the transition to global discounts while preserving existing applied discounts.


400-439: Both translation keys are already present in the locale file and properly configured. No action needed.


361-367: No issues found. The translation key "all_discounts_cleared" exists in the locale files and the implementation is correct.


80-80: Remove this comment—the filter at lines 220-223 prevents 0-value discounts from being submitted.

The submission filter explicitly requires discount.factor > 0 (not >= 0), so a discount with factor: 0 will not be submitted. The min(0) schema allows zero as an intermediate state (consistent with the DiscountMonetaryComponentForm.tsx pattern), but the submission logic ensures only valid discounts are sent. This is intentional and working correctly.


318-359: Translation key verified; condition handling is correct.

The translation key "global_discount_applied" exists in the locale files and resolves to "Discount added to all applicable items". The function correctly applies the discount to all items while preserving the conditions metadata, which is consistent with how other discount application functions in the file handle conditions. Conditions are stored as configuration with the discount rather than used as filtering criteria during application.

Comment on lines +260 to +264
// Get discounts from facility settings
const globalDiscounts = [
...(facility?.discount_monetary_components || []),
...(facility?.instance_discount_monetary_components || []),
].filter((d) => d != null);
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Consider adding explicit null check for facility.

The current implementation safely handles undefined facility via optional chaining and filtering, but it would be more explicit and readable to add a null check:

🔎 Suggested refinement for clarity
-  // Get discounts from facility settings
-  const globalDiscounts = [
-    ...(facility?.discount_monetary_components || []),
-    ...(facility?.instance_discount_monetary_components || []),
-  ].filter((d) => d != null);
+  // Get discounts from facility settings
+  const globalDiscounts = facility
+    ? [
+        ...(facility.discount_monetary_components || []),
+        ...(facility.instance_discount_monetary_components || []),
+      ].filter((d) => d != null)
+    : [];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Get discounts from facility settings
const globalDiscounts = [
...(facility?.discount_monetary_components || []),
...(facility?.instance_discount_monetary_components || []),
].filter((d) => d != null);
// Get discounts from facility settings
const globalDiscounts = facility
? [
...(facility.discount_monetary_components || []),
...(facility.instance_discount_monetary_components || []),
].filter((d) => d != null)
: [];
🤖 Prompt for AI Agents
In src/components/Billing/Invoice/EditInvoiceTable.tsx around lines 260 to 264,
add an explicit null/undefined check for facility before constructing
globalDiscounts: if facility is falsy, set globalDiscounts to an empty array (or
early-return/skip the downstream logic that requires discounts); otherwise build
the array from facility.discount_monetary_components and
facility.instance_discount_monetary_components and then filter out nulls. This
makes the intent clearer than relying solely on optional chaining and keeps
downstream code from operating on inferred empty values.

@github-actions
Copy link

github-actions bot commented Jan 2, 2026

🎭 Playwright Test Results

Status: ✅ Passed
Test Shards: 3

Metric Count
Total Tests 251
✅ Passed 251
❌ Failed 0
⏭️ Skipped 0

📊 Detailed results are available in the playwright-final-report artifact.

Run: #4201

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants