Bump version to 0.27.0
This commit is contained in:
@@ -4,6 +4,105 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
|
||||
## [0.27.0] - 2026-09-29
|
||||
|
||||
### Added
|
||||
- `Modules\Core\Shipping\Contracts\SupportsCashCollection` — a shipping driver
|
||||
implements this to say a person is physically present at handoff to collect
|
||||
cash. `AcsRateDriver` implements it (a courier can); `BoxNowRateDriver` and
|
||||
the new `StorePickupRateDriver` don't (an unattended locker or a store
|
||||
clerk deciding to accept cash isn't the same fact as a courier collecting
|
||||
it on delivery). `Modules\Core\Checkout\Services\CheckoutService::
|
||||
getPaymentMethods()` now checks this for cash-on-delivery specifically, so
|
||||
COD is no longer offered alongside Box Now — `RequiresFulfillmentType`
|
||||
alone couldn't distinguish "an unattended carrier" from "an attended one,"
|
||||
both being `carrier`.
|
||||
- `Modules\Core\Shipping\Carriers\StorePickup\StorePickupRateDriver` — a
|
||||
first-party replacement for `lunarphp/table-rate-shipping`'s own
|
||||
`Collection` driver, following the same shape as `AcsRateDriver`/
|
||||
`BoxNowRateDriver`. Fixes two bugs the vendor driver had: it read
|
||||
`ShippingMethod->name` directly instead of decoding the translatable JSON
|
||||
column, so the storefront showed the raw JSON blob instead of a
|
||||
translated name; and it never checked product exclusions the same way
|
||||
the vendor's own generic drivers did.
|
||||
- `Modules\Core\Shipping\Concerns\ExcludesRestrictedProducts` — shared
|
||||
product-exclusion check (a shipping zone's configured "this product can't
|
||||
ship via this method" list), now applied consistently by every
|
||||
first-party driver (ACS, Box Now, Store Pickup). Previously only Lunar's
|
||||
own generic drivers honored exclusions at all — ACS and Box Now silently
|
||||
ignored them.
|
||||
- `Modules\Core\Localization\Database\Seeders\StorefrontTranslationsSeeder`
|
||||
— the `storefront` translation group is now seeded the same way
|
||||
`checkout`/`validation` already are (a dedicated, idempotent seeder run
|
||||
from the entrypoint), rather than as a private method inside
|
||||
`InstallLunarCommand`. `Modules\Core\Localization\Services\
|
||||
StorefrontLabels` is removed; its ~160 lines moved into the new seeder.
|
||||
- `StoreDetailsService::bankTransferInstructionsFor()` — sanitized HTML for
|
||||
a bank transfer order's confirmation email, gated on
|
||||
`OrderStatusFlow::isBankTransfer()`.
|
||||
- `StoreServiceProvider::applyMailFromName()` — listens for
|
||||
`Illuminate\Mail\Events\MessageSending` and renames the From header's
|
||||
display name to Store Details' `mail_from_name`, when set, for every
|
||||
outgoing email app-wide (order notifications, OTP codes, contact form
|
||||
confirmations, etc.), no per-mailable changes needed. Only touches a
|
||||
message whose From address still matches `config('mail.from.address')`
|
||||
— the sending address itself is untouched (a deliverability/domain-
|
||||
authentication concern, not a merchant-editable text field), and a
|
||||
mailable/notification that already set its own explicit sender is left
|
||||
alone entirely.
|
||||
- `Order.meta['locale']` — the shopper's locale at checkout, saved by
|
||||
`CheckoutService::initiatePayment()` so every order notification renders
|
||||
in the locale they actually checked out in (via `Notification::locale()`
|
||||
in `NotificationRegistry::register()`), independent of whatever locale
|
||||
happens to be active when the notification is actually sent (a payment
|
||||
webhook, a queued job, a staff action).
|
||||
- `Order.meta['coupon_code']` — copied from the cart at checkout, so the
|
||||
confirmation email always shows the code the order was actually placed
|
||||
with, rather than reading the cart row (which may since have been
|
||||
cleared/reused).
|
||||
- Contact details on the storefront and product confirmation emails now
|
||||
accept `$order` directly (all 8 order notification views), removing two
|
||||
workarounds: `placed.blade.php` no longer reaches the order through
|
||||
`$lines->first()->order`, and `status-updated.blade.php` no longer
|
||||
reverse-searches a status key from its English label.
|
||||
|
||||
### Changed
|
||||
- The vendor's own generic shipping drivers (`free-shipping`, `flat-rate`,
|
||||
`ship-by`, `collection`) are no longer offered at all — every shipping
|
||||
method now uses a first-party driver (ACS, Box Now, or Store Pickup),
|
||||
each of which declares its own fulfillment type. The `data.fulfillment_type`
|
||||
Select on the shipping method form is removed, along with the
|
||||
merchant-facing fallback it existed for — every registered driver now
|
||||
hardcodes this fact about itself rather than a merchant configuring it
|
||||
per row.
|
||||
- `OrderCapturedNotification` ("payment captured") no longer sends for any
|
||||
payment method except bank transfer. For every other method, placing the
|
||||
order and paying for it are the same moment from the shopper's
|
||||
perspective — `OrderPlacedNotification` already covers it. Bank transfer
|
||||
is the one case where payment confirmation is a genuine, later, separate
|
||||
event (staff marking the order paid once the wire arrives).
|
||||
- `OrderStatusUpdatedNotification` no longer sends for an order's first
|
||||
transition off `awaiting_payment`, except for a bank transfer order —
|
||||
for every other payment method that transition happens in the same
|
||||
request as checkout itself, so it's not new information the shopper
|
||||
hasn't already been told.
|
||||
- `OrderStatusUpdatedNotification`'s subject line now names the order's
|
||||
actual current status ("Your order :reference is now :status") instead
|
||||
of a generic "has been updated."
|
||||
- The checkout page's payment methods now refresh live when the shipping
|
||||
option changes, instead of requiring a full page reload — switching to
|
||||
store pickup correctly drops cash-on-delivery and offers "pay in store"
|
||||
immediately.
|
||||
|
||||
### Fixed
|
||||
- `StoreDetailsService::bankTransferInstructionsFor()` returned the raw
|
||||
Tiptap JSON array `bank_transfer_instructions` is stored as, instead of
|
||||
rendering it to HTML — the order confirmation email for a bank transfer
|
||||
order failed outright (`TypeError`, queued job marked `FAIL`) rather than
|
||||
showing the store's payment instructions. Now converts via Filament's own
|
||||
`RichContentRenderer`, the same converter the admin panel itself uses to
|
||||
render a `RichEditor` field's content read-only.
|
||||
|
||||
## [0.26.5] - 2026-09-28
|
||||
|
||||
### Added
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
"name": "boboko/core",
|
||||
"description": "Core module — authentication and shared panel behaviour",
|
||||
"type": "library",
|
||||
"version": "0.26.5",
|
||||
"version": "0.27.0",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Modules\\Core\\": "src/"
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@boboko/core",
|
||||
"version": "0.26.5",
|
||||
"version": "0.27.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"description": "Portable Stimulus controllers and styles for boboko-core's cart + checkout module. Installed as a real npm dependency (file:../boboko-core in dev, a tagged git install in prod) so a consuming app's `npm install` resolves this package's own dependencies (leaflet, @hotwired/stimulus) transitively, the same way `composer update boboko/*` does for PHP. See CONTRIBUTE.md's \"JS/CSS: a real npm package\" section.",
|
||||
|
||||
Reference in New Issue
Block a user