Make Iranian Rial (IRR) the sole base currency for shipping rates:
- RateImportService now converts all imported rates to IRR at import
time using the current daily exchange rate (source currency AED/USD/
EUR/IRR). Rates are stored in rate_entries with currency='IRR'.
- PriceCalculatorService looks up IRR rates directly — no conversion
at calc time. Also fixes a pre-existing bug where extras (in IRR)
were incorrectly added to the AED base before conversion.
- RateEntry::lookup() default currency changed from 'AED' to 'IRR'.
- Migration changes the column default to 'IRR'.
- Filament import form: relabel 'Rate currency' to 'Source currency
(in Excel file)' with helper text explaining the conversion.
- WordPress JS: update price summary labels from 'درهم' to 'ریال'
and drop the deprecated net_dirham field.
Architectural benefit: rates are 'frozen' in IRR at import time —
daily exchange rate changes only affect NEW imports, not already-
stored rates. This is more stable and predictable for customers.
Restore the array-based signature of PriceCalculatorService::calculate()
to fix the TypeError thrown when PricingController and CustomerOrderController
called it with an array (the previous commit had switched to 4 separate
string params without updating the callers).
- PriceCalculatorService: support multiple input formats for direction
(export|import|Outbound|Inbound) and type (DOC_NORMAL|DOC_ECONOMY|PARCEL|
DOCUMENT|NON DOC) for backward compatibility with admin and customer flows.
- ExchangeRateService: add convertToIrr() for explicit AED→IRR conversion
(was missing but referenced by the calculator).
- PricingController: expand validation rules to accept new shipment types
and a discount_code string (was 'discount' numeric). Add 3-layer exception
handling (422 validation / 400 business / 500 server).
- PriceTestPage: compute volumetric weight from dimensions (IATA: L×W×H/5000),
resolve destination country by direction, and show errors as Filament
notifications instead of crashing.
Implement a new pricing architecture based on a 4-quadrant model (Export/Import
x Document/Non-Document) to replace the previous 2-zone model. This includes
the ability to handle different zones for parcels and documents per country.
- Add `RateEntry` and `CountryZone` models for managing complex rate matrices.
- Implement `RateImportService` to parse Excel templates using PhpSpreadsheet.
- Add `RateImportResource` in Filament for administrative rate uploads.
- Refactor `PriceCalculatorService` to utilize the new 4-quadrant lookup logic.
- Add database migrations to extend `rate_entries` and create `country_zones`.
- Update `DEPLOYMENT.md` with new architectural details and deployment steps.
Refactor the currency management system to eliminate the redundant
`rate_to_aed` field and transition to a single-base model where all
rates are stored relative to the Iranian Rial (IRR).
Key changes:
- Removed `rate_to_aed` from `currencies` table via new migration.
- Updated `ExchangeRateService` to handle rates using a single
`currency_code` parameter instead of currency pairs.
- Refactored `UpdateExchangeRates` command to fetch rates from the
Exir.io API and support multiple currencies (AED, USD, EUR, CNY).
- Updated Filament resources (`CurrencyResource`,
`ExchangeRateHistoryResource`) and widgets to reflect the new
single-base architecture.
- Improved `PriceCalculatorService` to use the updated service
methodology for fetching the AED/IRR conversion rate.
- Localized console command output to Persian.
Implement additional address and identification fields for both sender
and receiver across the WordPress plugin and Laravel API. This includes
state, postal code, and national ID/passport information.
Key changes:
- Added database migration to include postal and national ID fields in
the shipments table.
- Updated WordPress order form shortcodes and JavaScript to capture
new address fields.
- Refactored Laravel `CustomerOrderController` validation and storage
to support expanded shipment data.
- Implemented tiered data visibility in `TrackController` to protect
PII, providing masked data to anonymous users and full data to
owners/admins.
- Fixed weight-based rate lookup logic in `PriceCalculatorService` to
correctly select the appropriate shipping tier.
Migrate exchange rate handling from static system settings to a
centralized `ExchangeRateService`. This change ensures that currency
rates are managed through a single source of truth that supports
history tracking, approval workflows, and API updates.
Laravel:
- Remove manual exchange rate fields (`aed_to_irr`, `usd_to_irr`, etc.)
from `IfnexSettingsPage` and the `SystemSetting` persistence logic.
- Update `PricingPageController` and `PriceCalculatorService` to
retrieve live rates from `ExchangeRateService` instead of `SystemSetting`.
- Refactor `IfnexSettingsPage` UI to display current rates as
read-only information with a link to the dedicated exchange rate
management resource.
Documentation:
- Update `CLIENT_DELIVERY.md` to reflect the change in exchange rate
management workflow.
Introduces a complete shipment review system allowing staff to request
changes to customer orders and customers to resubmit corrected orders.
- Add `ReviewState` enum and `ShipmentReview` model to track review history.
- Implement `ShipmentReviewService` to handle approval and change
request logic.
- Add `resubmit` endpoint for customers to update orders when
`changes_requested` state is active.
- Add `request-changes` endpoint for staff to flag orders for correction.
- Update `ShipmentResource` in Filament to display review states and
manage approvals.
- Implement WordPress bridge support for fetching and resubmitting
orders via AJAX.
- Add database migrations for `shipment_reviews` table and `review_state`
column on shipments.
- Add `StaffApiMiddleware` to secure staff-specific API routes.
Refactor the pricing calculation service and shipping rate import logic to improve consistency and reliability. This includes updating direction naming conventions, enhancing model casting, and adding comprehensive test suites.
- Update `ShippingRatesImport` to use 'outbound' and 'inbound' instead of 'export' and 'import'
- Refactor `PriceCalculatorService` to use a more modular calculation structure
- Update `ShippingRate` model to use explicit property casting for zones
- Add `HasFactory` trait to `Country` and `ShippingRate` models
- Add new database factories for `Country` and `ShippingRate`
- Implement new feature tests for API endpoints and service logic
- Add new service tests for `PriceCalculatorService`
Implement the core logic for applying discount codes during price
calculation and introduce the WalletService. This includes updating
the PriceCalculatorService to validate and apply discounts,
incrementing usage counts, and adding a Filament resource for
managing discount codes via the admin panel.
Additionally, refactor TrackingDataImport to use OnEachRow for better
memory management during large Excel imports.
Refactor the shipping rate import process to support bidirectional
data handling (import/export) and implement currency conversion using
system settings. Update the price calculator to ensure valid zone
data is retrieved.
- Update `ShippingRatesImport` to handle both import and export
directions via `SimpleRateSheetImport`.
- Implement AED to IRR conversion during rate importation using
`SystemSetting`.
- Add validation for zone numbers and rate values during import.
- Enhance `PriceCalculatorService` to filter for non-zero zone values.
- Add various debug and testing scripts for pricing and data
structure verification.