✨ feat(crm): set selected customer when navigating to Prämienshop
Implements autoTriggerContinueFn pattern to properly set customer context
before navigating to reward shop from customer loyalty cards view.
Changes:
- Add output event to customer-loyalty-cards component (library layer)
- Handle navigation at app layer (kundenkarte-main-view) to respect module boundaries
- Use existing autoTriggerContinueFn pattern from details-main-view
- Inject NavigationStateService and CustomerSearchNavigation services
- Preserve context with returnUrl and autoTriggerContinueFn flag
This ensures customer selection logic (_setCustomer, _setBuyer, _setSelectedCustomerIdInTab)
executes before navigating to the reward shop, matching the behavior of the
continue() method in CustomerDetailsViewMainComponent.
Refs: #5485
Related work items: #5485
Add two new skills based on Angular Architects articles:
1. ngrx-resource-api: Guide for integrating Angular's Resource API with
NgRx Signal Store for reactive data management without RxJS
- withProps pattern for dependency injection
- Resource configuration and lifecycle
- Error handling and computed derivations
- Common patterns and best practices
2. angular-effects-alternatives: Guide for proper effect() usage and
declarative alternatives to prevent anti-patterns
- Valid use cases (logging, canvas, imperative APIs)
- Anti-patterns to avoid (state propagation, synchronization)
- Decision tree for choosing alternatives
- Refactoring patterns and code review checklist
Both skills follow modern Angular patterns and promote declarative,
maintainable code aligned with reactive principles.
- Replace manual type checking with Zod schema validation in isResponseArgs helper
- Simplify error handling logic in catchResponseArgsErrorPipe operator
- Remove redundant conditional checks by leveraging Zod's safeParse
- Remove unused ResponseArgs import from operator file
This improves type safety and validation robustness by using a declarative schema-based approach.
Add critical sections to CLAUDE.md covering:
- Context preservation rules to prevent bloat
- Agent invocation patterns (sequential/parallel/escalation)
- Result handling and synthesis guidelines
- Edge case handling (failures, timeouts, conflicts)
- Model selection criteria (Haiku vs Sonnet)
- Resume vs fresh agent decision framework
- Result validation and confidence communication
- Debug mode and special scenarios
- Performance degradation handling
- Caching strategies and priority conflict resolution
feat(crm-customer-booking): add loyalty card booking component
Implement new component for customer loyalty card credit/debit bookings with booking type selection and real-time transaction updates. Includes automatic reload of transaction history after successful bookings.
Key changes:
- Add CrmFeatureCustomerBookingComponent with booking form UI
- Create CustomerCardBookingFacade for booking API calls
- Add CustomerBookingReasonsResource for loading booking types
- Extend CrmSearchService with booking methods (addBooking, fetchBookingReasons, fetchCurrentBookingPartnerStore)
- Add AddBookingSchema with Zod validation
- Integrate component into KundenkarteMainViewComponent
- Update CustomerCardTransactionsResource to providedIn: 'root' for shared access
- Improve transaction list UX (hide header/center empty state when no data)
Technical details:
- New library: @isa/crm/feature/customer-booking (Vitest-based)
- Signals-based state management with computed properties
- Automatic points calculation based on booking type multiplier
- Error handling with feedback dialogs
- 500ms delay before transaction reload to ensure API consistency
- Data attributes for E2E testing (data-what, data-which)
Ref: #5315
feature(crm, isa-app-customer-search): Adjustments to Card Transaction History, Added Scroll Top Button, Show 50 last Transactions, Wording changes
Refs: #5316
Commit 86563a73: ✨ feat(crm): add customer card transactions history feature
Implements #5316 - Service Portal History displaying last 5 loyalty card transactions
**New feature library:**
- Created @isa/crm/feature/customer-card-transactions with CDK table component
- Shows transactions for first activated customer loyalty card
- Displays: Date, Transaction type (reason), Amount (EUR), Receipt number, Points
**Data layer:**
- Added CustomerCardTransactionsResource with reactive resource pattern
- Extended CrmSearchService with fetchLoyaltyBookings() method
- Uses LoyaltyCardService.LoyaltyCardListBookings() API endpoint
**UI/UX:**
- CDK table with ISA design system colors
- Header: 48px height, rounded corners (26px), neutral-400 background
- Visual indicators: Green up arrow (EARN), Red down arrow (BURN)
- German locale formatting (dd.MM.yyyy HH:mm.ss)
- Full-width table layout with proper spacing (24px between rows)
- Empty state when no transactions available
**Icons:**
- Added isaActionPolygonUp and isaActionPolygonDown to @isa/icons
**Integration:**
- Integrated into kundenkarte-main-view component
- Automatically loads transactions for first active card
Related work items: #5316
fix(core-tabs): improve tab cleanup and naming logic
Refactor tab management to handle checkout state transitions more reliably:
- Extract helpers (formatCustomerTabNameHelper, checkCartHasItemsHelper,
getNextTabNameHelper) from checkout component to @isa/core/tabs for reuse
- Fix getNextTabNameHelper to count tabs instead of finding max ID,
preventing gaps in "Vorgang X" numbering
- Add canDeactivateTabCleanup guard to manage tab context based on cart state:
* Preserves customer context if either cart (regular or reward) has items
* Updates tab name with customer/organization name when context preserved
* Resets tab to clean "Vorgang X" state when both carts empty
* Handles navigation to global areas (without tab ID) gracefully
- Apply canDeactivateTabCleanup to checkout-summary and reward-order-confirmation routes
- Move tab cleanup logic from component ngOnDestroy to reusable guard
- Add comprehensive unit tests for getNextTabNameHelper
This ensures tabs maintain correct state after order completion, properly
display customer context when carts have items, and reset cleanly when
both carts are empty. The guard approach centralizes cleanup logic and
makes it reusable across checkout flows.
Ref: #5480
Replace window.location.href with Router.navigateByUrl() to ensure proper Angular navigation flow after authentication, maintaining state and avoiding full page reloads.
fix(core/tabs): Add logging and fix critical bugs in TabService
- Add comprehensive logging using @isa/core/logging for all TabService methods
- Fix null pointer in patchTab when tab doesn't exist
- Fix activateTab allowing non-existent tabs to be set as active
- Fix removeTab not clearing activatedTabId when removing active tab
- Replace unsafe 'as any' type casts with proper type checking
- Document side effect in getCurrentLocation method
Fixes#5474
Related work items: #5474
- Update nx-mcp command format in .mcp.json
- Add Nx configuration section to CLAUDE.md
- Create AGENTS.md with Nx guidelines
- Improve formatting in CLAUDE.md
feat(pickup-shelf): display Prämie label and Lesepunkte for reward items
- Add "Prämie" ui-label badge below product images in both list and details views
- Display Lesepunkte value instead of price for reward items
- Update getOrderItemRewardFeature helper to use structural typing for better type flexibility
- Apply to pickup-shelf-details-item and pickup-shelf-list-item components
Fixes#5467
feat(confirmation-list-item-action-card): improve action card visibility logic and add ordered state
Enhance the action card display logic to show only when both feature flag
and command/completion conditions are met. Add support for "Ordered" state
to distinguish pending items from completed ones.
Changes:
- Add hasLoyaltyCollectCommand helper to check for LOYALTY_COLLECT_COMMAND
- Update displayActionCard logic to require both Rücklage feature AND
(loyalty collect command OR completion state)
- Add ProcessingStatusState.Ordered to distinguish ordered vs completed items
- Update isComplete to exclude ordered items from completion state
- Move role-based visibility check to outer container level
- Remove unused CSS class for completed state
- Add comprehensive unit tests for new helpers
The action card now correctly appears only for items that need user action,
hiding for CallCenter role and for items without the required commands.
Ref: #5459
fix(customer-details): prioritize cart navigation over reward return URL
Fixes issue #5461 where navigating to cart after customer selection would
incorrectly route to reward shop page. Changed navigation priority to check
for regular shopping cart items before checking for reward return URL context.
This ensures that active standard checkout flows take precedence over any
lingering reward flow navigation context.
Related work items: #5461
feat(core/auth): add type-safe role-based authorization library
Created @isa/core/auth library with comprehensive role checking:
- RoleService for programmatic hasRole() checks
- IfRoleDirective for declarative *ifRole/*ifNotRole templates
- Type-safe Role enum (CallCenter, Store)
- TokenProvider abstraction with OAuth2 integration
- Signal-based reactive rendering with Angular effects
- Zero-configuration setup via InjectionToken factory
Fixed Bug #5451:
- Hide action buttons for HSC (CallCenter) users on reward order confirmation
- Applied *ifNotRole="Role.CallCenter" to actions container
- Actions now hidden while maintaining card visibility
Testing:
- 18/18 unit tests passing with Vitest
- JUnit and Cobertura reporting configured
- Complete test coverage for role checking logic
Documentation:
- Comprehensive README (817 lines) with API reference
- Usage examples and architecture diagrams
- Updated library-reference.md (62→63 libraries)
Technical:
- Handles both string and array JWT role formats
- Integrated with @isa/core/logging
- Standalone directive (no module imports)
- Full TypeScript type safety
Closes#5451
Related work items: #5451
fix(crm-data-access, customer-details, reward-shopping-cart): persist selected addresses across navigation flows
Implement address selection persistence using CRM tab metadata to ensure
selected shipping addresses and payers are retained throughout the customer
selection flow, particularly when navigating from Kundenkarte to reward cart.
Changes include:
- Create PayerResource and CustomerPayerAddressResource to load selected
payer from tab metadata with fallback to customer as payer
- Create PayerService to fetch payer data from CRM API with proper error
handling and abort signal support
- Update BillingAndShippingAddressCardComponent to prefer selected addresses
from metadata over customer defaults, with computed loading state
- Refactor continue() flow in CustomerDetailsViewMainComponent to load
selected addresses from metadata before setting in checkout service
- Add adapter logic to convert CRM payer/shipping address types to checkout
types with proper type casting for incompatible enum types
- Implement fallback chain: metadata selection → component state → customer
default for both payer and shipping address
This ensures address selections made in the address selection dialogs are
properly preserved and applied when completing the customer selection flow,
fixing the issue where addresses would revert to customer defaults.
Ref: #5411
fix(open-reward-tasks): filter out pickup-only reward orders
Exclude reward orders with only pickup items (supplier_id: '16') from open tasks
as these cannot be completed in the reward shop.
Fixes BUG-5444
🐛 fix(order-destination): display 'Hugendubel Digital' for download destinations
Fixes#5453
- Add handling for Download order type in name() computed signal to return 'Hugendubel Digital'
- Add handling for Download order type in address() computed signal to return undefined
- Update template to conditionally show pipe separator and address only when address exists
- Add isaDeliveryDownload icon for download order type
- Remove unused OrderType import
Related work items: #5453
fix(purchase-options): resolve Lesepunkte delivery method change error
The commit includes:
- Restored ensureCurrencyDefaults import that was accidentally removed
- Fixed immutability violations in both getAddToShoppingCartDTOForItem and getUpdateShoppingCartItemDTOForItem methods
- Proper handling of frozen NgRx ComponentStore state objects
- Resolves bug #5452 where Lesepunkte delivery method changes failed
The pre-commit hooks ran successfully (ESLint passed with no changes needed). The fix is now ready to be pushed and tested.
Related work items: #5452
🐛 fix(checkout): include download orders in destination update flow
Fixes#5448 - Prämienshop download orders now properly update destination
logistician before order creation. Previously, download orders were excluded
from the destination update step, causing null logistician errors during
order creation in the reward shop.
The fix adds hasDownload to the condition that determines whether to update
destination shipping addresses, ensuring download items (including those
purchased with loyalty points) get their logistician properly assigned.
Related work items: #5448
fix(reward-shopping-cart-item, filter-service): exclude downloads and text inputs from counts
Hide low stock warning for download items in reward shopping cart, as
downloads don't have physical inventory constraints.
Exclude text/searchbox inputs from selected filter count calculation
to prevent search queries from inflating the filter badge counter.
Remove unused isIconButtonActive computed property in filter menu button.
Ref: #5441
fix(reward-print, reward-popup, reward-destination): improve reward cart stability and UX
- fix: remove console.log statement from calculate-price-value helper
- fix: add loading/pending state to print button to prevent duplicate prints
- fix: debounce reward selection resource reloading to prevent race conditions
- fix: correct reward cart item destination-info alignment and flex behavior
- fix: support OrderType in OrderDestinationComponent alongside OrderTypeFeature
- fix: use unitPrice instead of total for price calculations in reward items
- refactor: update calculatePriceValue test descriptions for clarity
- fix: fallback to order.orderType when features don't contain orderType
The reward selection popup now properly waits for all resources to reload
before resolving, preventing timing issues with cart synchronization.
Print button shows pending state during print operations.
Destination info components now handle both legacy OrderType and new
OrderTypeFeature enums for better compatibility.
Ref: #5442, #5445
- Regenerated all Swagger API clients (availability, checkout, crm, isa, print, wws)
- Updated CRM loyalty card API endpoints (removed interests, added booking/bon management)
- Temporarily disabled interests form block functionality due to API changes
- Removed deprecated models (check-loyalty-card-result, loyalty-card-status, entity-key-value)
- Added new loyalty booking and bon management models and services