- Added dark mode support to admin panel. remp/crm#3620
- Added dark/light mode toggle button in admin navbar. Theme preference is persisted in localStorage.
- Implemented comprehensive dark mode CSS with Bootstrap 3 overrides for all UI components.
- Added dark mode support for Select2, jQuery UI, Google Charts, and DateTimePicker plugins.
- Added ability to set flatpickr date format in admin js, through
flatpickr_dateformat html attribute. remp/crm#3526
- Added global AJAX form button handling to disable/enable submit buttons during AJAX form submissions. remp/crm#3611
- Fixed snippet sorting validation to prevent server error on empty input. remp/crm#3577
- Added option to redact extra fields in the API logger (defaults are
password, auth and token). remp/crm#3667
- Added JSON payload redaction in the API logger. remp/crm#3667
- Changed
Content-Type header handling so it retrieves correct content type even when parameters are used in the header’s value. remp/crm#3667
- Added empty handling of
PRICE_INCREASE server to server notification.
- This kind of notification should be handled by updating the mapping in
apple_appstore_subscription_types to the subscription type with higher price.
- BREAKING: Use of
FilterLoader to register Latte filters is not available anymore due to changes Latte 3.1.
- To register custom Latte filters, register them directly into Latte:
services:
nette.latteFactory:
setup:
- addFilter('your_filter', [Crm\YourModule\Helpers\YourFilter(), process])
Signature of addFilter function is the same as previously used FilterLoader::register. Class FilterLoader is now removed.
- DEPRECATED: Deprecated
Crm\ApplicationModule\Models\Request::getDomain in favor of Crm\ApplicationModule\Models\Request::getCookieDomain. remp/crm#3630
- If you used
getDomain method, it should be safe for you to replace it with getCookieDomain.
- Upgraded
phpoffice/phpspreadsheet library to v5. remp/crm#3613
- Added AJAX pagination system for widgets. remp/crm#3511
- Added
AjaxDataPaginator component with loading states and smart page range calculation.
- Added
PaginatedComponent interface and PaginatesDataTrait for reusable pagination.
- Added option to configure cookie domain for
applicationRequest service to force custom cookie domain instead of resolved one. remp/crm#3630
- Resolving wouldn’t work correctly with multi-level TLDs (.co.uk, .com.ua) or in case you need stored cookies on the subdomain.
- Use DI’s
setup directive with setCookieDomain() call to configure custom cookie domain.
- Fixed internation phone number pattern not validating Dutch phone numbers. remp/helpdesk#4150
- Added index for
table_name column in audit_logs table. remp/crm#3664
- Changed
DonateSubscription and subscription event handlers to allow subscription types outside of family_subscription_types. remp/crm#3589
- Subscription has to have generated master family requests instead of checking if subscription type is in
family_subscription_types.
- Changed
SubscriptionShortenedHandler and SubscriptionUpdatedHandler event handlers.
- Changed master family subscription widget to display any master subscriptions, not just the ones with subscription type defined in
family_subscription_types table. remp/helpdesk#3957
- Filter expired subscriptions without any accepted family requests. remp/helpdesk#3964
- Changed
IsFamilyMasterCriteria scenario criteria to check if subscription is master family using family_requests instead of family_subscription_types. remp/crm#3586
- Added ability to set donated subscriptions
isPaid through slave subscription type meta. remp/crm#3599
- Added
IsSubscriptionPausableDataProvider data provider which makes sure we do not pause family subscriptions. remp/crm#3605
- Added widget to payment details page showing child subscription activation status. remp/crm#3607
- Added new notification types to the recognized enum. remp/dn-mofa#598
- Updated
CreateMissingRecurrentPaymentsCommand to use ChainData for determining chain tracking data. remp/crm#3530
- Added beneficiary to invoices and proforma invoices. remp/crm#3612
- This field is now required by all EU banks and if user fills incorrect name, bank requires manual confirmation / override from user.
- Company name (
supplier_name) from config (/admin/config - invoices section) is used (same as for invoices).
- Added icon configuration for invoice addresses in
UserAddressListWidget. remp/crm#3511
- Added information that existing invoices will not change when changing the billing address. remp/helpdesk#3867
- Note: Invoice can be regenerated by support (see quick actions for payment).
- Added
companyId as the new parameter of function VatValidatorService::validateVatId(). remp/crm#3504
- Service of Czech financial administration requires company ID (IČO) instead of VAT ID.
- Changed visibility of first name and last name in the admin form if the fields are set (e.g. by import). remp/respekt#472
- Added config value for the threshold of reactivation recurrent payments stopped by system. remp/novydenik#1494
- Added beneficiary to bank transfer payment screen. remp/crm#3612
- This field is now required by all EU banks and if user fills incorrect name, bank requires manual confirmation / override from user.
- Company name (
supplier_name) from config (/admin/config - invoices section) is used (same as for invoices).
- Refactored
UserPaymentsListing to use AJAX pagination. remp/crm#3511
- Component now supports multiple independent paginators (payments table and recurrent payments table).
- Added ability to pause active subscription. remp/crm#3526
- Added
PauseSubscriptionWidget widget for pausing active subscriptions from user subscriptions listing.
- Added
IsSubscriptionPausableDataProviderInterface interface for implementing custom pausable validation logic.
- Added
PauseSubscriptionHandler hermes handler for pausing subscriptions asynchronously.
- Added
SubscriptionPausedEvent league event which fires after subscription is paused.
- Added
SubscriptionPauser service which handles pausing subscription logic.
- Added
allow_pause_subscriptions application config flag to enable/disable pausing subscriptions globally.
- Added
subscription_pauses table and corresponding SubscriptionPausesRepository for storing subscription pause records.
- Added subscription ends notification suppression when pausing subscription. remp/crm#3526
- Added
chain_id and cycle columns to recurrent_payments table for tracking recurrent payment chains. remp/crm#3530
- Added
ChainData value object for encapsulating chain tracking logic.
- Added
payments:fill_recurrent_chain_tracking command to backfill existing recurrent payments with chain data.
- Command can run for extended time on large datasets; recommended to run during off-peak hours.
- Changed items in subscription type select inputs to unified admin-wide format.
- Added icon configuration for print addresses in
UserAddressListWidget. remp/crm#3511
- Changed
AddressRedirectWidget button styling to compact size for inline display in UserAddressListWidget. remp/crm#3511
- Changed condition blocking (soft) delete of a print address when a redirect from another address exists. remp/novydenik#1415
CanDeleteAddressDataProvider was checking all redirects. It should check only active redirects (where the to date is in the future).
- Frequent use of redirects by user accounts can lead to too many temporary addresses. This fix now allows for the removal of these temporary addresses.
- Fixed OSS country resolution when shipping country is set. remp/helpdesk#4014
- Improved performance of calculation of most sold products. remp/crm#3577
- Changed related products sorting to prioritize recently sold items. remp/crm#3577
- Products with sales in last 3 months are shown first by popularity.
- Falls back to newest products when insufficient sold items found.
- Related products now filtered by matching tags for better relevance.
- Fixed checkout form preventing order completion when One Stop Shop was disabled. remp/crm#357
- Changed
ProductsRepository::relatedProducts() to filter related products by user-assignable tags only. remp/crm#3577
- Added scenario criteria for checking number of subscribed newsletters in selected categories. remp/crm#3647
- Added
ScenarioDuplicator for creating scenario copies with regenerated UUIDs. remp/crm#3611
- Added index to
scenarios_element_stats.created_at to improves stats aggregation performance.
- Changed
segments.query_string column type from TEXT to MEDIUMTEXT to support larger static segments. remp/crm#3640
- Updated Composer library from v7 to v18.
- Added instant refund for the Stripe payment gateway. remp/crm#3604
- Changed subscription types
trial_periods column to nullable. remp/crm#3315
- Added migration for fixing null and zero values in
trial_periods if next_subscription_type_id is filled in.
- Added min value validation for
trial_periods in SubscriptionTypesFormFactory. remp/crm#3315
- Number of trial periods can only be set when next subscription type is selected, and when selected, it’s required.
- Refactored
UserSubscriptionsListing to use AJAX pagination. remp/crm#3511
- Fixed
trial_periods not being saved when creating new subscription type. remp/crm#3562
- Fixed content access removal when editing subscription types. remp/crm#3591
- Fixed trial periods labels wording on the subscription type admin pages.
- Added audit log for
SubscriptionTypeItemsRepository (subscription_type_items table). remp/crm#3660
- BREAKING: Removed condition requiring the stored card to expire in more than 31 days in order to allow
PaidRecurrentUpgrade use. remp/helpdesk#3984
- This was an arbitrary decision we made in the past and it stuck there. Upgrade should be generally available for everyone requesting it, we recommend to handle possibly needed change of card via scenarios.
- BREAKING: Removed
nextSubscriptionType property and getter from UpgraderTrait. remp/helpdesk#3880
- Fixed
PaidRecurrentWidget and FreeRecurrentWidget to resolve next subscription type using RecurrentPaymentsResolver. remp/helpdesk#3880
- Added emission of
BeforeResolveSubscriptionTypeEvent before attempt to resolve the target subscription type. remp/crm#3618
- This adds an option to conditionally use your own resolve logic if you need to.
- Removed value of
custom_amount in TrialUpgrade - it generated recurrent payments with wrong price. remp/crm#3594
- BREAKING: Removed pre-populating of first name and last name in user’s address form in admin. remp/crm#3624
- BREAKING: Removed token auth source metadata from
/api/v1/user/info API handler. remp/crm#3663
- If you need to extend the API handler with extra data, extend/override it with your own handler instead.
- Added claim unclaimed user in
RegisterFormFactory. remp/helpdesk#4008
- Added
UserAddressListWidget component for user detail pages. remp/crm#3511
- You can configure address type icons and visibility via
UserAddressListConfig.
- Displays user addresses with configurable icons per address type.
- Added “Load more” functionality via AJAX for additional addresses.
- Fixed
UserAddressListWidget to support module widget injection via simpleWidget placeholder. remp/crm#3511
- Removed
AddressWidget registration from admin.user.address.partial placeholder. remp/crm#3511
- Prevents duplicate address rendering in
UserAddressListWidget.
- Changed
UserAddressListWidget to sort addresses by type with default addresses at the top of each type group. remp/crm#3511
- Addresses are now sorted by type, then by default status within type, then by creation date (newest first).
- Added fallback to display 3 newest addresses when no always-visible address types are configured.
- Added flag
with_uuid to /api/v1/users/list API to include uuid in response data. remp/crm#3617
- Added user data cache (Redis) as a source of data for
/api/v1/user/info API handler. remp/crm#3663
- If there’s nothing stored in cache, handler uses DB (former implementation) as a fallback.
- Changed how (when) information about the last user login is stored. remp/crm#3665
- Affected database columns:
users.current_sign_in_at and users.current_sign_in_ip.
- Previously, storing this data was the responsibility of each implementation of
AuthenticatorInterface.
- Now, the information is stored whenever the event
Crm\UsersModule\Events\UserSignInEvent is emitted. This event is emitted by UserAuthenticator upon successful authentication and is handled by event handler Crm\UsersModule\Events\SignEventHandler.
- Removed direct calls to the
addSignIn() from the authenticators AutoLoginAuthenticator and UsernameAuthenticator.
- Fixed possible user ID type inconsistency during SSO login. remp/crm#3670
- Removed storing of sign-in details (date & IP). This is now handled by event handler within UsersModule. remp/crm#3665