-
Notifications
You must be signed in to change notification settings - Fork 988
Add support for global discounts #14993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
WalkthroughThe 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
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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", |
Copilot
AI
Jan 2, 2026
There was a problem hiding this comment.
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.
| message: "Amount must be a valid number", | |
| message: "Amount cannot be negative", |
| const globalDiscounts = [ | ||
| ...(facility?.discount_monetary_components || []), | ||
| ...(facility?.instance_discount_monetary_components || []), | ||
| ].filter((d) => d != null); |
Copilot
AI
Jan 2, 2026
There was a problem hiding this comment.
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.
| ].filter((d) => d != null); | |
| ].filter((d) => d !== null && d !== undefined); |
| 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; |
Copilot
AI
Jan 2, 2026
There was a problem hiding this comment.
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.
| const handleClearAllDiscounts = () => { | ||
| const items = form.getValues("items"); | ||
| items.forEach((_, itemIndex) => { | ||
| form.setValue(`items.${itemIndex}.discounts`, []); | ||
| }); | ||
| toast.success(t("all_discounts_cleared")); | ||
| }; |
Copilot
AI
Jan 2, 2026
There was a problem hiding this comment.
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.
There was a problem hiding this 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
📒 Files selected for processing (2)
public/locale/en.jsonsrc/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.jsonsrc/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.jsonsrc/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
Useinterfacefor defining object types in TypeScript
Avoid explicitanytype 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 usinganytype; 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 thequeryandmutateutilities 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
UseuseQueryhook withqueryKeyandqueryFnparameters, wherequeryFnwraps the API route with thequery()utility
UseuseMutationhook withmutationFnparameter wrapping API routes with themutate()utility, and implementonSuccesscallbacks to invalidate related queries
Support path parameters in TanStack Query using thepathParamsoption in query/mutate utilities
Support query parameters in TanStack Query using thequeryParamsoption in query/mutate utilities
Use thesilent: trueoption to suppress global error notifications when custom error handling is needed
**/*.{ts,tsx}: Use TypeScript with strict mode and ES2022 target
Useinterfacefor defining object types
Avoid explicitanytypes 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 fromlucide-reactfor icons (e.g.,import { SettingsIcon } from "lucide-react")
ImportuseTranslationfromreact-i18nextfor 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/
UsebuttonVariantsfrom@/components/ui/buttonwith CVA patterns for button styling
Follow<Card><CardHeader>pattern for consistent card layouts
UsePatientReadtype from@/types/emr/patient/patientfor patient data handling
ImplementTagAssignmentSheetwithTagEntityTypefor patient/facility tags
UsePatientHoverCardfor patient info overlays
Use Badge components to display patient status, facility capacity, medication dosage with color variants
Usecva()from class variance authority for variant-based component styling
Usecn()from@/lib/utilsfor 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.tsxfor 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
UsenavigateanduseRedirectfrom 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 fromsrc/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.jsonis correct.
660-660: Bulk action labelapply_to_allis 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_appliedmessage 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 withfactor: 0will not be submitted. Themin(0)schema allows zero as an intermediate state (consistent with theDiscountMonetaryComponentForm.tsxpattern), 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.
| // Get discounts from facility settings | ||
| const globalDiscounts = [ | ||
| ...(facility?.discount_monetary_components || []), | ||
| ...(facility?.instance_discount_monetary_components || []), | ||
| ].filter((d) => d != null); |
There was a problem hiding this comment.
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.
| // 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.
🎭 Playwright Test ResultsStatus: ✅ Passed
📊 Detailed results are available in the playwright-final-report artifact. Run: #4201 |
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:
EditInvoiceTable.tsx) [1] [2]EditInvoiceTable.tsx) [1] [2] [3] [4] [5] [6]Form validation and schema adjustments:
EditInvoiceTable.tsx)Translation and UI updates:
en.json) [1] [2] [3]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
Summary by CodeRabbit
Release Notes
✏️ Tip: You can customize this high-level summary in your review settings.