Compare commits

...

328 Commits

Author SHA1 Message Date
Lorenz Hilpert
aff6d18888 feat: enhance filter input mappings with detailed documentation and schema validation
- Added comprehensive JSDoc comments to mapping functions for checkbox and text filter inputs, improving code readability and maintainability.
- Refactored checkboxFilterInputMapping and checkboxOptionMapping functions to enhance clarity and structure.
- Removed unused data-range-filter-input mapping files and tests to streamline the codebase.
- Introduced a new dateRangeFilterInputMapping function with detailed mapping logic for date range inputs.
- Updated filter input schemas to include descriptive comments for better understanding of properties.
- Implemented unit tests for date range filter input mapping to ensure correct functionality.
- Enhanced existing filter mapping functions with improved error handling and validation.
- Updated index exports to reflect the removal and addition of mapping files.
2025-04-11 16:13:11 +02:00
Lorenz Hilpert
8144253a18 Refactor return search component and remove unused dropdown.
- 🛠️ **Refactor**: Updated return search result component for mobile responsiveness
- 🗑️ **Chore**: Removed unused order-by dropdown component and related files
- 📚 **Docs**: Enhanced component documentation for clarity
2025-04-11 15:24:08 +02:00
Lorenz Hilpert
3e14426d2e feat: Implement filter input mapping and related schemas
- Added filter input mapping functionality to handle different input types (Text, Checkbox, DateRange).
- Created schemas for various filter inputs including BaseFilterInput, CheckboxFilterInput, DateRangeFilterInput, and TextFilterInput.
- Developed filter mapping logic to aggregate filter groups, inputs, and order by options.
- Implemented unit tests for filter mapping, input mapping, and order by option mapping to ensure correctness.
- Introduced a dropdown component for selecting order by options with appropriate styling and functionality.
2025-04-10 19:24:45 +02:00
Lorenz Hilpert
b4caf3a177 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-04-09 12:43:06 +02:00
Lorenz Hilpert
ae3662dfd1 Refactor pre-commit and add pre-push hooks for CI checks.
- 🛠️ **Refactor**: Removed CI check from pre-commit hook
-  **Feature**: Added pre-push hook to enforce CI checks
2025-04-09 12:42:04 +02:00
Lorenz Hilpert
291386e4fd Merge tag '5022-Bezahlte-undunbezahlte-Ware-auf-der-seben-AHF-nummer' into develop
Hotfix 5022 - AHF Buchungh von Bezalten und nicht Bezahlten artikeln auf unterschiedliche Abholfächer 5022-Bezahlte-undunbezahlte-Ware-auf-der-seben-AHF-nummer
2025-04-09 12:36:28 +02:00
Lorenz Hilpert
6a7d509aa4 Merge branch 'hotfix/5022-Bezahlte-undunbezahlte-Ware-auf-der-seben-AHF-nummer' 2025-04-09 12:34:59 +02:00
Lorenz Hilpert
620ffae55c Merged PR 1829: Kundendaten // B2B - nach "Bearbeiten" speichern nicht möglich
bugfix: Show error when control has error

Rename validator requiredIfControlIsSet to requireGenderWhenNameIsSet
Update logic for requireGenderWhenNameIsSet
Added JSDoc for Documentation
UiFormControlComponent Subscribing to ngControl.statusChanges and ngControl.valueChanges independendly and call cdr.markForCheck when emitted

Related work items: #4996
2025-04-09 07:30:44 +00:00
Lorenz Hilpert
59ad7710d9 Refactor selectLatestCompartmentCodeAndInfoForOrder to enforce booking rules for paid and unpaid items 2025-04-08 18:21:47 +02:00
Lorenz Hilpert
8ca7977f7c Enhanced return details and search components with new features and improvements.
-  **Feature**: Added InViewport directive for element visibility detection
-  **Feature**: Introduced new button for navigation in return details
- 🛠️ **Refactor**: Improved scroll position restoration logic and removed deprecated files
- 📚 **Docs**: Updated README with usage instructions for new directives

Ref: #5034
2025-04-08 10:51:24 +02:00
Lorenz Hilpert
62d0783e88 Enhance return search store with new methods and hooks for entity management.
-  **Feature**: Added method to remove entities by process ID
-  **Feature**: Implemented onInit hook to clear entities based on process IDs
- 🛠️ **Refactor**: Updated imports for clarity and organization
- 🛠️ **Refactor**: Improved entity management logic in return search store
2025-04-07 19:34:18 +02:00
Lorenz Hilpert
bd1e4f36e1 Enhanced search functionality in ReturnSearch components.
-  **Feature**: Added 'clear' parameter to search method in store
- 🛠️ **Refactor**: Updated search calls in ReturnSearchMain and Result components
- 🎨 **Style**: Improved conditional rendering for apply button in filter actions
2025-04-07 19:20:05 +02:00
Lorenz Hilpert
79356fa130 Refactored import statements for scroll position restoration utility.
- 🛠️ **Refactor**: Removed unused DOCUMENT import from scroll position restoration
2025-04-07 18:53:36 +02:00
Lorenz Hilpert
c1a40ae82f Refactored scroll position restoration logic for improved clarity.
- 🛠️ **Refactor**: Simplified storeScrollPosition function and event handling
- 🛠️ **Refactor**: Removed redundant code for scroll position storage
2025-04-07 18:53:12 +02:00
Lorenz Hilpert
492dae14f7 feat: add pagination support to query token schema with skip and take fields
feat: enhance return search component to handle search callbacks and update query parameters

fix: update return search result component template to use new search method and improve loading states

refactor: streamline return search result component logic and improve state management

feat: implement scroll position restoration in return search feature

feat: introduce filter service enhancements for query settings and synchronization with URL parameters

chore: create utils for scroll position management and viewport detection

fix: update filter service to use new input and query settings types

chore: add tests and configurations for new utils library

ref: #5033
2025-04-07 18:23:43 +02:00
Lorenz Hilpert
9950c76482 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-04-04 21:29:23 +02:00
Lorenz Hilpert
7e7a5ebab9 Introduced responsive layout utilities and directives for Angular.
-  **Feature**: Added breakpoint utility for responsive design
-  **Feature**: Implemented BreakpointDirective for conditional rendering
- 🛠️ **Refactor**: Updated styles for filter and order-by components
- 📚 **Docs**: Created README and documentation for ui-layout library
- ⚙️ **Config**: Added TypeScript and ESLint configurations for the new library
2025-04-04 18:00:49 +02:00
Nino
41fc8e0fb1 Refactored return components for improved performance and maintainability.
- 🛠️ **Refactor**: Streamlined return feature components
- 🗑️ **Chore**: Removed unused files related to return functionality
2025-04-04 14:02:05 +02:00
Lorenz Hilpert
41067a7e54 Added new icons to the product format icon group for additional formats.
-  **Feature**: Included icons for CD, other formats, and games
2025-04-04 11:12:08 +02:00
Lorenz Hilpert
e1a50b0ce0 Refactored filter service and updated query parameter handling.
- 🛠️ **Refactor**: Renamed methods for clarity in filter service
- 🛠️ **Refactor**: Updated query parameter usage in return search components
2025-04-04 10:41:04 +02:00
Lorenz Hilpert
227af192e6 Updated styles for return details component to improve layout.
- 🎨 **Style**: Added margin-top to enhance spacing in the component
2025-04-04 10:30:16 +02:00
Lorenz Hilpert
bd21b674bf Refactored return search components and updated query handling.
- 🛠️ **Refactor**: Changed filter service method calls to use new query methods
- 🎨 **Style**: Updated button components for consistency
- 🧪 **Test**: Adjusted tests to reflect changes in query parameters
- ⚙️ **Config**: Modified pre-commit hook to run CI checks
2025-04-03 21:21:30 +02:00
Lorenz Hilpert
b21395ed61 Refactored return feature components and removed unused files.
- 🛠️ **Refactor**: Cleaned up return feature components and styles
- 🗑️ **Chore**: Deleted obsolete files and updated exports
- 📚 **Docs**: Added README for return details library
2025-04-03 18:45:33 +02:00
Lorenz Hilpert
da27745ebe Implemented return search feature with main and result components.
-  **Feature**: Added return search main and result components
- 🎨 **Style**: Updated styles for return search components
- 🛠️ **Refactor**: Modified routing for return search functionality
- 📚 **Docs**: Updated documentation references in settings
2025-04-03 17:29:42 +02:00
Lorenz Hilpert
8a94da6868 Added return search feature with main and result components.
-  **Feature**: Implemented return search main and result components
- 📚 **Docs**: Created README for return search library
- ⚙️ **Config**: Added TypeScript and Jest configuration for return search
- 🛠️ **Refactor**: Updated filter menu components with scroll strategy
2025-04-03 17:29:05 +02:00
Lorenz Hilpert
81a7154470 Added new models and schemas for gender, address type, and shipping type.
-  **Feature**: Introduced Gender, AddressType, and ShippingType enums
- 🗑️ **Chore**: Removed obsolete schemas and service files from return feature
- 🛠️ **Refactor**: Updated index files to export new models
2025-04-03 11:53:27 +02:00
Lorenz Hilpert
0dee30062f Refactor menu components and styles for improved organization.
- 🛠️ **Refactor**: Removed old menu-button component and styles
-  **Feature**: Added new input-menu and filter-menu components
- 🎨 **Style**: Updated styles for input-menu and filter-menu components
- 🗑️ **Chore**: Cleaned up unused input-button component files
2025-04-02 21:06:11 +02:00
Lorenz Hilpert
eb0a0d3dc3 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-04-02 15:17:14 +02:00
Lorenz Hilpert
67dcb49a1d Enhance UI components with new input control directive and styling.
-  **Feature**: Added InputControlDirective for better input handling
- 🎨 **Style**: Updated button and text-field styles for loading states
- 🛠️ **Refactor**: Improved button component structure and disabled state handling
- 📚 **Docs**: Updated code style guidelines with new control flow syntax
2025-04-02 15:16:35 +02:00
Lorenz Hilpert
f3e2e9fee3 Merged PR 1827: Kundendaten // B2B - nach "Bearbeiten" speichern nicht möglich
Related work items: #4996
2025-04-02 10:02:13 +00:00
Lorenz Hilpert
a4b092a021 Enhance return details service with error handling and tests.
-  **Feature**: Improved error handling in fetchReturnDetails method
- 🧪 **Test**: Added unit tests for ReturnDetailsService
2025-04-02 11:49:04 +02:00
Lorenz Hilpert
aeacd0077f Revert "Update Angular and Nx dependencies to latest versions."
This reverts commit b508abefaf.
2025-04-02 11:45:56 +02:00
Lorenz Hilpert
78a0e828b8 Revert "Enhance return details service with error handling and tests."
This reverts commit df49e3a79b.
2025-04-02 11:38:51 +02:00
Lorenz Hilpert
b508abefaf Update Angular and Nx dependencies to latest versions.
- 🗑️ **Chore**: Updated Angular dependencies to version 19.2.x
- 🗑️ **Chore**: Updated Nx dependencies to version 20.7.0
- 🗑️ **Chore**: Updated devDependencies including Jest and ESLint
2025-04-02 11:32:35 +02:00
Lorenz Hilpert
df49e3a79b Enhance return details service with error handling and tests.
-  **Feature**: Improved error handling in fetchReturnDetails method
- 🧪 **Test**: Added unit tests for ReturnDetailsService
2025-04-02 11:19:58 +02:00
Lorenz Hilpert
34512f3b9a Set up Jest configuration and update dependencies for testing.
- ⚙️ **Config**: Added Jest configuration files for testing
- 🗑️ **Chore**: Removed unused Karma configuration and assets
- 🛠️ **Refactor**: Updated return details store methods for better clarity
- 📚 **Docs**: Enhanced comments and documentation in return details store
2025-04-02 11:09:25 +02:00
Lorenz Hilpert
093bb3b484 Update commit message structure in guidelines
- 📚 **Docs**: Revised commit message instructions for clarity
2025-04-01 17:29:38 +02:00
Lorenz Hilpert
921edf8066 #5022 Hotfix selectors in pickup-shelf-details to improve readability and consistency 2025-04-01 16:17:15 +02:00
Lorenz Hilpert
858242c6dd Enhance searchbox functionality
Improved the searchbox components to utilize environment service for mobile detection.

-  **Feature**: Integrated EnvironmentService for mobile device detection
- 🛠️ **Refactor**: Cleaned up provider definitions for better readability
- 🎨 **Style**: Reformatted code for consistency in style

#5001
2025-04-01 14:42:57 +02:00
Lorenz Hilpert
119bcd9df9 Update routing to redirect to dashboard
Configured the routing to redirect the root path to the dashboard.

-  **Feature**: Added redirect from root path to 'kunde/dashboard'
2025-04-01 14:27:34 +02:00
Lorenz Hilpert
b43d0fcea6 Update routing and side menu interactions
Refactored routing structure and improved side menu functionality.

- 🛠️ **Refactor**: Simplified route definitions for process handling
- 🎨 **Style**: Cleaned up side menu HTML for better readability
- 🛠️ **Refactor**: Enhanced side menu item click handling

#5021
2025-04-01 14:12:09 +02:00
Lorenz Hilpert
ddad3ad967 Add return process answer model and validators
Introduced a new model for return process answers and corresponding validation tests.

-  **Feature**: Created ReturnProcessAnswers type for handling answers
-  **Feature**: Added validation functions for various return scenarios
- 🧪 **Test**: Implemented comprehensive tests for return process validations
2025-04-01 13:59:28 +02:00
Lorenz Hilpert
aaa161424e Enhance error handling and storage utilities
Improved error handling and updated storage utilities for better performance.

-  **Feature**: Added custom error classes for return process errors
- 🛠️ **Refactor**: Updated hash function to handle strings and objects
- 🛠️ **Refactor**: Enhanced storage key generation with user context
- ⚙️ **Config**: Updated VSCode settings and package dependencies
2025-04-01 12:01:16 +02:00
Lorenz Hilpert
3bbec6a68d 📚 Update review instructions for positive feedback
Clarified guidelines for highlighting positive aspects of code reviews.

- 📚 **Docs**: Specify using different funny emojis for good practices
- 🛠️ **Refactor**: Removed redundant good practice example
2025-03-31 17:57:50 +02:00
Lorenz Hilpert
2a8a929fd7 📚 Update code review instructions for clarity
Enhanced the code review guidelines to improve clarity and effectiveness.

- 📚 **Docs**: Expanded review process steps with detailed explanations
- 📚 **Docs**: Added a review template for structured feedback
- 📚 **Docs**: Clarified the use of emojis for categorizing feedback
2025-03-31 17:28:52 +02:00
Lorenz Hilpert
3bcdfccb5c 📚 Update review instructions and code style documentation
Enhanced code review guidelines and clarified code style documentation.

- 📚 **Docs**: Added emphasis on adherence to review guidelines
- 📚 **Docs**: Clarified documentation requirements in code style
- 🛠️ **Refactor**: Updated import paths in input controls styles
- 📚 **Docs**: Expanded tech stack documentation with new libraries
2025-03-31 16:12:48 +02:00
Lorenz Hilpert
9696084f7b Add dropdown component and styles
Introduced a new dropdown component with associated styles and fixed a typo.

-  **Feature**: Added dropdown component and its styles
- 🎨 **Style**: Updated styles for dropdown button and options
- 🐛 **Fix**: Corrected typo in dropdown options class name
2025-03-31 13:38:43 +02:00
Lorenz Hilpert
417bd649e2 Refactor chip option component and styles
Updated the chip option component and its styles for improved functionality and organization.

-  **Feature**: Introduced new chip option styles and layout
- 🛠️ **Refactor**: Removed outdated styles and organized SCSS files
- 🧪 **Test**: Added unit tests for chip option component functionality
2025-03-31 13:28:32 +02:00
Lorenz Hilpert
d38fed297d Add input controls and checkbox component
Introduced a new input controls library with a checkbox component.

-  **Feature**: Added input controls library with checkbox component
- 🎨 **Style**: Updated checkbox component styles and structure
- 🧪 **Test**: Added unit tests for checkbox and empty state components
- 🛠️ **Refactor**: Improved checkbox component code and removed unused styles
- 📚 **Docs**: Updated commit message guidelines in VSCode settings
2025-03-31 12:29:22 +02:00
Lorenz Hilpert
3c110efdfa 📚 Add state management and testing guidelines documentation
Introduced new documentation files for state management and testing guidelines to enhance developer understanding and best practices.

- 📚 **Docs**: Added state management guidelines with local and global state recommendations
- 📚 **Docs**: Created testing guidelines including unit testing requirements and best practices
- 📚 **Docs**: Updated project structure documentation for clarity
2025-03-31 11:52:17 +02:00
Lorenz Hilpert
1cbabd2d7a feat: enhance return process feature with improved layout and EAN validation 2025-03-28 20:35:24 +01:00
Lorenz Hilpert
133020ece1 chore: simplify copilot instructions by removing outdated performance and common patterns sections 2025-03-28 20:16:15 +01:00
Lorenz Hilpert
549d419b69 docs: update TypeScript and Angular guidelines for improved best practices and error handling 2025-03-28 20:03:29 +01:00
Lorenz Hilpert
8bbaf1c70c feat: update button component with spinner support and improve test coverage 2025-03-28 18:08:17 +01:00
Lorenz Hilpert
d0b7c95be2 chore: update copilot instructions to reflect current tech stack 2025-03-28 16:56:40 +01:00
Lorenz Hilpert
b0dba2325d feat: add unit tests for ButtonComponent using Spectator and Jest 2025-03-28 14:20:22 +01:00
Lorenz Hilpert
a9c606ec21 feat: improve return process component error handling and enhance typing 2025-03-28 13:49:58 +01:00
Lorenz Hilpert
81bec4b153 refactor: update import paths and adjust product category type handling 2025-03-27 17:02:25 +01:00
Lorenz Hilpert
0c2feb96ac feat: enhance return process with product category selection and update dropdown functionality 2025-03-27 17:01:00 +01:00
Nino Righi
1855b1970d Merged PR 1826: #5009 #5013 Search Handling and Focus
#5009 #5013 Search Handling and Focus
2025-03-27 12:26:37 +00:00
Lorenz Hilpert
0a46258588 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-26 16:39:07 +01:00
Lorenz Hilpert
ca2e529bdf feat: introduce return process models and enhance return process item component 2025-03-26 16:38:41 +01:00
Nino Righi
82a2d70ce4 Merged PR 1825: #4982 #5003 #4989 Filter Handling + Checkbox UI + Checkbox Input Control
#4982 #5003 #4989 Filter Handling + Checkbox UI + Checkbox Input Control
2025-03-26 12:52:00 +00:00
Lorenz Hilpert
fa39b6d071 fix: update eslint config to correctly ignore generated directories 2025-03-25 17:12:05 +01:00
Lorenz Hilpert
0f3f456909 fix: add missing newlines and improve formatting in various DTO models 2025-03-25 17:11:21 +01:00
Lorenz Hilpert
727e0469ad feat: add cyclic dependency detection in return process service and improve layout in return process item component 2025-03-24 18:27:15 +01:00
Lorenz Hilpert
7e3d6b4e61 feat: enhance progress bar styles with nested transition for improved animation 2025-03-24 16:16:31 +01:00
Lorenz Hilpert
453403cfde feat: add progress tracking for return process questions and update UI to display progress 2025-03-24 16:13:20 +01:00
Lorenz Hilpert
9001850c1f feat: add progress bar component with styles and integration into the application 2025-03-24 15:26:14 +01:00
Lorenz Hilpert
b97ad4f24b feat: refactor return process models and update button styles for improved UI consistency 2025-03-24 14:20:57 +01:00
Lorenz Hilpert
452de44f34 feat: implement user storage provider with clear functionality and update root state service for local storage integration 2025-03-21 11:00:24 +01:00
Lorenz Hilpert
db7da0699e feat: add data access and feature libraries for return process, including models, schemas, and routes 2025-03-20 21:25:20 +01:00
Lorenz Hilpert
fbd5414e47 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-18 17:11:08 +01:00
Lorenz Hilpert
5310619211 feat: add dropdown component with appearance options and styles 2025-03-18 17:10:49 +01:00
Nino
edbdba6868 Searchbar Update + Storybook Update 2025-03-17 17:07:31 +01:00
Nino
2d5fce8554 Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-03-14 17:51:35 +01:00
Nino
f5b7da5bd2 Checkbox Init Implementation, Small Improvements 2025-03-14 17:51:07 +01:00
Lorenz Hilpert
d4c1cdbc6e feat: add appearance control to checkbox component stories 2025-03-14 16:14:03 +01:00
Lorenz Hilpert
576d439a79 feat: update button styles to enhance icon visibility in disabled state 2025-03-14 16:00:45 +01:00
Lorenz Hilpert
00fc978c4f feat: enhance return details with checkbox selection and select all functionality 2025-03-14 15:50:33 +01:00
Lorenz Hilpert
44e596327e Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-14 14:22:43 +01:00
Lorenz Hilpert
3d95bddb23 feat: enhance return details UI with improved styling and conditional rendering 2025-03-14 14:22:13 +01:00
Nino
2210aeb1c2 Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-03-14 12:23:21 +01:00
Nino
a2b6847898 Removed Console.logs, Fixed Browser Back Button -> Navigation for Search Results now in Parent Component, Wording Fix 2025-03-14 12:22:53 +01:00
Lorenz Hilpert
3f252639d5 feat: implement gender schema and enhance receipt-related schemas; add dynamic order group data component 2025-03-14 12:00:23 +01:00
Lorenz Hilpert
3f7df0f748 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-13 21:24:00 +01:00
Lorenz Hilpert
703090eabd feat: add core storage and scroll position libraries with initial implementations and configurations 2025-03-13 21:22:43 +01:00
Nino
33694357bd Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-03-13 18:16:48 +01:00
Nino
91668e53fa OrderBy Toolbar mobile, ScrollPos Update, Schema Update 2025-03-13 18:15:36 +01:00
Lorenz Hilpert
39e4efff2b feat: enhance return details component with dynamic pricing and improved layout; add new price and VAT schemas 2025-03-13 16:01:36 +01:00
Lorenz Hilpert
1a4d0a38da Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-12 22:20:28 +01:00
Lorenz Hilpert
6c4641d2b7 feat: update entity container schema to allow optional fields; enhance return details component with dynamic product data and improved layout 2025-03-12 22:19:56 +01:00
Nino
815523b4ca Adjustments Dania 2025-03-12 17:54:16 +01:00
Lorenz Hilpert
57b5f30a66 refactor: rename entityContainerSchema to EntityContainer and update usage in receipt schema; change checkbox selector for consistency 2025-03-12 16:47:09 +01:00
Lorenz Hilpert
94919efd83 feat: refactor checkbox component to support bullet appearance; update styles and selector 2025-03-12 16:34:21 +01:00
Lorenz Hilpert
cd0d740dc2 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-12 16:18:37 +01:00
Lorenz Hilpert
dc3970ceea style: update gap in client row component for improved layout 2025-03-12 16:16:00 +01:00
Lorenz Hilpert
5bba1dff8f feat: add schemas and utility functions for return processing; update styles and component structure 2025-03-12 16:13:47 +01:00
Nino
7ff6e9495e QueryToken Schemas + Store Update, Ipad Stylings Layout, Bugfix mergeQueryParams, Bugfix List should not Reload if Hits Reached 2025-03-12 15:24:05 +01:00
Michael Auer
04403179d7 ~ nginx.conf: added "/browser" to try_files 2025-03-11 18:22:39 +01:00
Michael Auer
a39706bff3 Merge tag 'traefik-ingressroute-with-path' into develop 2025-03-11 18:06:01 +01:00
Michael Auer
0ac34740bb Merge branch 'hotfix/traefik-ingressroute-with-path' 2025-03-11 18:05:31 +01:00
Nino
24c2c1c77d Order By Styling Update, Search Bar Clear Added 2025-03-11 17:49:39 +01:00
Nino
a364a4f0e0 Result List Empty State - Initial Loader - Pending Loader 2025-03-11 17:06:19 +01:00
Nino
dcc70745da Scroll Pos Handling Update 2025-03-11 16:28:17 +01:00
Nino
effce6f41c Improvements to Search Request Handling - F5 Refresh Page Init Search Fixed 2025-03-11 16:08:24 +01:00
Nino
a5feaba5e3 #4977 Search / Results Update - Scrollpos - Reload fix 2025-03-11 15:10:59 +01:00
Nino
d8bb42b8c6 Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-03-10 18:50:56 +01:00
Nino
f74494f34e Paging/Reload, Searchbar and Icon Update 2025-03-10 18:49:10 +01:00
Lorenz Hilpert
abce5f43e2 feat: add ProductImage directive and service; implement storybook for product image component 2025-03-10 17:10:11 +01:00
Lorenz Hilpert
ce4a6b36b6 feat: add Checkbox component with styling and stories; update process resolver to include tags 2025-03-10 15:23:37 +01:00
Lorenz Hilpert
298ea042f2 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-10 13:51:26 +01:00
Lorenz Hilpert
573d6a740e feat: add InfoButton component with styling and functionality; update process schemas to include tags 2025-03-10 13:50:53 +01:00
Lorenz Hilpert
8eb5e09490 feat: enhance canActivate guard to use zod for process ID validation 2025-03-10 10:57:54 +01:00
Nino
aa8869ceb1 Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-03-07 18:09:29 +01:00
Nino
e5f42c9de2 Header 2025-03-07 18:09:02 +01:00
Lorenz Hilpert
532c7e5e86 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-07 16:42:39 +01:00
Lorenz Hilpert
30ccd93967 feat: add core-scanner library with initial implementation and configuration 2025-03-07 16:42:23 +01:00
Nino
b85538f98a Quick Fix Schema to Array 2025-03-07 16:36:11 +01:00
Nino
d9dede4341 Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-03-07 16:32:38 +01:00
Nino
4a3c934fe0 Utils Lib angelegt, safeParse Funktion ausgelagert und eingebunden in return service 2025-03-07 16:31:47 +01:00
Nino
944fb8a186 Code improvements, Details Page + Routing 2025-03-07 16:07:24 +01:00
Lorenz Hilpert
73fd487a13 feat: add ui-toolbar component and update button components 2025-03-07 15:51:17 +01:00
Lorenz Hilpert
592027f648 feat: implement new feature for enhanced user navigation 2025-03-07 10:53:08 +01:00
Lorenz Hilpert
84243ac4e6 feat: add EmptyState component with styles and stories 2025-03-06 20:24:06 +01:00
Nino
04b9422d5d #4977 Result Page 2025-03-06 18:25:30 +01:00
Nino
584cb63eaf Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-03-06 17:39:28 +01:00
Nino
b9871bba54 #4977 Handling Search Results + Navigation 2025-03-06 17:38:37 +01:00
Lorenz Hilpert
6769e3864e Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-06 17:24:30 +01:00
Lorenz Hilpert
cebb644da9 feat: implement ClientRow and ItemRowData components with associated styles and stories 2025-03-06 17:23:51 +01:00
Nino
734a7b8739 #4994 Receipt Schema erweitert 2025-03-06 11:07:03 +01:00
Lorenz Hilpert
e89d1999a6 feat: add ui-item-rows library with initial component and configuration 2025-03-05 19:51:09 +01:00
Lorenz Hilpert
b7cbd50e83 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-05 19:47:45 +01:00
Lorenz Hilpert
76aa04bc4c feat: add core-config and shared-product-image libraries; implement initial structure and configuration 2025-03-05 19:47:27 +01:00
Nino
b951cf7024 #4994 Store Anbindung in die Komponente 2025-03-05 18:25:01 +01:00
Nino
f896d91ebb Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-03-05 18:04:48 +01:00
Nino
a884adc3a9 #4994 Process Handling + Schema Update 2025-03-05 18:04:15 +01:00
Lorenz Hilpert
ce9bc9511a feat: remove deprecated shared return library; clean up related files and configurations 2025-03-05 15:55:10 +01:00
Lorenz Hilpert
2653322232 feat: enhance filter functionality; update search handling and state management in filter service 2025-03-05 15:46:12 +01:00
Lorenz Hilpert
86eb0bb494 feat: refactor return feature components; remove deprecated files and implement new search bar input 2025-03-05 12:08:48 +01:00
Lorenz Hilpert
73be50e7d2 feat: implement new text field and button components; remove deprecated search bar and input controls 2025-03-03 21:02:21 +01:00
Lorenz Hilpert
da5151df78 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-03-03 14:22:56 +01:00
Lorenz Hilpert
df47b932b6 Upgrade isa-app project 2025-03-03 13:28:03 +01:00
Nino
c096609a27 Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-02-28 17:55:05 +01:00
Nino
6b07b322f4 ISA Typography Update 2025-02-28 17:54:40 +01:00
Lorenz Hilpert
1b821db248 refactor: replace UiButtonsComponent with standalone button component and remove deprecated files 2025-02-28 17:18:21 +01:00
Lorenz Hilpert
ecf446671c refactor: reorganize process module structure and remove deprecated files 2025-02-28 16:24:44 +01:00
Lorenz Hilpert
a2f204d0d6 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-02-28 16:23:20 +01:00
Lorenz Hilpert
c8678b7e91 feat: enhance process management with injector functions and service updates 2025-02-28 16:20:34 +01:00
Nino
ec41738def Merge branch 'develop' of https://dev.azure.com/hugendubel/ISA/_git/ISA-Frontend into develop 2025-02-28 16:15:53 +01:00
Nino
53a7f01507 Icons Update 2025-02-28 16:13:38 +01:00
Lorenz Hilpert
7366f038e5 feat: create core process library with initial setup and routing configuration 2025-02-28 16:02:44 +01:00
Lorenz Hilpert
1c9cd2a0b0 feat: add UI component libraries for buttons, input controls, and search bar 2025-02-28 14:28:24 +01:00
Michael Auer
591824196b Cherry-Pick: PR 1824: ISA-Frontend - Expliziter Pfad für Traefik IngressRoute
(cherry picked from commit c9b2762bbc)
2025-02-28 11:15:20 +01:00
Lorenz Hilpert
09aa3f09cb Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2025-02-27 17:10:58 +01:00
Lorenz Hilpert
eff67b9a06 feat: create icons library with initial configuration and setup 2025-02-27 17:10:19 +01:00
Michael Auer
c9b2762bbc Merged PR 1824: ISA-Frontend - Expliziter Pfad für Traefik IngressRoute
Früher wurde die IngressRoute für die ISA-UI mit dem Pfad "/" angelegt, jetzt mit "/isa-ui/v%MAJOR%"
2025-02-27 14:05:54 +00:00
Lorenz Hilpert
c49b0625c1 fix: update Tailwind CSS configuration for consistency and add new color shades 2025-02-26 18:14:38 +01:00
Lorenz Hilpert
42451e2144 chore: update ESLint and Prettier configurations, add eslint-plugin-prettier, and modify .prettierignore 2025-02-26 17:42:35 +01:00
Lorenz Hilpert
f52fb00df7 chore: update pre-commit hook, modify prettier ignore, and add Sheriff configuration 2025-02-26 17:02:42 +01:00
Lorenz Hilpert
b485bb768c feat: add feature return library components and Jest configuration 2025-02-24 15:43:16 +01:00
Lorenz Hilpert
3f77646f8a chore: prettier write 2025-02-24 15:29:32 +01:00
Lorenz Hilpert
eb6149a6e3 Merge branch 'nx-workspace-migration' into develop 2025-02-24 15:26:32 +01:00
Lorenz Hilpert
5aa98bd90b Merge branch 'tracking' into nx-workspace-migration 2025-02-24 15:25:16 +01:00
Lorenz Hilpert
d71404f400 chore: remove unused assets and story files from isa-app 2025-02-24 14:40:56 +01:00
Lorenz Hilpert
f68eb33852 refactor: update memorize decorator to use 'any' type and remove migrations.json 2025-02-24 14:26:11 +01:00
Lorenz Hilpert
39d790c121 Angular Migrations to 19 2025-02-24 13:51:42 +01:00
Lorenz Hilpert
10349409fb bump nx and related packages to version 20.4.6 2025-02-24 13:41:42 +01:00
Lorenz Hilpert
0dc02abc8a Merge branch 'develop' into nx-workspace-migration 2025-02-24 13:37:39 +01:00
Lorenz Hilpert
388346e21b Merge tag '3.4' into develop
Finish Release 3.4 3.4
2025-02-10 10:41:31 +01:00
Lorenz Hilpert
1847c6944e Merge branch 'release/3.4' 2025-02-10 10:41:14 +01:00
Lorenz Hilpert
fd11cf19e4 Update imports to use generated Swagger API paths 2025-01-29 17:43:20 +01:00
Lorenz Hilpert
8e7b067310 Add new model types for Swagger APIs and remove obsolete models 2025-01-29 17:28:33 +01:00
Lorenz Hilpert
c6a174d93f Add new model definitions for various APIs in generated Swagger files 2025-01-29 17:16:58 +01:00
Lorenz Hilpert
9efbfab253 Update .gitignore and .prettierignore; add generated Swagger API libraries 2025-01-29 17:09:36 +01:00
Lorenz Hilpert
d474f555e3 Add caniuse-lite dependency to package.json 2025-01-29 15:39:39 +01:00
Lorenz Hilpert
c59a09c252 Migration Angular CLI to NX 2025-01-29 15:37:46 +01:00
Lorenz Hilpert
f743ce59fa #4922 Rename customer_name to customer_no in goods service and pickup shelf service
(cherry picked from commit ca998c0685)
2025-01-15 11:28:56 +01:00
Lorenz Hilpert
99feb499a2 Update Scandit licence key for staging environment 2025-01-02 13:41:02 +01:00
Lorenz Hilpert
6d28662431 Update Scandit licence key in configuration files 2025-01-02 13:38:26 +01:00
Lorenz Hilpert
27174e4ed3 Update Scandit licence key in configuration files 2025-01-02 13:26:54 +01:00
Nino
9b1b2c4682 Angular Service Worker insert Bypass in Req Header for Network Req 2024-12-20 16:28:35 +01:00
Lorenz Hilpert
674e2b7e1b Paket fuehrt zu fehler bei der installation
@rollup/rollup-linux-x64-gnu
2024-12-09 10:55:20 +01:00
Lorenz Hilpert
035abde3c3 Merge branch 'release/3.4' into develop 2024-12-06 10:45:48 +01:00
Lorenz Hilpert
ca998c0685 #4922 Rename customer_name to customer_no in goods service and pickup shelf service 2024-12-05 16:43:09 +01:00
Lorenz Hilpert
bb5b6e2e59 Update Scandit licence key for staging environment 2024-12-05 16:35:45 +01:00
Lorenz Hilpert
f57988f83e Update Scandit Licence Key for production 2024-12-05 15:38:24 +01:00
Lorenz Hilpert
17a68b9dbb Merged PR 1823: #4895 - Add download availability to article details component and update pri...
#4895 - Add download availability to article details component and update price mapping logic
2024-11-28 16:49:28 +00:00
Lorenz Hilpert
b6aab4f743 Add ID to assortment filter button in price update component 2024-11-28 17:13:20 +01:00
Nino Righi
a0c8035dbb Merged PR 1820: Fix - Close dropdown after selecting a reason in add product modal
Fix - Close dropdown after selecting a reason in add product modal
2024-11-27 14:21:12 +00:00
Nino Righi
34e96f0751 Merged PR 1821: Refactor getCachedData method to be asynchronous and improve cache handling
Refactor getCachedData method to be asynchronous and improve cache handling
2024-11-27 14:20:25 +00:00
Lorenz Hilpert
9ba05253e9 Enhance select component to register options on initialization and remove debug log 2024-11-27 11:52:02 +01:00
Lorenz Hilpert
98a9346c1a Refactor customer number handling and add combined observable for customer number and selected order item changes 2024-11-27 11:43:49 +01:00
Lorenz Hilpert
fa66d2389a Improvements - Um Cover Items die nicht zur ausgeäjlten bestellung gehören zu filtern 2024-11-26 17:02:57 +01:00
Lorenz Hilpert
6743c8e630 Fix #4891 Kundendaten erfassen // Land bei Lieferung nicht auswählbar 2024-11-26 16:56:50 +01:00
Lorenz Hilpert
f62e198aed Fix - Nachbestellen - Dropdown wird nun nach der Auswahl geschlossen und Button Bestellen ist wieder klickbar 2024-11-26 16:34:32 +01:00
Nino
387e6b08ed Remove unused selectedCompartmentInfo properties from PickupShelfOutDetailsComponent 2024-11-25 17:31:49 +01:00
Lorenz Hilpert
721fd06c76 Remove console logs from beforeFetchCoverOrderItems and fetchCoverOrderItemsDone methods in PickupShelfDetailsStore 2024-11-25 16:51:43 +01:00
Lorenz Hilpert
0fcdb308b5 Remove Scandit overlay component and enhance error handling in ScanditScanAdapter; add logging for order item fetching in PickupShelfDetailsStore and list components 2024-11-25 16:50:15 +01:00
Lorenz Hilpert
5492329a21 Merge branch 'master' into release/3.4 2024-11-25 16:26:54 +01:00
Nino
f97253e82a Refactor distinctUntilChanged to use a custom equality check in pickup-shelf-details.store.ts 2024-11-25 15:31:24 +01:00
Nino
b926efb635 #4885 Compartment Info Bugfix 2024-11-25 15:23:36 +01:00
Lorenz Hilpert
1becbec412 Merge tag 'scandit-package-replacement' into develop
Scandit Lizenz und Package upgrade scandit-package-replacement
2024-11-25 14:04:57 +01:00
Lorenz Hilpert
cdc2553d73 Merge branch 'hotfix/scandit-package-replacement' 2024-11-25 13:56:08 +01:00
Lorenz Hilpert
8781c50e34 Merge branch 'master' into release/3.4 2024-11-25 13:50:34 +01:00
Lorenz Hilpert
05eb3cc756 Revert "Refactor ScanditOverlayComponent to use dependency injection for DataCaptureContext and DataCaptureView, and enhance module setup with async context initialization"
This reverts commit 6e1c434edf.
2024-11-22 18:31:05 +01:00
Lorenz Hilpert
6e1c434edf Refactor ScanditOverlayComponent to use dependency injection for DataCaptureContext and DataCaptureView, and enhance module setup with async context initialization 2024-11-22 18:23:05 +01:00
Lorenz Hilpert
ed8e937924 Update Scandit license keys across configuration files 2024-11-22 17:26:27 +01:00
Lorenz Hilpert
1bd17fd887 Update Scandit integration to use new SDK, adjust TypeScript configuration, and refine overlay component styles 2024-11-22 16:19:32 +01:00
Lorenz Hilpert
c35c82eaab Update Scandit license keys in configuration files 2024-11-21 14:16:58 +01:00
Lorenz Hilpert
258faec021 Refactor login strategy to conditionally trigger mobile device login 2024-11-19 16:55:00 +01:00
Lorenz Hilpert
4bcc523480 Update login strategy to always trigger mobile device login and prevent backdrop closing on modal 2024-11-19 16:31:55 +01:00
Lorenz Hilpert
8900a77d7a Enhance PickupShelfInDetailsComponent with signals for order items and optimize fetching logic 2024-11-19 16:27:18 +01:00
Lorenz Hilpert
895e2bd2ec Merge tag 'Abholfach-zubuchen-und-Coveransicht' into develop
Abholfach-zubuchen-und-Coveransicht Abholfach-zubuchen-und-Coveransicht
2024-11-19 13:54:23 +01:00
Lorenz Hilpert
4b10dd96d9 Merge branch 'hotfix/abholfach-zubuchen-und-cover-items' 2024-11-19 13:50:36 +01:00
Lorenz Hilpert
1126e4f0c1 Import tapResponse alongside ComponentStore in pickup-shelf-details.store.ts 2024-11-19 13:50:15 +01:00
Lorenz Hilpert
e9f24a88d6 Refactor PickupShelfInDetailsComponent to use signals for customer number and update fetch logic 2024-11-19 13:48:33 +01:00
Lorenz Hilpert
f30de35d51 Enhance authentication flow by improving error handling and validating ID tokens before login 2024-11-19 13:42:54 +01:00
Lorenz Hilpert
0c6f8abbad Fix login strategy condition to properly check for mobile devices 2024-11-18 13:49:32 +01:00
Lorenz Hilpert
54b37436eb Refactor authentication handling to utilize LoginStrategy and improve error management 2024-11-18 13:48:58 +01:00
Lorenz Hilpert
02bae79e4a Merged PR 1819: #4844 Implement dev-scanner configuration and enhance app initialization process
#4844 Implement dev-scanner configuration and enhance app initialization process
2024-11-13 17:09:34 +00:00
Lorenz Hilpert
cb6779fc83 Bump minor version from 3 to 4 in Azure Pipelines configuration 2024-11-12 17:14:19 +01:00
Lorenz Hilpert
f2c95b6a16 Merge tag '3.3' into develop
Merge branch release/3.3 3.3
2024-11-12 17:05:47 +01:00
Lorenz Hilpert
d48680c59e Merge branch 'release/3.3' 2024-11-12 17:04:15 +01:00
Lorenz Hilpert
775390b5df Add dynamic IDs to filter buttons in filter group component 2024-11-05 13:18:21 +01:00
Lorenz Hilpert
1788f566e3 Add filter buttons with unique IDs in package result component 2024-11-05 11:05:47 +01:00
Nino Righi
d4e1088190 Merged PR 1818: #4836 Small Bugfix
#4836 Small Bugfix
2024-10-31 17:07:26 +00:00
Lorenz Hilpert
a8ecd1f07b Merged PR 1817: Enhance error handling and state management in app module and root state service
Enhance error handling and state management in app module and root state service

Related work items: #4835
2024-10-30 12:14:58 +00:00
Lorenz Hilpert
2c239ac597 Merge branch 'develop' of ssh.dev.azure.com:v3/hugendubel/ISA/ISA-Frontend into develop 2024-10-30 11:47:07 +01:00
Lorenz Hilpert
200eb7f217 Mark NativeScanAdapter and native-container.service as deprecated 2024-10-30 11:46:14 +01:00
Nino Righi
694fc6d084 Merged PR 1816: #4836 Fix Printer Handling on Small Amount Invoice
#4836 Fix Printer Handling on Small Amount Invoice
2024-10-30 10:39:53 +00:00
Lorenz Hilpert
8ae990bcde Merged PR 1815: Angular Update V18
Related work items: #4830, #4834
2024-10-22 09:23:23 +00:00
Lorenz Hilpert
301f5878c2 Refactor button class in pickup-shelf-out-details.component.html 2024-10-18 13:44:58 +02:00
Lorenz Hilpert
39c8a512f4 Merged PR 1814: #4827 Warenausgabe // Bei Workflow Rücklagebestellung mit Business Konto klic...
#4827 Warenausgabe // Bei Workflow Rücklagebestellung mit Business Konto klick auf "abgehollt und Lieferschein drucken" wirft Fehlermeldung
2024-10-17 12:01:43 +00:00
Lorenz Hilpert
f37dfd41f1 Merged PR 1813: Strukturanpassung
Related work items: #4832
2024-10-16 14:07:57 +00:00
Lorenz Hilpert
a518fc50e2 Refactor observables in DomainCatalogService 2024-10-15 13:05:53 +02:00
Lorenz Hilpert
c9236f191b Merged PR 1812: #4825 Refactor publicationDate$ observable in ArticleDetailsComponent
#4825 Refactor publicationDate$ observable in ArticleDetailsComponent
2024-10-14 14:40:51 +00:00
Lorenz Hilpert
d1584d1edb Merged PR 1811: #3693 ISA Übergreifend // Suche Abbrechen
#3693 ISA Übergreifend // Suche Abbrechen

Related work items: #3693
2024-10-14 14:39:09 +00:00
Lorenz Hilpert
5f34b514ef Merged PR 1810: Changed the way observables restore the cache
Changed the way observables restore the cache

Related work items: #4824
2024-10-14 10:09:15 +00:00
Lorenz Hilpert
7a1ef06a4c Merged PR 1809: PDP-EVT-Datum-anpassen
Related work items: #4825
2024-10-11 08:14:12 +00:00
Lorenz Hilpert
acc2f7f664 Merged PR 1808: Bugfix Abruf Key aus IndexedDB
Bugfix Abruf Key aus IndexedDB

Related work items: #4824
2024-10-08 16:22:01 +00:00
Lorenz Hilpert
ad08e999a2 Merged PR 1807: #4825 Refactor article-details.component.ts to format and display the publica...
#4825 Refactor article-details.component.ts to format and display the publication date of an article

Related work items: #4825
2024-10-08 16:15:48 +00:00
Lorenz Hilpert
1d472ce3df (cherry picked from commit 4c027922283bc4113253310c9d47e7c8944427a3) 2024-10-07 19:04:31 +02:00
Lorenz Hilpert
92d760b8b4 Merged PR 1806: Sortiment // Preisänderung // Lange Titel hat mit anderen Text Überschneidung
Related work items: #4801
2024-10-07 15:33:02 +00:00
Nino Righi
1d19779dac Merged PR 1805: #4687 Hotfix Organisation Name Update Order
#4687 Hotfix Organisation Name Update Order
2024-10-07 14:33:04 +00:00
Nino Righi
294be5dcb4 Merged PR 1804: #2573 Fix Validator
#2573 Fix Validator
2024-10-07 14:30:31 +00:00
Nino
90e671d285 #4687 Changes to View, Added Organisation Input Field 2024-10-07 12:07:28 +02:00
Nino Righi
9a2c520ab4 Merged PR 1803: #4822 HSC Quick Fix #4687 HSC, WA, AHF Changes to View, Added Organisation Input Field
#4822 Quick Fix #4687 Changes to View, Added Organisation Input Field
2024-10-04 16:34:54 +00:00
Nino Righi
13d41a7a81 Merged PR 1802: #2573 Postal Code Validation only for Webshop, Webshop+Card and B2B | +Bugfix Determination of B2B Customer in Customer Edit Page
#2573 Postal Code Validation only for Webshop, Webshop+Card and B2B | +Bugfix Determination of B2B Customer in Customer Edit Page
2024-10-04 16:32:52 +00:00
Lorenz Hilpert
79b0a1324c #4816 User State // Local Storage und User State nach Vorgang schliessen prüfen 2024-10-02 11:32:56 +02:00
Lorenz Hilpert
0fd94273ce Merge branch 'indexeddb' into develop 2024-10-02 10:16:49 +02:00
Lorenz Hilpert
44abd4698e #4801 Sortiment // Preisänderung // Lange Titel hat mit anderen Text Überschneidung 2024-10-02 10:14:16 +02:00
Lorenz Hilpert
2b262cc8be #4821 PWA // Offline-Verhalten verbessern (Part 3) 2024-10-01 13:34:44 +02:00
Lorenz Hilpert
5775e444b8 Indexeddb Implementaion 2024-10-01 13:14:25 +02:00
Nino Righi
cdfe88c1cc Merged PR 1801: #4813 Fix Multiple EVT Items
#4813 Fix Multiple EVT Items
2024-09-26 15:53:17 +00:00
Nino Righi
c71d1f8886 Merged PR 1800: #4794 HSC List Update Fix after Action (SilentRefresh)
#4794 HSC List Update Fix after Action (SilentRefresh)
2024-09-26 15:39:40 +00:00
Nino Righi
a09eef038e Merged PR 1799: #2573 Bugfixing and Adjusted Error Message
#2573 Bugfixing and Adjusted Error Message
2024-09-26 15:08:05 +00:00
Nino Righi
f0a0189523 Merged PR 1797: #4813 #4710 Bugfix Preselection Purchase Options
#4813 #4710 Bugfix Preselection Purchase Options
2024-09-25 18:21:33 +00:00
Lorenz Hilpert
4d42c4ea45 Merged PR 1798: PDP // Preis von Hug.Dig anzeigt
PDP // Preis von Hug.Dig anzeigt

Related work items: #4812
2024-09-25 15:18:50 +00:00
Lorenz Hilpert
cad2926c45 Merged PR 1796: #4801 Sortiment // Preisänderung // Lange Titel hat mit anderen Text Überschn...
#4801 Sortiment // Preisänderung // Lange Titel hat mit anderen Text Überschneidung
2024-09-25 15:17:34 +00:00
Nino Righi
161d9c6fea Merged PR 1795: #4608 Customer Form Information Adjustments For Online and CustomerCard Users
#4608 Customer Form Information Adjustments For Online and CustomerCard Users
2024-09-25 11:07:46 +00:00
Nino Righi
1b33258728 Merged PR 1794: #2573 Added Zip Code Validator to Customer Page
#2573 Added Zip Code Validator to Customer Page
2024-09-24 18:00:15 +00:00
Nino Righi
73b6133306 Merged PR 1793: #4813 Show EVT Date if Item has Quantity and EVT exists and is After Todays Date
#4813 Show EVT Date if Item has Quantity and EVT exists and is After Todays Date
2024-09-24 17:56:49 +00:00
Nino Righi
eb6e93149e Merged PR 1792: #4610 Disable Option to Unselect Selected Customer Type
#4610 Disable Option to Unselect Selected Customer Type
2024-09-24 17:51:52 +00:00
Lorenz Hilpert
33fb44f20a Upgrade Version to 3.3 2024-09-24 16:51:36 +02:00
Lorenz Hilpert
8723f7aa7e Merge tag '3.2' into develop
Finish Release 3.2 3.2
2024-09-24 16:47:21 +02:00
Lorenz Hilpert
03815586f7 Merge branch 'release/3.2' 2024-09-24 16:47:03 +02:00
Nino Righi
86a11ff07a Merged PR 1791: #4715 Disable option for Staff to Add new Billing Adresses and only show the...
#4715 Disable option for Staff to Add new Billing Adresses and only show the very first attached to their accounts
2024-09-24 14:25:48 +00:00
Nino Righi
41be8533dc Merged PR 1790: #4776 Suchbegriff in der Artikelsuche soll bei Klick auf Filter bestehen blei...
#4776 Suchbegriff in der Artikelsuche soll bei Klick auf Filter bestehen bleiben (Trefferliste)
2024-09-24 13:42:17 +00:00
Nino Righi
186afbc828 Merged PR 1789: #4687 WA, Abholfach, HSC - First and Lastname Update on Buyer just on Order
#4687 WA, Abholfach, HSC - First and Lastname Update on Buyer just on Order
2024-09-24 13:39:57 +00:00
Nino Righi
c3561339a9 Merged PR 1788: #4794 Adjusted Route Error Handling
#4794 Adjusted Route Error Handling
2024-09-24 13:01:43 +00:00
Nino Righi
5312073184 Merged PR 1787: #4710 Initially Select All Possible Items Inside Purchase Options Modal
#4710 Initially Select All Possible Items Inside Purchase Options Modal
2024-09-24 12:45:49 +00:00
Lorenz Hilpert
4dfe3bfa11 Merge tag 'KameraOffline' into develop
Kamera kann nur geöffnet werden wenn man Online ist. KameraOffline
2024-09-24 14:39:19 +02:00
Lorenz Hilpert
9b7a1b1c21 Merge branch 'hotfix/skip-open-camera-when-offline' 2024-09-24 14:39:11 +02:00
Lorenz Hilpert
a290d3b249 Kamera öffnet sich nur wenn man Online ist 2024-09-24 14:37:48 +02:00
Lorenz Hilpert
ad348af551 Merge branch 'master' into release/3.2 2024-09-17 10:56:13 +02:00
Lorenz Hilpert
f1bdba5d10 Merge tag 'online-offline-verhalten' into develop
Merge Online Offline Verhalten online-offline-verhalten
2024-09-16 16:46:38 +02:00
Lorenz Hilpert
c4134e7f99 Merge branch 'hotfix/online-offline-network' 2024-09-16 16:46:28 +02:00
Lorenz Hilpert
b7a16f5d30 IPad 6 Fehlermeldung word wrap 2024-09-16 14:39:00 +02:00
Lorenz Hilpert
4105709286 Added Styles instead of classes for word wrapping 2024-09-16 14:23:11 +02:00
Lorenz Hilpert
0c3b322fbd Ipad 4 Error Anzeige 2024-09-16 13:31:00 +02:00
Lorenz Hilpert
12096754c7 Set Max Screen Width Error 2024-09-16 12:28:25 +02:00
Lorenz Hilpert
453d921a99 Nachricht angepasst 2024-09-16 11:54:52 +02:00
Lorenz Hilpert
bad05fd098 Offline und Online Banner
Initialisierung Wartet auf Netzwerk
2024-09-13 17:30:08 +02:00
Lorenz Hilpert
363daf1e35 console.log entfernt 2024-09-13 16:08:21 +02:00
Lorenz Hilpert
e0cb0974cf Initialisierung gibt ein Feedback an den Benutzer aus. Feedback wenn Benutzer offline ist. 2024-09-13 16:05:54 +02:00
Lorenz Hilpert
c3d9274766 Merge branch 'hotfix/pwa-camera-dialog-size' 2024-09-13 11:03:04 +02:00
Lorenz Hilpert
bc16b841fb Kamera Overlay Größe
(cherry picked from commit d5dc4e053d)
2024-09-13 11:02:30 +02:00
Lorenz Hilpert
d5dc4e053d Kamera Overlay Größe 2024-09-12 18:03:07 +02:00
Lorenz Hilpert
3c6833988c Change Variables in pipeline Minor from 1 to 2 2024-09-04 17:58:00 +02:00
Lorenz Hilpert
28fb4ebb48 Merge tag '3.1' into develop 2024-09-04 17:56:06 +02:00
Lorenz Hilpert
2118bd996a Merge branch 'release/3.1' 2024-09-04 17:52:55 +02:00
Lorenz Hilpert
8a6448cc17 Merge branch 'develop' into release/3.1 2024-08-19 15:01:59 +02:00
Lorenz Hilpert
f2c7d57ad6 Fix Remi Filter 2024-08-16 14:17:11 +02:00
Lorenz Hilpert
9c9ddfaeec #4774 Remi // Wannennummer nur einmal am Tag benutzbar 2024-08-14 15:45:39 +02:00
Lorenz Hilpert
6eaa347de5 Merge branch 'master' into develop 2024-08-13 11:04:36 +02:00
Lorenz Hilpert
a16f355396 Merge branch 'hotfix/scandit-lizenz-erneuern' 2024-08-13 11:02:16 +02:00
Lorenz Hilpert
8b8db6e335 Update Scandit Lizenz 2024-08-12 13:39:32 +02:00
Lorenz Hilpert
06e248d615 Kundensuche abbrechen 2024-06-27 15:47:41 +02:00
Lorenz Hilpert
67cf380948 Update Matomo Docker Konfiguration 2024-06-25 14:06:18 +02:00
Lorenz Hilpert
e0ae79bc2a Update Docker Compose 2024-06-25 13:00:54 +02:00
Lorenz Hilpert
8ccc29c85a Tracking - Filter, Artikelsuche, Abholfach(Einbuchen, Reservierung, Ausräumen,Fehlende) 2024-06-24 15:10:51 +02:00
Lorenz Hilpert
c68706b54f Merged PR 1786: #4760 Fehler bei Abholpreisberechnung in Filiale Darmstadt Ernst-Ludwig-Straße
#4760 Fehler bei Abholpreisberechnung in Filiale Darmstadt Ernst-Ludwig-Straße
2024-06-10 12:22:36 +00:00
Lorenz Hilpert
b271ce9711 Merged PR 1785: Angular 17 Update + Cleanup Packages 2024-06-06 13:31:02 +00:00
Nino Righi
94888213b1 Merged PR 1784: #4758 Loading Indicator if Date gets Patched on OrderItemSubset
#4758 Loading Indicator if Date gets Patched on OrderItemSubset
2024-06-05 17:04:41 +00:00
Nino Righi
1041d92486 Merged PR 1783: #4750 Code improvements, Check if Icon gets loaded
#4750 Code improvements, Check if Icon gets loaded
2024-06-04 16:02:53 +00:00
Nino Righi
43d8d220c9 Merged PR 1782: #4750 Check if Icon File exists
#4750 Check if Icon File exists
2024-05-28 16:03:15 +00:00
Nino Righi
e0993d9c46 Merged PR 1781: #4599 Fix Routing After Click on Continue Shopping CTA - On Tablet Size or Sm...
#4599 Fix Routing After Click on Continue Shopping CTA - On Tablet Size or Smaller
2024-05-28 15:57:54 +00:00
Nino Righi
82656d9b27 Merged PR 1780: #4314 Navigation on Product Cover Click
#4314 Navigation on Product Cover Click
2024-05-28 15:57:31 +00:00
Lorenz Hilpert
df36d0934d Merged PR 1779: #4752 Performance in der WA verbessert -> Details Seite
#4752 Performance in der WA verbessert -> Details Seite
2024-05-28 13:48:00 +00:00
Nino Righi
920b8eb8e3 Merged PR 1778: #4004 Changed Minimum Birth Date for Kubi Case
#4004 Changed Minimum Birth Date for Kubi Case
2024-05-06 12:00:58 +00:00
Nino Righi
4db28b1aa7 Merged PR 1777: Merge Develop -> Release/3.1
Merge Develop -> Release/3.1
2024-05-03 13:00:46 +00:00
Nino Righi
3a9820aa54 Merged PR 1776: #4721 Removed unnecessary check for scrolling to item
#4721 Removed unnecessary check for scrolling to item
2024-05-02 19:21:52 +00:00
Nino Righi
30ad99332e Merged PR 1775: #3751 ProductGroup and ProductGroupDetails Update
#3751 ProductGroup and ProductGroupDetails Update
2024-04-22 13:31:20 +00:00
Lorenz Hilpert
4b48275910 Merged PR 1774: AHF Performance 2024-04-19 09:54:54 +00:00
Lorenz Hilpert
d3e3316459 Merge branch 'master' into develop 2024-04-17 16:25:02 +02:00
Nino Righi
4ef1bd4df6 Merged PR 1771: #4720 Hotfix Navigation Pickup Shelf Out
#4720 Hotfix Navigation Pickup Shelf Out
2024-04-17 14:21:30 +00:00
Nino Righi
0c2a23e5d2 Merged PR 1773: #3751 Reservation List Show Compartment and ProductGroup from InStock
#3751 Reservation List Show Compartment and ProductGroup from InStock
2024-04-17 08:46:32 +00:00
Nino Righi
36bd2c1eba Merged PR 1772: #4004 Kubi Check If Customer is 18 Years old
#4004 Kubi Check If Customer is 18 Years old
2024-04-15 12:34:14 +00:00
Nino Righi
a38d2eede6 Merged PR 1770: #4709 Removed Save Special Comment CTA on Checkout Cart Review
#4709 Removed Save Special Comment CTA on Checkout Cart Review
2024-04-12 10:37:43 +00:00
Lorenz Hilpert
ed7dc10246 Bump Version 2024-04-09 10:43:39 +02:00
Lorenz Hilpert
f5251d9069 Merge tag '3.0' into develop
3.0
2024-04-09 09:35:54 +02:00
Lorenz Hilpert
2bd21e168a Merge branch 'release/3.0' 2024-04-09 09:34:33 +02:00
Lorenz Hilpert
3661bf7580 Merge branch 'develop' into release/3.0 2024-04-03 11:59:12 +02:00
Lorenz Hilpert
9f2a6633f7 Anpasssung Selector Für E2E - Lieferadresse, Rechnugsadresse 2024-04-03 11:30:07 +02:00
Nino
3c4d0ea56c Merge branch 'release/3.0' into develop 2024-03-20 12:10:17 +01:00
Nino
56bb784c83 Added Classes and Data Attributes to package-inspection for e2e testing 2024-03-20 12:06:05 +01:00
Nino Righi
c687570b1f Merged PR 1769: #4712 Removed isShippingEnabled check from availabilities modal
#4712 Removed isShippingEnabled check from availabilities modal
2024-03-20 10:42:59 +00:00
5784 changed files with 473359 additions and 85564 deletions

36
.github/commit-instructions.md vendored Normal file
View File

@@ -0,0 +1,36 @@
# Commit Message Instructions
## Format
Each commit message should follow this structure:
1. **Short Summary**: A brief summary of the changes (max 72 characters).
2. **List of Changes**: A detailed list of changes with icons to indicate the type of change.
---
### Example
```
Added a new module to handle user authentication, including login and registration.
- ✨ **Feature**: Implemented user login functionality
- 🐛 **Fix**: Resolved session timeout issue
- 🛠️ **Refactor**: Improved error handling in auth service
- 🧪 **Test**: Added unit tests for login component
```
---
## Icons for Change Types
-**Feature**: New features or functionality
- 🐛 **Fix**: Bug fixes
- 🛠️ **Refactor**: Code improvements without changing functionality
- 🧪 **Test**: Adding or updating tests
- 📚 **Docs**: Documentation updates
- 🗑️ **Chore**: Maintenance tasks (e.g., dependency updates)
- 🚀 **Performance**: Performance improvements
- 🎨 **Style**: Code style changes (e.g., formatting)
- 🔒 **Security**: Security-related changes
- ⚙️ **Config**: Configuration changes

17
.github/copilot-instructions.md vendored Normal file
View File

@@ -0,0 +1,17 @@
# Spark Instructions
## Introduction
You are Spark, a mentor designed to help me with coding, preview my work, and assist me in improving by pointing out areas for enhancement.
## Tone and Personality
You are a mentor with a dual approach: when I make a mistake or my work needs improvement, you adopt a strict and technical tone to clearly explain whats wrong and how to fix it. In all other cases, you are casual and friendly, like a supportive coding buddy, keeping the vibe light and encouraging.
## Behavioral Guidelines
- Focus on constructive feedback; avoid simply rewriting my code unless I ask for it.
- If my question or code is unclear, ask me for clarification or more details.
- Do not discourage me; always frame suggestions as opportunities for growth.
- Avoid giving generic answers—tailor your advice to my specific code or problem.
- Keep my preferences in mind: prioritize Type safety, follow Clean Code principles and emphasize good documentation.

181
.github/review-instructions.md vendored Normal file
View File

@@ -0,0 +1,181 @@
# Code Review Instructions
## Summary
When conducting a code review, follow these steps to ensure a thorough and constructive process.
**Ensure that all review guidelines are followed. If any guideline is not adhered to, make it explicitly clear which guideline needs to be followed.**
## Review Process
1. 🎯 **Key Issues**
Identify critical issues in the code such as bugs, security vulnerabilities, or violations of the project's coding standards.
_Include specific links to files and line numbers (e.g., file.js#L10) where applicable._
2. 💡 **Suggestions for Improvement**
Highlight areas where the code can be enhanced in terms of readability, performance, maintainability, or adherence to best practices.
_Clarify what constitutes a "Critical" versus a "Minor" issue to avoid ambiguity._
3.**Code Examples**
Provide specific, concise code snippets that illustrate your suggestions.
_Include both a "Before" (problematic code) and an "After" (improved version) example where beneficial._
4. 📚 **Relevant Documentation Links**
Attach links to useful resources or official documentation to support the suggested changes.
_For example, link to ESLint, Jest, or Angular Style Guide pages when relevant._
## Tone and Feedback
- Be constructive and supportive.
Frame suggestions as opportunities for growth rather than criticism.
- Use the following emojis to categorize your feedback:
- 🚨 **Critical issues**
-**Minor Issues**
- ⚠️ **Warnings**
- 💡 **Suggestions**
-**Good practices**
## Additional Informations
- Treat missing tests and JSDocs as warnings
- Tread missing unit test as warnings
### Review Template
````markdown
# Code Review
## Summary
A brief overview of the codes overall quality, highlighting key strengths and areas needing attention. This sets the stage for the detailed feedback below.
---
## 🚨 Critical Issues
High-priority issues that must be addressed immediately due to their potential to severely impact functionality, performance, or security.
### 1. High Priority: [Issue Title]
#### 🚨 Issue
Describe the issue clearly, including links to specific files and lines (e.g., file.js#L10). Explain why its critical—highlight crashes, security risks, or significant performance issues.
#### 💡 Suggestions for Improvement
Provide specific steps or alternative approaches to resolve the issue.
#### ✨ Code Example
**Current**: [file](file.js#L10) Problematic code with path to the file and line of the code
```typescript
// Code...
```
**Improvement**: Improved version
```typescript
// Code...
```
#### 📚 Relevant Documentation
Include URLs for further research (e.g., [Jest Documentation](https://jestjs.io/docs/getting-started)).
---
## ❗ Minor Issues
Issues that can improve code quality, maintainability, or adherence to best practices when resolved.
### 1. Medium Priority: [Issue Title]
#### ❗ Issue
Describe the issue clearly, including file and line references (e.g., file.js#L10). Explain the impact on the project.
#### 💡 Suggestions for Improvement
Offer concrete steps or alternative approaches to mitigate the issue.
#### ✨ Code Example
**Current**: [file](file.js#L10) Problematic code with path to the file and line of the code
```typescript
// Code...
```
**Improvement**: Improved version
```typescript
// Code...
```
#### 📚 Relevant Documentation
Provide links to further resources.
---
## ⚠️ Warnings
Low-priority issues or suggestions that could help prevent future problems or improve the code quality over time.
### 1. Low Priority: [Issue Title]
#### ⚠️ Issue
Describe the issue clearly with references (e.g., file.js#L10). Explain the potential impact if left unaddressed.
#### 💡 Suggestions for Improvement
Provide suggestions or alternative implementations to mitigate the issue.
#### ✨ Code Example
**Current**: [file](file.js#L10) Problematic code with path to the file and line of the code
```typescript
// Code...
```
**Improvement**: Improved version
```typescript
// Code...
```
#### 📚 Relevant Documentation
Include relevant resources for more information.
---
## 🛑 Bad Practices
Highlight up to five bad aspects of the code to reinforce improvements and encourage good practices. Use different funny emoji at the beginning of each bad practice.
- Emoji **Bad Practice 1**:
Describe a specific weakness (e.g., clear code structure) with an example reference (e.g., file.js#L20). Explain why its bad.
- Emoji **Bad Practice 2**:
Outline another negative feature (e.g., effective error handling) with a snippet reference.
---
## ✅ Good Practices
Highlight up to five positive aspects of the code to reinforce well-implemented patterns and encourage good practices. Use different funny emoji at the beginning of each good practice.
- Emoji **Good Practice 1**:
Describe a specific strength (e.g., clear code structure) with an example reference (e.g., file.js#L20). Explain why its commendable.
- Emoji **Good Practice 2**:
Outline another positive feature (e.g., effective error handling) with a snippet reference.
---
## 📓 Additional Notes
- **General Feedback**: Optional thoughts regarding the overall quality or potential areas for future improvement.
- **Next Steps**: Outline follow-up actions or further examination areas as needed.
````

61
.github/testing-instructions.md vendored Normal file
View File

@@ -0,0 +1,61 @@
# Testing Instructions
## Framework and Tools
- Use **Jest** as the testing framework.
- For unit tests, utilize **Spectator** to simplify Angular component testing.
## Guidelines
1. **Error Case Testing**: Ensure all edge cases and error scenarios are thoroughly tested.
2. **Arrange-Act-Assert Pattern**: Follow the Arrange-Act-Assert pattern for structuring your tests:
- **Arrange**: Set up the testing environment and initialize required variables.
- **Act**: Execute the functionality being tested.
- **Assert**: Verify the expected outcomes.
## Best Practices
- Write clear and descriptive test names.
- Ensure tests are isolated and do not depend on each other.
- Mock external dependencies to avoid side effects.
- Aim for high code coverage without compromising test quality.
## Example Test Structure
```typescript
// Example using Jest and Spectator
import { createComponentFactory, Spectator } from '@ngneat/spectator';
import { MyComponent } from './my-component.component';
describe('MyComponent', () => {
let spectator: Spectator<MyComponent>;
const createComponent = createComponentFactory(MyComponent);
beforeEach(() => {
spectator = createComponent();
});
it('should display the correct title', () => {
// Arrange
const expectedTitle = 'Hello World';
// Act
spectator.component.title = expectedTitle;
spectator.detectChanges();
// Assert
expect(spectator.query('h1')).toHaveText(expectedTitle);
});
it('should handle error cases gracefully', () => {
// Arrange
const invalidInput = null;
// Act
spectator.component.input = invalidInput;
// Assert
expect(() => spectator.component.processInput()).toThrowError('Invalid input');
});
});
```
## Additional Resources
- [Jest Documentation](https://jestjs.io/docs/getting-started)
- [Spectator Documentation](https://ngneat.github.io/spectator/)

15
.gitignore vendored
View File

@@ -1,10 +1,14 @@
# See http://help.github.com/ignore-files/ for more about ignoring files.
.matomo
# compiled output
/dist
/tmp
/out-tsc
/
# dependencies
/node_modules
@@ -47,4 +51,13 @@ testem.log
.DS_Store
Thumbs.db
libs/swagger/src/lib/*
libs/swagger/src/lib/*
*storybook.log
.nx/cache
.nx/workspace-data
.angular
storybook-static

1
.husky/pre-commit Normal file
View File

@@ -0,0 +1 @@
npx lint-staged

1
.husky/pre-push Normal file
View File

@@ -0,0 +1 @@
npm run ci

7
.lintstagedrc.json Normal file
View File

@@ -0,0 +1,7 @@
{
"*.ts": "npx eslint --fix --config eslint.config.mjs",
"*.tsx": "npx eslint --fix --config eslint.config.mjs",
"*.js": "npx eslint --fix --config eslint.config.mjs",
"*.jsx": "npx eslint --fix --config eslint.config.mjs",
"*.html": "npx eslint --fix --config eslint.config.mjs"
}

View File

@@ -1,10 +1,8 @@
# Add files here to ignore them from prettier formatting
/dist
/coverage
/helmvalues
/apps/swagger
/ng-swagger-gen
*.json
*.yml
/.nx/cache
/.nx/workspace-data
/node_modules
.angular
.vscode

View File

@@ -1,5 +0,0 @@
{
"singleQuote": true,
"printWidth": 140
}

View File

@@ -1,7 +1,10 @@
{
"recommendations": [
"johnpapa.angular2",
"esbenp.prettier-vscode",
"angular.ng-template",
]
}
"recommendations": [
"johnpapa.angular2",
"esbenp.prettier-vscode",
"angular.ng-template",
"nrwl.angular-console",
"dbaeumer.vscode-eslint",
"firsttris.vscode-jest-runner"
]
}

90
.vscode/settings.json vendored
View File

@@ -1,15 +1,95 @@
{
"editor.accessibilitySupport": "off",
"typescript.tsdk": "node_modules/typescript/lib",
"exportall.config.exclude": [".test.", ".spec.", ".stories."],
"editor.formatOnSave": true,
"typescriptHero.imports.insertSemicolons": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"[javascript]": {
"eslint.validate": [
"json"
],
"[html]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"css.validate": false,
"less.validate": false,
"scss.validate": false
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
},
"exportall.config.folderListener": [
"/libs/oms/data-access/src/lib/models",
"/libs/oms/data-access/src/lib/schemas",
"/libs/catalogue/data-access/src/lib/models"
],
"github.copilot.chat.commitMessageGeneration.instructions": [
{
"file": ".github/commit-instructions.md"
}
],
"github.copilot.chat.codeGeneration.instructions": [
{
"file": ".github/copilot-instructions.md"
},
{
"file": ".github/review-instructions.md"
},
{
"file": ".github/testing-instructions.md"
},
{
"file": "docs/tech-stack.md"
},
{
"file": "docs/guidelines/code-style.md"
},
{
"file": "docs/guidelines/project-structure.md"
},
{
"file": "docs/guidelines/state-management.md"
},
{
"file": "docs/guidelines/testing.md"
}
],
"github.copilot.chat.testGeneration.instructions": [
{
"file": ".github/copilot-instructions.md"
},
{
"file": ".github/testing-instructions.md"
},
{
"file": "docs/tech-stack.md"
},
{
"file": "docs/guidelines/code-style.md"
},
{
"file": "docs/guidelines/testing.md"
}
],
"github.copilot.chat.reviewSelection.instructions": [
{
"file": ".github/copilot-instructions.md"
},
{
"file": ".github/review-instructions.md"
},
{
"file": "docs/tech-stack.md"
},
{
"file": "docs/guidelines/code-style.md"
},
{
"file": "docs/guidelines/project-structure.md"
},
{
"file": "docs/guidelines/state-management.md"
},
{
"file": "docs/guidelines/testing.md"
}
],
}

View File

@@ -24,6 +24,6 @@ ARG BuildUniqueID
LABEL build.uniqueid="${BuildUniqueID:-1}"
RUN wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb -q -O /tmp/chrome.deb && apt update && apt install -y /tmp/chrome.deb
# ignore exitcode, sonst gibts keinen container
RUN npm test || true
RUN npm run ci || true
ENTRYPOINT [ "/bin/sleep", "60000" ]

View File

@@ -1,4 +0,0 @@
- Neue Icon Module (z.B. mit SVG sprites)
- Breadcrumb Navigation (Neu)
- Remissions Produkt Liste (Refactoring / Neu)
- Angular Version (Upgrade)

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,25 +0,0 @@
# Scan
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 12.2.0.
## Code scaffolding
Run `ng generate component component-name --project scan` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project scan`.
> Note: Don't forget to add `--project scan` or else it will be added to the default project in your `angular.json` file.
## Build
Run `ng build scan` to build the project. The build artifacts will be stored in the `dist/` directory.
## Publishing
After building your library with `ng build scan`, go to the dist folder `cd dist/scan` and run `npm publish`.
## Running unit tests
Run `ng test scan` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/adapter/scan",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,11 +0,0 @@
{
"name": "@adapter/scan",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^12.2.0",
"@angular/core": "^12.2.0"
},
"dependencies": {
"tslib": "^2.3.0"
}
}

View File

@@ -1,44 +0,0 @@
import { Injectable, isDevMode } from '@angular/core';
import { EnvironmentService } from '@core/environment';
import { PromptModalData, UiModalService, UiPromptModalComponent } from '@ui/modal';
import { Observable } from 'rxjs';
import { ScanAdapter } from './scan-adapter';
@Injectable()
export class DevScanAdapter implements ScanAdapter {
readonly name = 'Dev';
constructor(private _modal: UiModalService, private _environmentService: EnvironmentService) {}
async init(): Promise<boolean> {
return Promise.resolve(false);
// return new Promise((resolve, reject) => {
// resolve(isDevMode());
// });
}
scan(): Observable<string> {
return new Observable((observer) => {
const modalRef = this._modal.open({
content: UiPromptModalComponent,
title: 'Scannen',
data: {
message: 'Diese Eingabemaske dient nur zu Entwicklungs und Testzwecken.',
placeholder: 'Scan Code',
confirmText: 'weiter',
cancelText: 'abbrechen',
} as PromptModalData,
});
const sub = modalRef.afterClosed$.subscribe((result) => {
observer.next(result.data);
observer.complete();
});
return () => {
modalRef.close();
sub.unsubscribe();
};
});
}
}

View File

@@ -1,20 +0,0 @@
:host {
@apply block relative;
}
.scanner-container {
width: 100vw;
max-width: 95vw;
max-height: calc(95vh - 120px);
}
.close-scanner {
@apply block px-6 py-4 bg-white text-brand border-2 border-solid border-brand rounded-full text-lg font-bold mx-auto mt-4;
}
@screen desktop {
.scanner-container {
max-width: 900px;
max-height: 900px;
}
}

View File

@@ -1,4 +0,0 @@
<div class="scanner-container" #scanContainer></div>
<button class="close-scanner" type="button" (click)="close()">
Scan abbrechen
</button>

View File

@@ -1,100 +0,0 @@
import { Component, ChangeDetectionStrategy, ElementRef, ViewChild, NgZone, AfterViewInit, OnDestroy } from '@angular/core';
import { UiMessageModalComponent, UiModalService } from '@ui/modal';
import { Barcode, BarcodePicker, ScanResult, ScanSettings } from 'scandit-sdk';
@Component({
selector: 'app-scandit-overlay',
templateUrl: 'scandit-overlay.component.html',
styleUrls: ['scandit-overlay.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ScanditOverlayComponent implements AfterViewInit, OnDestroy {
private _barcodePicker: BarcodePicker;
private _onScan?: (code: string) => void;
private _onClose?: () => void;
@ViewChild('scanContainer', { read: ElementRef, static: true }) scanContainer: ElementRef;
constructor(private _zone: NgZone, private _modal: UiModalService) {}
ngAfterViewInit(): void {
this.createBarcodePicker()
.then(() => {
this._barcodePicker.on('scan', (scanResult) => {
this._zone.run(() => this.handleScanrResult(scanResult));
});
})
.catch((err: Error) => {
this._modal
.open({
content: UiMessageModalComponent,
title: 'Zugriff auf Kamera verweigert',
data: { message: 'Falls Sie den Zugriff erlauben möchten, können Sie das über die Webseiteinstellung Ihres Browsers.' },
})
.afterClosed$.subscribe(() => {
this._onClose?.();
});
});
}
async createBarcodePicker() {
this._barcodePicker = await BarcodePicker.create(this.scanContainer.nativeElement, {
playSoundOnScan: true,
vibrateOnScan: true,
});
this._barcodePicker.applyScanSettings(this.getScanSettings());
}
getScanSettings(): ScanSettings {
return new ScanSettings({
blurryRecognition: false,
enabledSymbologies: [
Barcode.Symbology.EAN8,
Barcode.Symbology.EAN13,
Barcode.Symbology.UPCA,
Barcode.Symbology.UPCE,
Barcode.Symbology.CODE128,
Barcode.Symbology.CODE39,
Barcode.Symbology.CODE93,
Barcode.Symbology.INTERLEAVED_2_OF_5,
Barcode.Symbology.QR,
],
codeDuplicateFilter: 1000,
});
}
onScan(fn: (code: string) => void) {
this._onScan = fn;
}
onClose(fn: () => void) {
this._onClose = fn;
}
handleScanrResult(scanRestul: ScanResult) {
let result: string | undefined;
if (scanRestul.barcodes.length) {
result = scanRestul.barcodes[0].data;
} else if (scanRestul.texts.length) {
result = scanRestul.texts[0].value;
}
if (result) {
this._onScan?.(result);
}
}
close() {
this._onClose?.();
}
ngOnDestroy(): void {
this._zone.runOutsideAngular(() => {
this._barcodePicker?.destroy(true);
});
}
}

View File

@@ -1,82 +0,0 @@
import { Injectable } from '@angular/core';
import { Observable, Subscriber } from 'rxjs';
import { ScanAdapter } from '../scan-adapter';
import { Overlay } from '@angular/cdk/overlay';
import { configure } from 'scandit-sdk';
// import { ScanditModalComponent } from './scandit-modal';
import { Config } from '@core/config';
import { ComponentPortal } from '@angular/cdk/portal';
import { ScanditOverlayComponent } from './scandit-overlay.component';
import { EnvironmentService } from '@core/environment';
@Injectable()
export class ScanditScanAdapter implements ScanAdapter {
readonly name = 'Scandit';
constructor(private readonly _config: Config, private _overlay: Overlay, private _environmentService: EnvironmentService) {}
async init(): Promise<boolean> {
if (this._environmentService.isTablet()) {
await configure(this._config.get('licence.scandit'), {
engineLocation: '/scandit/',
});
return true;
}
return false;
}
scan(): Observable<string> {
return new Observable((observer) => {
const overlay = this.createOverlay();
const portal = this.createPortal();
const ref = overlay.attach(portal);
const sub = new Subscriber();
const complete = () => {
overlay.detach();
ref.destroy();
sub.unsubscribe();
sub.complete();
observer.complete();
};
sub.add(
overlay.backdropClick().subscribe(() => {
complete();
})
);
ref.instance.onScan((code) => {
observer.next(code);
complete();
});
ref.instance.onClose(() => {
complete();
});
return complete;
});
}
createOverlay() {
const overlay = this._overlay.create({
positionStrategy: this._overlay.position().global().centerHorizontally().centerVertically(),
hasBackdrop: true,
});
return overlay;
}
createPortal() {
const portal = new ComponentPortal(ScanditOverlayComponent);
return portal;
}
}

View File

@@ -1,11 +0,0 @@
/*
* Public API Surface of scan
*/
export * from './lib/scandit';
export * from './lib/dev.scan-adapter';
export * from './lib/native.scan-adapter';
export * from './lib/scan-adapter';
export * from './lib/scan.module';
export * from './lib/scan.service';
export * from './lib/tokens';

View File

@@ -1,19 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "../../../out-tsc/lib",
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"types": [],
"lib": [
"dom",
"es2018"
]
},
"exclude": [
"src/test.ts",
"**/*.spec.ts"
]
}

View File

@@ -1,10 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.lib.json",
"compilerOptions": {
"declarationMap": false
},
"angularCompilerOptions": {
"compilationMode": "partial"
}
}

View File

@@ -1,14 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "../../../out-tsc/spec",
"types": [
"jasmine"
]
},
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}

View File

@@ -1,25 +0,0 @@
# ProductImage
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
## Code scaffolding
Run `ng generate component component-name --project product-image` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project product-image`.
> Note: Don't forget to add `--project product-image` or else it will be added to the default project in your `angular.json` file.
## Build
Run `ng build product-image` to build the project. The build artifacts will be stored in the `dist/` directory.
## Publishing
After building your library with `ng build product-image`, go to the dist folder `cd dist/product-image` and run `npm publish`.
## Running unit tests
Run `ng test product-image` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/cdn/product-image",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,11 +0,0 @@
{
"name": "@cdn/product-image",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^10.1.2",
"@angular/core": "^10.1.2"
},
"dependencies": {
"tslib": "^2.0.0"
}
}

View File

@@ -1,8 +0,0 @@
/*
* Public API Surface of product-image
*/
export * from './lib/product-image.service';
export * from './lib/product-image.module';
export * from './lib/product-image.pipe';
export * from './lib/tokens';

View File

@@ -1,24 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "../../../out-tsc/lib",
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"types": [],
"lib": [
"dom",
"es2018"
]
},
"angularCompilerOptions": {
"skipTemplateCodegen": true,
"strictMetadataEmit": true,
"enableResourceInlining": true
},
"exclude": [
"src/test.ts",
"**/*.spec.ts"
]
}

View File

@@ -1,10 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.lib.json",
"compilerOptions": {
"declarationMap": false
},
"angularCompilerOptions": {
"compilationMode": "partial"
}
}

View File

@@ -1,14 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../../tsconfig.json",
"compilerOptions": {
"outDir": "../../../out-tsc/spec",
"types": [
"jasmine"
]
},
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}

View File

@@ -1,17 +0,0 @@
{
"extends": "../../../tslint.json",
"rules": {
"directive-selector": [
true,
"attribute",
"cdn",
"camelCase"
],
"component-selector": [
true,
"element",
"cdn",
"kebab-case"
]
}
}

View File

@@ -1,25 +0,0 @@
# Core
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 15.0.0.
## Code scaffolding
Run `ng generate component component-name --project core` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project core`.
> Note: Don't forget to add `--project core` or else it will be added to the default project in your `angular.json` file.
## Build
Run `ng build core` to build the project. The build artifacts will be stored in the `dist/` directory.
## Publishing
After building your library with `ng build core`, go to the dist folder `cd dist/core` and run `npm publish`.
## Running unit tests
Run `ng test core` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/core/application",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,6 +0,0 @@
// start:ng42.barrel
export * from './application.module';
export * from './application.service';
export * from './defs';
export * from './store';
// end:ng42.barrel

View File

@@ -1,18 +0,0 @@
import { createAction, props } from '@ngrx/store';
import { ApplicationProcess } from '..';
const prefix = '[CORE-APPLICATION]';
export const setTitle = createAction(`${prefix} Set Title`, props<{ title: string }>());
export const setSection = createAction(`${prefix} Set Section`, props<{ section: 'customer' | 'branch' }>());
export const addProcess = createAction(`${prefix} Add Process`, props<{ process: ApplicationProcess }>());
export const removeProcess = createAction(`${prefix} Remove Process`, props<{ processId: number }>());
export const setActivatedProcess = createAction(`${prefix} Set Activated Process`, props<{ activatedProcessId: number }>());
export const patchProcess = createAction(`${prefix} Patch Process`, props<{ processId: number; changes: Partial<ApplicationProcess> }>());
export const patchProcessData = createAction(`${prefix} Patch Process Data`, props<{ processId: number; data: Record<string, any> }>());

View File

@@ -1,35 +0,0 @@
import { ApplicationState } from './application.state';
import { ApplicationProcess } from '../defs';
import * as selectors from './application.selectors';
describe('applicationSelectors', () => {
it('should select the processes', () => {
const processes: ApplicationProcess[] = [{ id: 1, name: 'Vorgang 1', section: 'customer' }];
const state: ApplicationState = {
processes,
section: 'customer',
};
expect(selectors.selectProcesses.projector(state)).toEqual(processes);
});
it('should select the section', () => {
const state: ApplicationState = {
processes: [],
section: 'customer',
};
expect(selectors.selectSection.projector(state)).toEqual('customer');
});
it('should select the activatedProcess', () => {
const processes: ApplicationProcess[] = [
{ id: 1, name: 'Vorgang 1', section: 'customer', activated: 100 },
{ id: 2, name: 'Vorgang 2', section: 'customer', activated: 300 },
{ id: 3, name: 'Vorgang 3', section: 'customer', activated: 200 },
];
const state: ApplicationState = {
processes,
section: 'customer',
};
expect(selectors.selectActivatedProcess.projector(state)).toEqual(processes[1]);
});
});

View File

@@ -1,5 +0,0 @@
/*
* Public API Surface of application
*/
export * from './lib';

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/core/auth",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,125 +0,0 @@
import { coerceArray, coerceStringArray } from '@angular/cdk/coercion';
import { Injectable } from '@angular/core';
import { Config } from '@core/config';
import { isNullOrUndefined } from '@utils/common';
import { AuthConfig, OAuthService } from 'angular-oauth2-oidc';
import { JwksValidationHandler } from 'angular-oauth2-oidc-jwks';
import { asapScheduler, BehaviorSubject } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class AuthService {
private readonly _initialized = new BehaviorSubject<boolean>(false);
get initialized$() {
return this._initialized.asObservable();
}
private _authConfig: AuthConfig;
constructor(private _config: Config, private readonly _oAuthService: OAuthService) {
this._oAuthService.events?.subscribe((event) => {
if (event.type === 'token_received') {
console.log('SSO Token Expiration:', new Date(this._oAuthService.getAccessTokenExpiration()));
}
});
}
async init() {
if (this._initialized.getValue()) {
throw new Error('AuthService is already initialized');
}
this._authConfig = this._config.get('@core/auth');
this._authConfig.redirectUri = window.location.origin;
this._authConfig.silentRefreshRedirectUri = window.location.origin + '/silent-refresh.html';
this._authConfig.useSilentRefresh = true;
this._oAuthService.configure(this._authConfig);
this._oAuthService.tokenValidationHandler = new JwksValidationHandler();
this._oAuthService.setupAutomaticSilentRefresh();
try {
await this._oAuthService.loadDiscoveryDocumentAndTryLogin();
} catch (error) {
this.login();
}
this._initialized.next(true);
}
isAuthenticated() {
return this._oAuthService.hasValidIdToken();
}
getToken() {
return this._oAuthService.getAccessToken();
}
getClaims() {
const token = this._oAuthService.getAccessToken();
return this.parseJwt(token);
}
getClaimByKey(key: string) {
const claims = this.getClaims();
if (isNullOrUndefined(claims)) {
return null;
}
return claims[key];
}
parseJwt(token: string) {
if (isNullOrUndefined(token)) {
return null;
}
const base64Url = token.split('.')[1];
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
const encoded = window.atob(base64);
return JSON.parse(encoded);
}
login() {
this._oAuthService.initLoginFlow();
}
setKeyCardToken(token: string) {
this._oAuthService.customQueryParams = {
temp_token: token,
};
}
async logout() {
await this._oAuthService.revokeTokenAndLogout();
// asapScheduler.schedule(() => {
// window.location.reload();
// }, 250);
}
hasRole(role: string | string[]) {
const roles = coerceArray(role);
const userRoles = this.getClaimByKey('role');
if (isNullOrUndefined(userRoles)) {
return false;
}
return roles.every((r) => userRoles.includes(r));
}
async refresh() {
try {
if (this._authConfig.responseType.includes('code') && this._authConfig.scope.includes('offline_access')) {
await this._oAuthService.refreshToken();
} else {
await this._oAuthService.silentRefresh();
}
} catch (error) {
console.error(error);
}
}
}

View File

@@ -1,4 +0,0 @@
// start:ng42.barrel
export * from './auth.module';
export * from './auth.service';
// end:ng42.barrel

View File

@@ -1,5 +0,0 @@
/*
* Public API Surface of auth
*/
export * from './lib';

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/core/breadcrumb",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1 +0,0 @@
describe('Breadcrumb Actions', () => {});

View File

@@ -1,57 +0,0 @@
import * as selector from './breadcrumb.selectors';
import * as action from './breadcrumb.actions';
import { breadcrumbReducer } from './breadcrumb.reducer';
import { BreadcrumbState, INIT } from './breadcrumb.state';
describe('Breadcrumb Selectors', () => {
let state: BreadcrumbState;
beforeEach(() => {
state = breadcrumbReducer(
INIT,
action.addBreadcrumb({ breadcrumb: { id: 1, key: 'unit-test-1', path: '', name: 'Unit Test 1', section: 'customer' } })
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({
breadcrumb: { id: 2, key: 'unit-test-1', path: '', name: 'Unit Test 1', tags: ['details'], section: 'customer' },
})
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({ breadcrumb: { id: 3, key: 'unit-test-2', path: '', name: 'Unit Test 1', section: 'customer' } })
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({ breadcrumb: { id: 4, key: 'unit-test-3', path: '', name: 'Unit Test 1', section: 'customer' } })
);
state = breadcrumbReducer(
state,
action.addBreadcrumb({
breadcrumb: { id: 5, key: 'unit-test-3', path: '', name: 'Unit Test 1', tags: ['details'], section: 'customer' },
})
);
});
describe('selectBreadcrumbsByKey', () => {
it('should return all breadcrumbs with the key unit-test-1', () => {
const fixture = selector.selectBreadcrumbsByKey.projector(Object.values(state.entities), 'unit-test-1');
expect(fixture.length).toBe(2);
expect(fixture[0].key).toBe('unit-test-1');
expect(fixture[1].key).toBe('unit-test-1');
});
});
describe('selectBreadcrumbsByKeyAndTag', () => {
it('should return all breadcrumbs with the key unit-test-3 and tag details', () => {
const fixture = selector.selectBreadcrumbsByKeyAndTag.projector(Object.values(state.entities), {
key: 'unit-test-3',
tag: 'details',
});
expect(fixture.length).toBe(1);
expect(fixture[0].key).toBe('unit-test-3');
expect(fixture[0].tags).toContain('details');
});
});
});

View File

@@ -1,7 +0,0 @@
/*
* Public API Surface of breadcrumb
*/
export * from './lib/breadcrumb.service';
export * from './lib/core-breadcrumb.module';
export * from './lib/defs';

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/core/cache",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,4 +0,0 @@
export interface CacheOptions {
ttl?: number;
persist?: boolean;
}

View File

@@ -1,116 +0,0 @@
import { Injectable } from '@angular/core';
import { CacheOptions } from './cache-options';
import { Cached } from './cached';
import { interval } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class CacheService {
constructor() {
this._registerCleanupTask();
}
_registerCleanupTask() {
this.cleanup();
interval(1000 * 60).subscribe(() => {
this.cleanup();
});
}
set<T>(token: Object, data: T, options?: CacheOptions) {
const persist = options?.persist;
const ttl = options?.ttl;
const cached: Cached = {
data,
};
if (ttl) {
cached.until = Date.now() + ttl;
} else {
cached.until = Date.now() + 1000 * 60 * 60 * 12;
}
if (persist) {
localStorage.setItem(this.getKey(token), this.serialize(cached));
} else {
sessionStorage.setItem(this.getKey(token), this.serialize(cached));
}
Object.freeze(cached);
return cached;
}
get<T = any>(token: Object, from?: 'session' | 'persist'): T {
let cached: Cached;
if (from === 'session') {
cached = this.deserialize(sessionStorage.getItem(this.getKey(token)));
} else if (from === 'persist') {
cached = this.deserialize(localStorage.getItem(this.getKey(token)));
} else {
cached = this.deserialize(sessionStorage.getItem(this.getKey(token))) || this.deserialize(localStorage.getItem(this.getKey(token)));
}
if (!cached) {
return undefined;
}
if (cached.until < Date.now()) {
this.delete(token, from);
return undefined;
}
return cached.data;
}
delete(token: Object, from: 'session' | 'persist' = 'session') {
if (from === 'session') {
sessionStorage.removeItem(this.getKey(token));
} else if (from === 'persist') {
localStorage.removeItem(this.getKey(token));
}
}
private getKey(token: Object) {
const key = `CacheService_` + this.hash(JSON.stringify(token));
return key;
}
private hash(data: string): string {
let hash = 0;
for (let i = 0; i < data.length; i++) {
hash = data.charCodeAt(i) + ((hash << 5) - hash);
}
return hash.toString(16);
}
private serialize(data: Cached): string {
return JSON.stringify(data);
}
private deserialize(data: string): Cached {
return JSON.parse(data);
}
cleanup() {
// get all keys created by this service by looking for the service name and remove the entries
// that ttl is expired
let localStorageKeys = Object.keys(localStorage).filter((key) => key.startsWith('CacheService_'));
let seesionStorageKeys = Object.keys(sessionStorage).filter((key) => key.startsWith('CacheService_'));
localStorageKeys.forEach((key) => {
const cached = this.deserialize(localStorage.getItem(key));
if (cached.until < Date.now()) {
localStorage.removeItem(key);
}
});
seesionStorageKeys.forEach((key) => {
const cached = this.deserialize(sessionStorage.getItem(key));
if (cached.until < Date.now()) {
sessionStorage.removeItem(key);
}
});
}
}

View File

@@ -1,4 +0,0 @@
export interface Cached {
until?: number;
data?: any;
}

View File

@@ -1,6 +0,0 @@
/*
* Public API Surface of cache
*/
export * from './lib/cache.service';
export * from './lib/cache.module';

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/core/command",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,25 +0,0 @@
import { ModuleWithProviders, NgModule, Provider, Type } from '@angular/core';
import { ActionHandler } from './action-handler.interface';
import { CommandService } from './command.service';
import { FEATURE_ACTION_HANDLERS, ROOT_ACTION_HANDLERS } from './tokens';
export function provideActionHandlers(actionHandlers: Type<ActionHandler>[]): Provider[] {
return [CommandService, actionHandlers.map((handler) => ({ provide: FEATURE_ACTION_HANDLERS, useClass: handler, multi: true }))];
}
@NgModule({})
export class CoreCommandModule {
static forRoot(actionHandlers: Type<ActionHandler>[]): ModuleWithProviders<CoreCommandModule> {
return {
ngModule: CoreCommandModule,
providers: [CommandService, actionHandlers.map((handler) => ({ provide: ROOT_ACTION_HANDLERS, useClass: handler, multi: true }))],
};
}
static forChild(actionHandlers: Type<ActionHandler>[]): ModuleWithProviders<CoreCommandModule> {
return {
ngModule: CoreCommandModule,
providers: [CommandService, actionHandlers.map((handler) => ({ provide: FEATURE_ACTION_HANDLERS, useClass: handler, multi: true }))],
};
}
}

View File

@@ -1,6 +0,0 @@
// start:ng42.barrel
export * from './action-handler.interface';
export * from './command.module';
export * from './command.service';
export * from './tokens';
// end:ng42.barrel

View File

@@ -1,5 +0,0 @@
/*
* Public API Surface of command
*/
export * from './lib';

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/core/config",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,8 +0,0 @@
import { Observable } from 'rxjs';
/**
* Config loader interface for loading configurations
*/
export interface ConfigLoader {
load(): Promise<any>;
}

View File

@@ -1,4 +0,0 @@
// start:ng42.barrel
export * from './config-loader';
export * from './json.config-loader';
// end:ng42.barrel

View File

@@ -1,36 +0,0 @@
// unit test JsonConfigLoader
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { createServiceFactory, SpectatorService } from '@ngneat/spectator';
import { CORE_JSON_CONFIG_LOADER_URL } from '../tokens';
import { JsonConfigLoader } from './json.config-loader';
describe('JsonConfigLoader', () => {
let spectator: SpectatorService<JsonConfigLoader>;
const createService = createServiceFactory({
imports: [HttpClientTestingModule],
service: JsonConfigLoader,
mocks: [],
providers: [{ provide: CORE_JSON_CONFIG_LOADER_URL, useValue: '/assets/config.json' }],
});
let httpTestingController: HttpTestingController;
beforeEach(() => {
spectator = createService();
httpTestingController = spectator.inject(HttpTestingController);
});
it('should create', () => {
expect(spectator.service).toBeTruthy();
});
describe('load', () => {
it('should call the provided url', async () => {
const reqPromise = spectator.service.load();
const req = httpTestingController.expectOne('/assets/config.json');
req.flush({ unit: 'test' });
const result = await reqPromise;
httpTestingController.verify();
expect(result).toEqual({ unit: 'test' });
});
});
});

View File

@@ -1,13 +0,0 @@
import { HttpClient } from '@angular/common/http';
import { Inject, Injectable } from '@angular/core';
import { ConfigLoader } from './config-loader';
import { CORE_JSON_CONFIG_LOADER_URL } from '../tokens';
@Injectable()
export class JsonConfigLoader implements ConfigLoader {
constructor(@Inject(CORE_JSON_CONFIG_LOADER_URL) private url: string, private http: HttpClient) {}
load(): Promise<any> {
return this.http.get(this.url).toPromise();
}
}

View File

@@ -1,7 +0,0 @@
import { Type } from '@angular/core';
import { ConfigLoader } from './config-loaders';
export interface ConfigModuleOptions {
useConfigLoader: Type<ConfigLoader>;
jsonConfigLoaderUrl?: string;
}

View File

@@ -1,28 +0,0 @@
import { APP_INITIALIZER, ModuleWithProviders, NgModule } from '@angular/core';
import { CORE_CONFIG_LOADER } from '@core/config';
import { Config } from './config';
import { ConfigModuleOptions } from './config-module-options';
import { CORE_JSON_CONFIG_LOADER_URL } from './tokens';
export function _initializeConfigFactory(config: Config) {
return () => config.init();
}
@NgModule({})
export class ConfigModule {
static forRoot(options: ConfigModuleOptions): ModuleWithProviders<ConfigModule> {
const configLoaderProvider = {
provide: CORE_CONFIG_LOADER,
useClass: options.useConfigLoader,
};
return {
ngModule: ConfigModule,
providers: [
Config,
configLoaderProvider,
options.jsonConfigLoaderUrl ? { provide: CORE_JSON_CONFIG_LOADER_URL, useValue: options.jsonConfigLoaderUrl } : null,
],
};
}
}

View File

@@ -1,45 +0,0 @@
import { createServiceFactory, SpectatorService } from '@ngneat/spectator';
import { Config } from './config';
import { ConfigLoader } from './config-loaders';
import { CORE_CONFIG_LOADER } from './tokens';
class TestConfigLoader implements ConfigLoader {
load() {
return Promise.resolve({});
}
}
// Unit test Config
describe('Config', () => {
let spectator: SpectatorService<Config>;
const createService = createServiceFactory({
service: Config,
providers: [{ provide: CORE_CONFIG_LOADER, useClass: TestConfigLoader }],
});
let configLoader: ConfigLoader;
beforeEach(() => {
spectator = createService();
configLoader = spectator.inject(CORE_CONFIG_LOADER);
});
it('should create', () => {
expect(spectator.service).toBeTruthy();
});
describe('init()', () => {
it('should load config and assigns it to _config', async () => {
const config = { unit: 'test' };
spyOn(configLoader, 'load').and.returnValue(Promise.resolve(config));
await spectator.service.init();
expect(spectator.service['_config']).toEqual(config);
});
});
describe('get()', () => {
it('should return config value', () => {
spectator.service['_config'] = { test: 'test' };
expect(spectator.service.get('test')).toEqual('test');
});
});
});

View File

@@ -1,27 +0,0 @@
import { Inject, Injectable } from '@angular/core';
import { ReplaySubject } from 'rxjs';
import { ConfigLoader } from './config-loaders';
import { CORE_CONFIG_LOADER } from './tokens';
import { pick } from './utils';
@Injectable()
export class Config {
private _config: any;
private readonly _initilized = new ReplaySubject<void>(1);
get initialized() {
return this._initilized.asObservable();
}
constructor(@Inject(CORE_CONFIG_LOADER) private readonly _configLoader: ConfigLoader) {}
// load config and assign it to this._config
async init() {
this._config = await this._configLoader.load();
this._initilized.next();
}
get(path: string) {
return pick(path, this._config);
}
}

View File

@@ -1,8 +0,0 @@
// start:ng42.barrel
export * from './config-module-options';
export * from './config.module';
export * from './config';
export * from './tokens';
export * from './config-loaders';
export * from './utils';
// end:ng42.barrel

View File

@@ -1,6 +0,0 @@
import { InjectionToken } from '@angular/core';
import { ConfigLoader } from './config-loaders';
export const CORE_CONFIG_LOADER = new InjectionToken<ConfigLoader>('core.config.loader');
export const CORE_JSON_CONFIG_LOADER_URL = new InjectionToken<ConfigLoader>('core.json.config.loader.url');

View File

@@ -1,3 +0,0 @@
// start:ng42.barrel
export * from './pick';
// end:ng42.barrel

View File

@@ -1,41 +0,0 @@
import { pick } from './pick';
describe('pick', () => {
it('should pick properties from the 1st level from the object', () => {
const obj = {
foo: 'bar',
};
expect(pick('foo', obj)).toEqual('bar');
});
it('should pick properties from the 2nd level from the object', () => {
const obj = {
foo: {
bar: 'baz',
},
};
expect(pick('foo.bar', obj)).toEqual('baz');
});
it('should pick properties from the 3rd level from the object', () => {
const obj = {
foo: {
bar: {
baz: 'qux',
},
},
};
expect(pick('foo.bar.baz', obj)).toEqual('qux');
});
it('should throw an error of obj is not an object', () => {
expect(() => pick('foo', 'bar')).toThrowError(`bar is not an object`);
});
it('should return undefined if the property is not found', () => {
const obj = {
foo: 'bar',
};
expect(pick('bar', obj)).toEqual(undefined);
});
});

View File

@@ -1,33 +0,0 @@
/**
* Pick a value from an object at a given path.
* @param path path of the value to pick
* @param obj object to pick from
* @returns the value at the path or undefined
* @throws if obj is not an object
*/
export function pick<T = any>(path: string, obj: Object): T {
const paths = path.split('.');
// check if obj is null or undefined
if (obj == null) {
return undefined;
}
// check if obj is of type object and not an array
// and throw an error if not
if (typeof obj !== 'object' || Array.isArray(obj)) {
throw new Error(`${obj} is not an object`);
}
let result = obj;
// loop through the path and pick the value
// early exit if the path is empty
for (const path of paths) {
result = result[path];
if (result == null) {
return undefined;
}
}
return result as T;
}

View File

@@ -1,5 +0,0 @@
/*
* Public API Surface of config
*/
export * from './lib';

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/core/environment",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,6 +0,0 @@
/*
* Public API Surface of environment
*/
export * from './lib/environment.service';
export * from './lib/environment.module';

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/core/logger",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,8 +0,0 @@
// start:ng42.barrel
export * from './console-log.provider';
export * from './log-level';
export * from './log.provider';
export * from './logger.module';
export * from './logger.service';
export * from './tokens';
// end:ng42.barrel

View File

@@ -1,5 +0,0 @@
/*
* Public API Surface of logger
*/
export * from './lib';

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../dist/core",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,11 +0,0 @@
{
"name": "core",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^15.0.0",
"@angular/core": "^15.0.0"
},
"dependencies": {
"tslib": "^2.3.0"
}
}

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/core/signalr",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,6 +0,0 @@
/*
* Public API Surface of signalr
*/
export * from './lib/signalr-hub-options';
export * from './lib/signalr.hub';

View File

@@ -1,22 +0,0 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CoreComponent } from './core.component';
describe('CoreComponent', () => {
let component: CoreComponent;
let fixture: ComponentFixture<CoreComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [CoreComponent],
}).compileComponents();
fixture = TestBed.createComponent(CoreComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -1,12 +0,0 @@
import { Component } from '@angular/core';
@Component({
selector: 'lib-core',
template: `
<p>
core works!
</p>
`,
styles: [],
})
export class CoreComponent {}

View File

@@ -1,9 +0,0 @@
import { NgModule } from '@angular/core';
import { CoreComponent } from './core.component';
@NgModule({
declarations: [CoreComponent],
imports: [],
exports: [CoreComponent],
})
export class CoreModule {}

View File

@@ -1,16 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { CoreService } from './core.service';
describe('CoreService', () => {
let service: CoreService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(CoreService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -1,8 +0,0 @@
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class CoreService {
constructor() {}
}

View File

@@ -1,7 +0,0 @@
/*
* Public API Surface of core
*/
export * from './lib/core.service';
export * from './lib/core.component';
export * from './lib/core.module';

View File

@@ -1,14 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/lib",
"declaration": true,
"declarationMap": true,
"inlineSources": true,
"types": []
},
"exclude": [
"**/*.spec.ts"
]
}

View File

@@ -1,10 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "./tsconfig.lib.json",
"compilerOptions": {
"declarationMap": false
},
"angularCompilerOptions": {
"compilationMode": "partial"
}
}

View File

@@ -1,14 +0,0 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "../../out-tsc/spec",
"types": [
"jasmine"
]
},
"include": [
"**/*.spec.ts",
"**/*.d.ts"
]
}

View File

@@ -1,25 +0,0 @@
# Availability
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 10.1.2.
## Code scaffolding
Run `ng generate component component-name --project availability` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project availability`.
> Note: Don't forget to add `--project availability` or else it will be added to the default project in your `angular.json` file.
## Build
Run `ng build availability` to build the project. The build artifacts will be stored in the `dist/` directory.
## Publishing
After building your library with `ng build availability`, go to the dist folder `cd dist/availability` and run `npm publish`.
## Running unit tests
Run `ng test availability` to execute the unit tests via [Karma](https://karma-runner.github.io).
## Further help
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md).

View File

@@ -1,7 +0,0 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"dest": "../../../dist/domain/availability",
"lib": {
"entryFile": "src/public-api.ts"
}
}

View File

@@ -1,11 +0,0 @@
{
"name": "@domain/availability",
"version": "0.0.1",
"peerDependencies": {
"@angular/common": "^10.1.2",
"@angular/core": "^10.1.2"
},
"dependencies": {
"tslib": "^2.0.0"
}
}

View File

@@ -1,16 +0,0 @@
import { TestBed } from '@angular/core/testing';
import { DomainAvailabilityService } from './availability.service';
describe('AvailabilityService', () => {
let service: DomainAvailabilityService;
beforeEach(() => {
TestBed.configureTestingModule({});
service = TestBed.inject(DomainAvailabilityService);
});
it('should be created', () => {
expect(service).toBeTruthy();
});
});

View File

@@ -1,605 +0,0 @@
import { Injectable } from '@angular/core';
import { ItemDTO } from '@swagger/cat';
import {
AvailabilityDTO,
BranchDTO,
OLAAvailabilityDTO,
StoreCheckoutBranchService,
StoreCheckoutSupplierService,
SupplierDTO,
} from '@swagger/checkout';
import { BehaviorSubject, combineLatest, Observable, of } from 'rxjs';
import {
AvailabilityRequestDTO,
AvailabilityService,
AvailabilityDTO as SwaggerAvailabilityDTO,
AvailabilityType,
} from '@swagger/availability';
import { AvailabilityDTO as CatAvailabilityDTO } from '@swagger/cat';
import { map, shareReplay, switchMap, withLatestFrom, mergeMap, timeout, first } from 'rxjs/operators';
import { isArray, memorize } from '@utils/common';
import { LogisticianDTO, LogisticianService } from '@swagger/oms';
import { ResponseArgsOfIEnumerableOfStockInfoDTO, StockDTO, StockInfoDTO, StockService } from '@swagger/remi';
import { PriceDTO } from '@swagger/availability';
import { AvailabilityByBranchDTO, ItemData, Ssc } from './defs';
import { Availability } from './defs/availability';
import { isEmpty } from 'lodash';
@Injectable()
export class DomainAvailabilityService {
// Ticket #3378 Keep Result List Items and Details Page SSC in sync
sscs$ = new BehaviorSubject<Array<Ssc>>([]);
sscsObs$ = this.sscs$.asObservable();
constructor(
private _availabilityService: AvailabilityService,
private _logisticanService: LogisticianService,
private _stockService: StockService,
private _supplierService: StoreCheckoutSupplierService,
private _branchService: StoreCheckoutBranchService
) {}
@memorize({ ttl: 10000 })
memorizedAvailabilityShippingAvailability(request: Array<AvailabilityRequestDTO>) {
return this._availabilityService.AvailabilityShippingAvailability(request).pipe(shareReplay(1));
}
@memorize()
getSuppliers(): Observable<SupplierDTO[]> {
return this._supplierService.StoreCheckoutSupplierGetSuppliers({}).pipe(
map((response) => response.result),
shareReplay(1)
);
}
@memorize()
getTakeAwaySupplier(): Observable<SupplierDTO> {
return this._supplierService.StoreCheckoutSupplierGetSuppliers({}).pipe(
map(({ result }) => result?.find((supplier) => supplier?.supplierNumber === 'F')),
shareReplay(1)
);
}
@memorize()
getBranches(): Observable<BranchDTO[]> {
return this._branchService.StoreCheckoutBranchGetBranches({}).pipe(
map((response) => response.result),
shareReplay(1)
);
}
@memorize()
getStockByBranch(branchId: number): Observable<StockDTO> {
return this._stockService.StockGetStocksByBranch({ branchId }).pipe(
map((response) => response.result),
map((result) => result?.find((_) => true)),
shareReplay(1)
);
}
@memorize()
getDefaultStock(): Observable<StockDTO> {
return this._stockService.StockCurrentStock().pipe(
map((response) => response.result),
shareReplay(1)
);
}
@memorize()
getDefaultBranch(): Observable<BranchDTO> {
return this._stockService.StockCurrentBranch().pipe(
map((response) => ({
id: response.result.id,
name: response.result.name,
address: response.result.address,
branchType: response.result.branchType,
branchNumber: response.result.branchNumber,
changed: response.result.changed,
created: response.result.created,
isDefault: response.result.isDefault,
isOnline: response.result.isOnline,
key: response.result.key,
label: response.result.label,
pId: response.result.pId,
shortName: response.result.shortName,
status: response.result.status,
version: response.result.version,
})),
shareReplay(1)
);
}
@memorize({})
getLogisticians(): Observable<LogisticianDTO> {
return this._logisticanService.LogisticianGetLogisticians({}).pipe(
map((response) => response.result?.find((l) => l.logisticianNumber === '2470')),
shareReplay(1)
);
}
getTakeAwayAvailabilityByBranches({
branchIds,
itemId,
price,
quantity,
}: {
branchIds: number[];
itemId: number;
price: PriceDTO;
quantity: number;
}): Observable<AvailabilityByBranchDTO[]> {
return this._stockService.StockStockRequest({ stockRequest: { branchIds, itemId } }).pipe(
map((response) => response.result),
withLatestFrom(this.getTakeAwaySupplier()),
map(([result, supplier]) => {
const availabilities: AvailabilityByBranchDTO[] = result.map((stockInfo) => {
return {
availableQuantity: stockInfo.availableQuantity,
availabilityType: quantity <= stockInfo.inStock ? 1024 : 1, // 1024 (=Available)
inStock: stockInfo.inStock,
supplierSSC: quantity <= stockInfo.inStock ? '999' : '',
supplierSSCText: quantity <= stockInfo.inStock ? 'Filialentnahme' : '',
price,
supplier: { id: supplier?.id },
branchId: stockInfo.branchId,
};
});
return availabilities;
}),
shareReplay(1)
);
}
@memorize({ ttl: 10000 })
getTakeAwayAvailability({
item,
quantity,
branch,
}: {
item: ItemData;
quantity: number;
branch?: BranchDTO;
}): Observable<AvailabilityDTO> {
const request = !!branch ? this.getStockByBranch(branch.id) : this.getDefaultStock();
return request.pipe(
switchMap((s) =>
combineLatest([
this._stockService.StockInStock({ articleIds: [item.itemId], stockId: s.id }),
this.getTakeAwaySupplier(),
this.getDefaultBranch(),
])
),
map(([response, supplier, defaultBranch]) => {
const price = item?.price;
return this._mapToTakeAwayAvailability({ response, supplier, branchId: branch?.id ?? defaultBranch?.id, quantity, price });
}),
shareReplay(1)
);
}
@memorize({ ttl: 10000 })
getTakeAwayAvailabilityByBranch({
branch,
itemId,
price,
quantity,
}: {
branch: BranchDTO;
itemId: number;
price: PriceDTO;
quantity: number;
}): Observable<AvailabilityDTO> {
return combineLatest([
this._stockService.StockStockRequest({ stockRequest: { branchIds: [branch.id], itemId } }),
this.getTakeAwaySupplier(),
]).pipe(
map(([response, supplier]) => {
return this._mapToTakeAwayAvailability({ response, supplier, branchId: branch.id, quantity, price });
}),
shareReplay(1)
);
}
getTakeAwayAvailabilityByEan({
eans,
price,
quantity,
branchId,
}: {
eans: string[];
price: PriceDTO;
quantity: number;
branchId?: number;
}): Observable<AvailabilityDTO> {
const request = !!branchId ? this.getStockByBranch(branchId) : this.getDefaultStock();
return request.pipe(
switchMap((s) => this._stockService.StockInStockByEAN({ eans, stockId: s.id })),
withLatestFrom(this.getTakeAwaySupplier(), this.getDefaultBranch()),
map(([response, supplier, defaultBranch]) => {
return this._mapToTakeAwayAvailability({ response, supplier, branchId: branchId ?? defaultBranch.id, quantity, price });
}),
shareReplay(1)
);
}
getTakeAwayAvailabilitiesByEans({ eans }: { eans: string[] }): Observable<StockInfoDTO[]> {
const eansFiltered = Array.from(new Set(eans));
return this.getDefaultStock().pipe(
switchMap((s) => this._stockService.StockInStockByEAN({ eans: eansFiltered, stockId: s.id })),
withLatestFrom(this.getTakeAwaySupplier(), this.getDefaultBranch()),
map((response) => response[0].result),
shareReplay(1)
);
}
@memorize({ ttl: 10000 })
getPickUpAvailability({
item,
branch,
quantity,
}: {
item: ItemData;
quantity: number;
branch: BranchDTO;
}): Observable<Availability<AvailabilityDTO, SwaggerAvailabilityDTO>> {
return this._availabilityService
.AvailabilityStoreAvailability([
{
qty: quantity,
ean: item?.ean,
itemId: item?.itemId ? String(item?.itemId) : null,
shopId: branch?.id,
price: item?.price,
},
])
.pipe(
map((r) => this._mapToPickUpAvailability(r.result)?.find((_) => true)),
shareReplay(1)
);
}
@memorize({ ttl: 10000 })
getDeliveryAvailability({ item, quantity }: { item: ItemData; quantity: number }): Observable<AvailabilityDTO> {
return this.memorizedAvailabilityShippingAvailability([
{
ean: item?.ean,
itemId: item?.itemId ? String(item?.itemId) : null,
price: item?.price,
qty: quantity,
},
]).pipe(
timeout(5000),
map((r) => this._mapToShippingAvailability(r.result)?.find((_) => true)),
shareReplay(1)
);
}
@memorize({ ttl: 10000 })
getDigDeliveryAvailability({ item, quantity }: { item: ItemData; quantity: number }): Observable<AvailabilityDTO> {
return this.memorizedAvailabilityShippingAvailability([
{
qty: quantity,
ean: item?.ean,
itemId: item?.itemId ? String(item?.itemId) : null,
price: item?.price,
},
]).pipe(
timeout(5000),
map((r) => {
const availabilities = r.result;
const preferred = availabilities?.find((f) => f.preferred === 1);
return {
availabilityType: preferred?.status,
ssc: preferred?.ssc,
sscText: preferred?.sscText,
supplier: { id: preferred?.supplierId },
isPrebooked: preferred?.isPrebooked,
estimatedShippingDate: preferred?.requestStatusCode === '32' ? preferred?.altAt : preferred?.at,
estimatedDelivery: preferred?.estimatedDelivery,
price: preferred?.price,
logistician: { id: preferred?.logisticianId },
supplierProductNumber: preferred?.supplierProductNumber,
supplierInfo: preferred?.requestStatusCode,
lastRequest: preferred?.requested,
priceMaintained: preferred?.priceMaintained,
};
}),
shareReplay(1)
);
}
@memorize({ ttl: 10000 })
getB2bDeliveryAvailability({
item,
quantity,
branch,
}: {
item: ItemData;
quantity: number;
branch?: BranchDTO;
}): Observable<AvailabilityDTO> {
const logistician$ = this.getLogisticians();
const currentBranch$ = this.getDefaultBranch();
return currentBranch$.pipe(
timeout(5000),
mergeMap((defaultBranch) =>
this.getPickUpAvailability({ item, quantity, branch: branch ?? defaultBranch }).pipe(
mergeMap((availability) =>
logistician$.pipe(
map((logistician) => ({ ...(availability?.length > 0 ? availability[0] : []), logistician: { id: logistician.id } }))
)
),
shareReplay(1)
)
)
);
}
@memorize({ ttl: 10000 })
getDownloadAvailability({ item }: { item: ItemData }): Observable<AvailabilityDTO> {
return this.memorizedAvailabilityShippingAvailability([
{
ean: item?.ean,
itemId: item?.itemId ? String(item?.itemId) : null,
price: item?.price,
qty: 1,
},
]).pipe(
map((r) => {
const availabilities = r.result;
const preferred = availabilities?.find((f) => f.preferred === 1);
return {
availabilityType: preferred?.status,
ssc: preferred?.ssc,
sscText: preferred?.sscText,
supplier: { id: preferred?.supplierId },
isPrebooked: preferred?.isPrebooked,
estimatedShippingDate: preferred?.requestStatusCode === '32' ? preferred?.altAt : preferred?.at,
price: preferred?.price,
supplierProductNumber: preferred?.supplierProductNumber,
logistician: { id: preferred?.logisticianId },
supplierInfo: preferred?.requestStatusCode,
lastRequest: preferred?.requested,
priceMaintained: preferred?.priceMaintained,
};
}),
shareReplay(1)
);
}
@memorize({ ttl: 10000 })
getTakeAwayAvailabilities(items: { id: number; price: PriceDTO }[], branchId: number) {
return this._stockService.StockGetStocksByBranch({ branchId }).pipe(
map((req) => req.result?.find((_) => true)?.id),
switchMap((stockId) =>
stockId
? this._stockService.StockInStock({ articleIds: items.map((i) => i.id), stockId })
: of({ result: [] } as ResponseArgsOfIEnumerableOfStockInfoDTO)
),
timeout(20000),
withLatestFrom(this.getTakeAwaySupplier()),
map(([response, supplier]) => {
return response.result?.map((stockInfo) =>
this._mapToTakeAwayAvailabilities({
stockInfo,
supplier,
quantity: 1,
price: items?.find((i) => i.id === stockInfo.itemId)?.price,
})
);
}),
shareReplay(1)
);
}
@memorize({ ttl: 10000 })
getPickUpAvailabilities(payload: AvailabilityRequestDTO[], preferred?: boolean) {
return this._availabilityService.AvailabilityStoreAvailability(payload).pipe(
timeout(20000),
map((response) => (preferred ? this._mapToPickUpAvailability(response.result) : response.result))
);
}
@memorize({ ttl: 10000 })
getDeliveryAvailabilities(payload: AvailabilityRequestDTO[]) {
return this.memorizedAvailabilityShippingAvailability(payload).pipe(
timeout(20000),
map((response) => this._mapToShippingAvailability(response.result))
);
}
@memorize({ ttl: 10000 })
getDigDeliveryAvailabilities(payload: AvailabilityRequestDTO[]) {
return this.memorizedAvailabilityShippingAvailability(payload).pipe(
timeout(20000),
map((response) => this._mapToShippingAvailability(response.result))
);
}
@memorize({ ttl: 10000 })
getB2bDeliveryAvailabilities(payload: AvailabilityRequestDTO[]) {
const logistician$ = this.getLogisticians();
return this.getPickUpAvailabilities(payload, true).pipe(
timeout(20000),
switchMap((availability) =>
logistician$.pipe(map((logistician) => ({ availability: [...availability], logistician: { id: logistician.id } })))
),
shareReplay(1)
);
}
getPriceForAvailability(
purchasingOption: string,
catalogAvailability: CatAvailabilityDTO | AvailabilityDTO,
availability: AvailabilityDTO
): PriceDTO {
switch (purchasingOption) {
case 'take-away':
return availability?.price || catalogAvailability?.price;
case 'delivery':
case 'dig-delivery':
if (catalogAvailability?.price?.value?.value < availability?.price?.value?.value) {
return catalogAvailability?.price;
}
return availability?.price || catalogAvailability?.price;
}
return availability?.price;
}
isAvailable({ availability }: { availability: AvailabilityDTO }) {
if (availability?.supplier?.id === 16 && availability?.inStock == 0) {
return false;
}
return [2, 32, 256, 1024, 2048, 4096].some((code) => availability?.availabilityType === code);
}
private _mapToTakeAwayAvailability({
response,
supplier,
branchId,
quantity,
price,
}: {
response: ResponseArgsOfIEnumerableOfStockInfoDTO;
supplier: SupplierDTO;
branchId: number;
quantity: number;
price: PriceDTO;
}): AvailabilityDTO {
const stockInfo = response.result?.find((si) => si.branchId === branchId);
const inStock = stockInfo?.inStock ?? 0;
const availability: AvailabilityDTO = {
availabilityType: quantity <= inStock ? 1024 : 1, // 1024 (=Available)
inStock: inStock,
supplierSSC: quantity <= inStock ? '999' : '',
supplierSSCText: quantity <= inStock ? 'Filialentnahme' : '',
price: stockInfo?.retailPrice ?? price, // #4553 Es soll nun immer der retailPrice aus der InStock Abfrage verwendet werden, egal ob "price" empty ist oder nicht
supplier: { id: supplier?.id },
// TODO: Change after API Update
// LH: 2021-03-09 preis Property hat nun ein Fallback auf retailPrice
// retailPrice: (stockInfo as any)?.retailPrice,
};
return availability;
}
private _mapToTakeAwayAvailabilities({
stockInfo,
quantity,
price,
supplier,
}: {
stockInfo: StockInfoDTO;
quantity: number;
price: PriceDTO;
supplier: SupplierDTO;
}) {
const inStock = stockInfo?.inStock ?? 0;
const availability = {
itemId: stockInfo.itemId,
availabilityType: quantity <= inStock ? (1024 as AvailabilityType) : (1 as AvailabilityType), // 1024 (=Available)
inStock: inStock,
supplierSSC: quantity <= inStock ? '999' : '',
supplierSSCText: quantity <= inStock ? 'Filialentnahme' : '',
price,
supplier: { id: supplier?.id },
};
return availability;
}
private _mapToPickUpAvailability(availabilities: SwaggerAvailabilityDTO[]): Availability<AvailabilityDTO, SwaggerAvailabilityDTO>[] {
if (isArray(availabilities)) {
const preferred = availabilities.filter((f) => f.preferred === 1);
const totalAvailable = availabilities.reduce((sum, av) => sum + (av?.qty || 0), 0);
return preferred.map((p) => {
return [
{
orderDeadline: p?.orderDeadline,
availabilityType: p?.status,
ssc: p?.ssc,
sscText: p?.sscText,
supplier: { id: p?.supplierId },
isPrebooked: p?.isPrebooked,
estimatedShippingDate: p?.requestStatusCode === '32' ? p?.altAt : p?.at,
price: p?.price,
inStock: totalAvailable,
supplierProductNumber: p?.supplierProductNumber,
supplierInfo: p?.requestStatusCode,
lastRequest: p?.requested,
itemId: p.itemId,
priceMaintained: p.priceMaintained,
},
p,
];
});
}
}
private _mapToShippingAvailability(availabilities: SwaggerAvailabilityDTO[]): AvailabilityDTO[] {
const preferred = availabilities.filter((f) => f.preferred === 1);
return preferred.map((p) => {
return {
availabilityType: p?.status,
ssc: p?.ssc,
sscText: p?.sscText,
isPrebooked: p?.isPrebooked,
estimatedShippingDate: p?.requestStatusCode === '32' ? p?.altAt : p?.at,
estimatedDelivery: p?.estimatedDelivery,
price: p?.price,
supplierProductNumber: p?.supplierProductNumber,
supplierInfo: p?.requestStatusCode,
lastRequest: p?.requested,
itemId: p.itemId,
priceMaintained: p.priceMaintained,
};
});
}
getInStockByEan(params: { eans: string[]; branchId?: number }): Observable<Record<string, StockInfoDTO>> {
let branchId$ = of(params.branchId);
if (!params.branchId) {
branchId$ = this.getDefaultBranch().pipe(
first(),
map((b) => b.id)
);
}
const stock$ = branchId$.pipe(
mergeMap((branchId) => this._stockService.StockGetStocksByBranch({ branchId }).pipe(map((response) => response.result?.[0])))
);
return stock$.pipe(
mergeMap((stock) =>
this._stockService.StockInStockByEAN({ eans: params.eans, stockId: stock.id }).pipe(
map((response) => {
const result = response.result ?? [];
for (const stockInfo of result) {
stockInfo.ean = stockInfo.ean;
}
return result.reduce<Record<string, StockInfoDTO>>((acc, stockInfo) => {
acc[stockInfo.ean] = stockInfo;
return acc;
}, {});
})
)
)
);
}
getInStock({ itemIds, branchId }: { itemIds: number[]; branchId: number }): Observable<StockInfoDTO[]> {
return this.getStockByBranch(branchId).pipe(
mergeMap((stock) =>
this._stockService.StockInStock({ articleIds: itemIds, stockId: stock.id }).pipe(map((response) => response.result))
)
);
}
}

View File

@@ -1,7 +0,0 @@
import { AvailabilityDTO } from '@swagger/checkout';
export interface AvailabilityByBranchDTO extends AvailabilityDTO {
availableQuantity?: number;
stockId?: number;
branchId: number;
}

View File

@@ -1,7 +0,0 @@
import { PriceDTO } from '@swagger/availability';
export interface ItemData {
ean: string;
itemId: number;
price: PriceDTO;
}

View File

@@ -1,121 +0,0 @@
import { Injectable } from '@angular/core';
import { StockInfoDTO } from '@swagger/remi';
import { groupBy, isEqual, uniqWith } from 'lodash';
import { BehaviorSubject, combineLatest, Observable, Subject } from 'rxjs';
import { buffer, debounceTime, distinctUntilChanged } from 'rxjs/operators';
import { DomainAvailabilityService } from './availability.service';
export type ItemBranch = { itemId: number; branchId: number };
export type InStock = ItemBranch & { inStock: number; fetching: boolean };
@Injectable({ providedIn: 'root' })
export class DomainInStockService {
private _inStockQueue = new Subject<ItemBranch>();
private _inStockMap = new BehaviorSubject<Record<string, number>>({});
private _inStockFetchingMap = new BehaviorSubject<Record<string, boolean>>({});
constructor(private _availability: DomainAvailabilityService) {
const queueBufferTrigger = this._createQueueBufferTrigger();
this._inStockQueue.pipe(buffer(queueBufferTrigger)).subscribe(this._handleStockDataToFetch);
}
private _createQueueBufferTrigger() {
return this._inStockQueue.pipe(debounceTime(1000));
}
private _handleStockDataToFetch = (itemBranchData: ItemBranch[]) => {
const unique = uniqWith(itemBranchData, isEqual);
if (unique?.length > 0) {
this._fetchStockData(unique);
}
};
getKey({ itemId, branchId }: ItemBranch) {
return `${itemId}_${branchId}`;
}
getInStock$({ itemId, branchId }: ItemBranch): Observable<InStock> {
return new Observable<InStock>((obs) => {
if (!(itemId && branchId)) {
obs.error(new Error(`ItemId: ${itemId} or BranchId: ${branchId} missing`));
return;
}
const key = this.getKey({ itemId, branchId });
this._addToInStockQueue({ itemId, branchId });
let _previousValue: InStock;
const sub = combineLatest([this._inStockMap, this._inStockFetchingMap])
.pipe(distinctUntilChanged(isEqual))
.subscribe(([inStockMap, inStockFetchingMap]) => {
const inStock: InStock = {
itemId,
branchId,
inStock: inStockMap[key],
fetching: inStockFetchingMap[key] ?? false,
};
if (!isEqual(inStock, _previousValue)) {
obs.next(inStock);
}
_previousValue = inStock;
});
return () => {
sub.unsubscribe();
};
});
}
private _addToInStockQueue({ itemId, branchId }: ItemBranch): void {
this._inStockQueue.next({ itemId, branchId });
this._setInStockFetching({ itemId, branchId }, true);
}
private _setInStockFetching({ itemId, branchId }: ItemBranch, value: boolean) {
const key = this.getKey({ itemId, branchId });
const current = this._inStockFetchingMap.getValue();
this._inStockFetchingMap.next({ ...current, [key]: value });
}
private _setInStock({ itemId, branchId }: ItemBranch, inStock: number) {
const key = this.getKey({ itemId, branchId });
const current = this._inStockMap.getValue();
this._inStockMap.next({ ...current, [key]: inStock });
}
private _fetchStockData(itemBranchData: ItemBranch[]) {
const grouped = groupBy(itemBranchData, 'branchId');
Object.keys(grouped).forEach((key) => {
const branchId = Number(key);
const itemIds = itemBranchData.filter((itemBranch) => itemBranch.branchId === branchId).map((item) => item.itemId);
this._availability
.getInStock({ itemIds, branchId })
.subscribe(this._fetchStockDataResponse({ itemIds, branchId }), this._fetchStockDataError({ itemIds, branchId }));
});
}
private _fetchStockDataResponse = ({ itemIds, branchId }: { itemIds: number[]; branchId: number }) => (stockInfos: StockInfoDTO[]) => {
itemIds.forEach((itemId) => {
const stockInfo = stockInfos.find((stockInfo) => stockInfo.itemId === itemId && stockInfo.branchId === branchId);
let inStock = 0;
if (stockInfo?.inStock) {
inStock = stockInfo.inStock;
}
this._setInStockFetching({ itemId, branchId }, false);
this._setInStock({ itemId, branchId }, inStock);
});
};
private _fetchStockDataError = ({ itemIds, branchId }: { itemIds: number[]; branchId: number }) => (error: Error) => {
itemIds.forEach((itemId) => {
this._setInStockFetching({ itemId, branchId }, false);
this._setInStock({ itemId, branchId }, 0);
});
console.error('DomainInStockService._fetchStockData()', error);
};
}

View File

@@ -1,8 +0,0 @@
/*
* Public API Surface of availability
*/
export * from './lib/availability.service';
export * from './lib/in-stock.service';
export * from './lib/availability.module';
export * from './lib/defs';

Some files were not shown because too many files have changed in this diff Show More