PHPackages                             azaharizaman/nexus-sales - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. azaharizaman/nexus-sales

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

azaharizaman/nexus-sales
========================

Framework-agnostic sales management package for quotation-to-order lifecycle

v0.1.0-alpha1(1mo ago)002MITPHPPHP ^8.3

Since May 5Pushed 1mo agoCompare

[ Source](https://github.com/azaharizaman/nexus-sales)[ Packagist](https://packagist.org/packages/azaharizaman/nexus-sales)[ RSS](/packages/azaharizaman-nexus-sales/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (1)Versions (2)Used By (2)

Nexus\\Sales
============

[](#nexussales)

Framework-agnostic sales management package for quotation-to-order commercial contract lifecycle.

Overview
--------

[](#overview)

`Nexus\Sales` manages the complete sales process from quotation to order fulfillment, including:

- **Sales Quotations**: Price quotes with validity periods and versioning
- **Sales Orders**: Confirmed customer orders with payment terms and fulfillment tracking
- **Pricing Engine**: Multi-strategy pricing (list price, tiered discounts, customer-specific, promotional)
- **Tax Calculation**: Pluggable tax calculation interface
- **Exchange Rate Locking**: Foreign currency order protection
- **Stock Reservation**: Real-time inventory integration with automatic reservation
- **Invoice Generation**: Seamless integration with accounts receivable
- **Credit Limit Checking**: Real-time customer credit validation
- **Sales Returns (RMA)**: Return order processing and validation

Key Features
------------

[](#key-features)

### 1. Quotation-to-Order Workflow

[](#1-quotation-to-order-workflow)

```
DRAFT → SENT → ACCEPTED → CONVERTED_TO_ORDER
              ↓         ↓
           REJECTED  EXPIRED

```

Sales Order Workflow:

```
DRAFT → CONFIRMED → PARTIALLY_SHIPPED → FULLY_SHIPPED → INVOICED → PAID
                 ↓
             CANCELLED

```

### 2. Pricing Strategies

[](#2-pricing-strategies)

- **List Price**: Standard price list pricing
- **Tiered Discount**: Quantity-based pricing tiers (matrix pricing foundation)
- **Customer-Specific**: Customer-negotiated pricing
- **Promotional**: Time-sensitive promotional campaigns

### 3. Integrated Services

[](#3-integrated-services)

The package includes the following production-ready services:

ServicePurposeIntegration[`QuoteToOrderConverter`](#quotetoorderconverter)Converts accepted quotes to sales ordersNexus\\Sequencing[`SalesOrderManager`](#salesordermanager)Full order lifecycle managementAll packages[`ReceivableCreditLimitChecker`](#receivablecreditlimitchecker)Real-time credit limit validationNexus\\Receivable[`SalesReturnManager`](#salesreturnmanager)Return order (RMA) processingNexus\\Receivable (Phase 2)[`InventoryStockReservation`](#inventorystockreservation)Real-time stock reservationNexus\\Inventory[`ReceivableInvoiceManager`](#receivableinvoicemanager)Invoice generation from ordersNexus\\Receivable### 4. Future-Proof Architecture

[](#4-future-proof-architecture)

V1 includes schema fields for Phase 2 features:

- **Recurring Subscriptions**: `is_recurring`, `recurrence_rule` (JSON)
- **Sales Commission**: `salesperson_id`, `commission_percentage`
- **Multi-Warehouse**: `preferred_warehouse_id`

All V1 stub implementations provide clear upgrade paths.

Installation
------------

[](#installation)

```
composer require azaharizaman/nexus-sales
```

Dependencies
------------

[](#dependencies)

- `azaharizaman/nexus-party` - Customer management
- `azaharizaman/nexus-product` - Product catalog
- `azaharizaman/nexus-uom` - Unit of measurement
- `azaharizaman/nexus-currency` - Multi-currency support
- `azaharizaman/nexus-finance` - Accounting integration
- `azaharizaman/nexus-sequencing` - Auto-numbering
- `azaharizaman/nexus-period` - Fiscal period management
- `azaharizaman/nexus-audit-logger` - Audit trail
- `azaharizaman/nexus-inventory` - Stock management (for InventoryStockReservation)
- `azaharizaman/nexus-receivable` - Accounts receivable (for credit checking and invoicing)

Architecture
------------

[](#architecture)

This package follows the **Nexus Atomic Package Pattern**:

- **NO Laravel dependencies** - Pure PHP 8.3
- **NO database schema** - Contracts only
- **NO Eloquent models** - Entity interfaces only
- **Framework-agnostic** - Can run in any PHP application

Implementation is provided by `apps/Atomy` (Laravel orchestrator).

Quick Start Guide
-----------------

[](#quick-start-guide)

### Step 1: Create a Quotation

[](#step-1-create-a-quotation)

```
use Nexus\Sales\Services\QuotationManager;

// Inject via constructor
public function __construct(
    private readonly QuotationManager $quotationManager
) {}

// Create quotation
$quotation = $this->quotationManager->createQuotation(
    tenantId: 'tenant-123',
    customerId: 'customer-456',
    lines: [
        [
            'product_variant_id' => 'variant-789',
            'quantity' => 10,
            'uom_code' => 'EA',
        ]
    ],
    data: [
        'quote_date' => new DateTimeImmutable(),
        'valid_until' => new DateTimeImmutable('+30 days'),
        'currency_code' => 'MYR',
        'prepared_by' => 'user-id',
    ]
);
```

### Step 2: Convert Quote to Order

[](#step-2-convert-quote-to-order)

```
use Nexus\Sales\Services\QuoteToOrderConverter;

$order = $this->converter->convertToOrder(
    quotationId: 'quote-id',
    orderData: [
        'payment_term' => \Nexus\Sales\Enums\PaymentTerm::NET_30,
        'shipping_address' => '123 Main St',
        'customer_po' => 'PO-12345',
    ]
);
```

### Step 3: Confirm Order

[](#step-3-confirm-order)

The confirmation process performs three critical operations:

1. **Credit Limit Check** - Validates customer has sufficient credit
2. **Stock Reservation** - Reserves inventory for the order
3. **Exchange Rate Lock** - Locks foreign currency rate (if applicable)

```
use Nexus\Sales\Services\SalesOrderManager;

$this->salesOrderManager->confirmOrder(
    orderId: 'order-id',
    confirmedBy: 'user-id'
);
```

### Step 4: Generate Invoice

[](#step-4-generate-invoice)

```
$invoiceId = $this->salesOrderManager->generateInvoice(
    orderId: 'order-id'
);
```

Service Reference
-----------------

[](#service-reference)

### QuoteToOrderConverter

[](#quotetoorderconverter)

Converts accepted quotations to sales orders, copying all line items, pricing, and customer information.

**Location:** `src/Services/QuoteToOrderConverter.php`

**Constructor Dependencies:**

- `QuotationRepositoryInterface`
- `SalesOrderRepositoryInterface`
- `SequenceGeneratorInterface`
- `TransactionManagerInterface`
- `AuditLogManagerInterface`
- `LoggerInterface`

**Methods:**

MethodDescription`convertToOrder(string $quotationId, array $orderData = []): SalesOrderInterface`Converts accepted quote to order`canConvertToOrder(string $quotationId): bool`Validates if quote can be converted### SalesOrderManager

[](#salesordermanager)

Manages the complete sales order lifecycle including creation, confirmation, shipping, invoicing, and cancellation.

**Location:** `src/Services/SalesOrderManager.php`

**Constructor Dependencies:**

- `SalesOrderRepositoryInterface`
- `SequenceGeneratorInterface`
- `ExchangeRateServiceInterface`
- `CreditLimitCheckerInterface`
- `StockReservationInterface`
- `InvoiceManagerInterface`
- `AuditLogManagerInterface`
- `LoggerInterface`

**Methods:**

MethodDescription`createOrder(string $tenantId, string $customerId, array $lines, array $data): SalesOrderInterface`Creates a new draft order`confirmOrder(string $orderId, string $confirmedBy): void`Confirms order, checks credit, reserves stock`cancelOrder(string $orderId, ?string $reason = null): void`Cancels order and releases stock`markAsShipped(string $orderId, bool $isPartialShipment = false): void`Marks order as shipped`generateInvoice(string $orderId): string`Generates invoice from order`findOrder(string $orderId): SalesOrderInterface`Finds order by ID`findOrdersByCustomer(string $tenantId, string $customerId): array`Finds orders by customer### ReceivableCreditLimitChecker

[](#receivablecreditlimitchecker)

Integrates with Nexus\\Receivable for real-time credit limit validation.

**Location:** `src/Services/ReceivableCreditLimitChecker.php`

**Constructor Dependencies:**

- `Nexus\Receivable\Contracts\CreditLimitCheckerInterface`
- `LoggerInterface`

**Methods:**

MethodDescription`checkCreditLimit(string $tenantId, string $customerId, float $orderTotal, string $currencyCode): bool`Validates customer credit limit**Throws:** `CreditLimitExceededException` when limit exceeded

### SalesReturnManager

[](#salesreturnmanager)

Handles return order (RMA) processing including validation and quantity checks.

**Location:** `src/Services/SalesReturnManager.php`

**Constructor Dependencies:**

- `SalesOrderRepositoryInterface`
- `LoggerInterface`

**Methods:**

MethodDescription`createReturnOrder(string $salesOrderId, array $returnLineItems, string $returnReason): string`Creates return order### InventoryStockReservation

[](#inventorystockreservation)

Integrates with Nexus\\Inventory for real-time stock reservation.

**Location:** `src/Services/InventoryStockReservation.php`

**Constructor Dependencies:**

- `SalesOrderRepositoryInterface`
- `Nexus\Inventory\Contracts\ReservationManagerInterface`
- `Nexus\Inventory\Contracts\StockLevelRepositoryInterface`
- `LoggerInterface`

**Methods:**

MethodDescription`reserveStockForOrder(string $salesOrderId): array`Reserves stock for all order lines`releaseStockReservation(string $salesOrderId): void`Releases all reservations`getOrderReservations(string $salesOrderId): array`Gets active reservations`checkStockAvailability(string $salesOrderId): StockAvailabilityResult`Checks availability without reserving**Throws:** `InsufficientStockException` when stock unavailable

### ReceivableInvoiceManager

[](#receivableinvoicemanager)

Integrates with Nexus\\Receivable for invoice generation.

**Location:** `src/Services/ReceivableInvoiceManager.php`

**Constructor Dependencies:**

- `SalesOrderRepositoryInterface`
- `Nexus\Receivable\Contracts\ReceivableManagerInterface`
- `LoggerInterface`

**Methods:**

MethodDescription`generateInvoiceFromOrder(string $salesOrderId): string`Generates invoice from sales orderPricing Engine
--------------

[](#pricing-engine)

### Matrix Pricing (Quantity Tiers)

[](#matrix-pricing-quantity-tiers)

The pricing engine supports quantity-based tiered pricing via dedicated `price_tiers` table:

```
// Example: Volume discount structure
// 1-99 units: $10.00 each
// 100-499 units: $9.50 each
// 500+ units: $9.00 each

$price = $this->pricingEngine->getPrice(
    tenantId: 'tenant-123',
    productVariantId: 'variant-789',
    quantity: new Quantity(250, 'EA'), // Returns $9.50
    currencyCode: 'MYR'
);
```

Performance: SQL-based tier matching enables efficient queries:

```
SELECT unit_price
FROM price_tiers
WHERE price_list_item_id = ?
  AND ? >= min_quantity
  AND (max_quantity IS NULL OR ? app->singleton(TaxCalculatorInterface::class, function () {
    return new SimpleTaxCalculator(
        logger: app(LoggerInterface::class),
        defaultTaxRate: 6.0 // 6% SST for Malaysia
    );
});
```

Exchange Rate Locking
---------------------

[](#exchange-rate-locking)

For foreign currency orders, the exchange rate is locked at **confirmation time**:

```
// Order created in USD (exchange rate not yet locked)
$order = $this->salesOrderManager->createOrder(...);
// exchange_rate = NULL

// Order confirmed (exchange rate locked)
$this->salesOrderManager->confirmOrder($order->getId(), 'user-id');
// exchange_rate = 4.75 (locked at current rate)

// Rate changes in market, but order is unaffected
// Prevents currency fluctuation risk
```

Integration Points
------------------

[](#integration-points)

### Stock Reservation (Nexus\\Inventory)

[](#stock-reservation-nexusinventory)

Production-ready via `InventoryStockReservation`:

```
$this->app->singleton(
    StockReservationInterface::class,
    InventoryStockReservation::class
);
```

### Invoice Generation (Nexus\\Receivable)

[](#invoice-generation-nexusreceivable)

Production-ready via `ReceivableInvoiceManager`:

```
$this->app->singleton(
    InvoiceManagerInterface::class,
    ReceivableInvoiceManager::class
);
```

### Credit Limit Checking (Nexus\\Receivable)

[](#credit-limit-checking-nexusreceivable)

Production-ready via `ReceivableCreditLimitChecker`:

```
$this->app->singleton(
    CreditLimitCheckerInterface::class,
    ReceivableCreditLimitChecker::class
);
```

Discount Rules
--------------

[](#discount-rules)

Time-sensitive promotional pricing:

```
use Nexus\Sales\ValueObjects\DiscountRule;
use Nexus\Sales\Enums\DiscountType;

$discountRule = new DiscountRule(
    type: DiscountType::PERCENTAGE,
    value: 15.0,
    minQuantity: 50,
    validFrom: new DateTimeImmutable('2024-12-01'),
    validUntil: new DateTimeImmutable('2024-12-31')
);

// Check if discount is currently active
if ($discountRule->isCurrentlyValid()) {
    // Apply discount
}

// Check at specific date
if ($discountRule->isValidAt(new DateTimeImmutable('2024-12-15'))) {
    // Discount was/will be active
}
```

Payment Terms
-------------

[](#payment-terms)

Standard payment terms with automatic due date calculation:

```
use Nexus\Sales\Enums\PaymentTerm;

$orderDate = new DateTimeImmutable('2024-12-01');

PaymentTerm::NET_30->calculateDueDate($orderDate); // 2024-12-31
PaymentTerm::NET_45->calculateDueDate($orderDate); // 2025-01-15
PaymentTerm::DUE_ON_RECEIPT->calculateDueDate($orderDate); // 2024-12-01

// Custom payment term (e.g., NET 7)
PaymentTerm::CUSTOM->calculateDueDate($orderDate, 7); // 2024-12-08
```

Exception Handling
------------------

[](#exception-handling)

All domain exceptions extend `SalesException`:

```
use Nexus\Sales\Exceptions\{
    QuotationNotFoundException,
    SalesOrderNotFoundException,
    DuplicateQuoteNumberException,
    DuplicateOrderNumberException,
    InsufficientStockException,
    CreditLimitExceededException,
    InvalidQuoteStatusException,
    InvalidOrderStatusException,
    PriceNotFoundException,
    ExchangeRateLockedException
};

try {
    $this->salesOrderManager->confirmOrder($orderId, $userId);
} catch (CreditLimitExceededException $e) {
    // Handle credit limit exceeded
} catch (InsufficientStockException $e) {
    // Handle out of stock
} catch (SalesException $e) {
    // Handle generic sales error
}
```

Audit Trail
-----------

[](#audit-trail)

All state changes are logged via `Nexus\AuditLogger`:

- Quotation sent to customer
- Quotation accepted/rejected
- Quotation converted to order
- Order confirmed (with locked exchange rate)
- Order shipped (partial/full)
- Order invoiced
- Order cancelled
- Return order created
- Stock reserved/released

Example audit log entry:

```
Event: order_confirmed
Description: Sales order SO-2024-001 confirmed by user-123
Metadata: {"order_number":"SO-2024-001","exchange_rate":4.75,"confirmed_by":"user-123"}

```

Testing
-------

[](#testing)

```
# Run package tests
composer test

# Run with coverage
composer test -- --coverage
```

Future Enhancements (Phase 2)
-----------------------------

[](#future-enhancements-phase-2)

1. **Recurring Subscriptions**

    - Use `is_recurring` and `recurrence_rule` fields
    - Automatic renewal order generation
    - Subscription lifecycle management
2. **Sales Commission**

    - Track salesperson via `salesperson_id`
    - Calculate commission via `commission_percentage`
    - Commission payout integration
3. **Multi-Warehouse Fulfillment**

    - Route orders via `preferred_warehouse_id`
    - Split shipments across warehouses
    - Warehouse selection optimization
4. **Advanced Tax Engine**

    - Tax jurisdiction determination
    - Multi-level tax (federal + state)
    - Tax exemption certificates
    - Reverse charge mechanism
5. **Advanced Sales Returns**

    - Credit note integration with Nexus\\Receivable
    - Restocking fee calculation
    - Return quality inspection workflow

📖 Documentation
---------------

[](#-documentation)

### Package Documentation

[](#package-documentation)

- [Getting Started Guide](docs/getting-started.md)
- [API Reference](docs/api-reference.md)
- [Integration Guide](docs/integration-guide.md)
- [Examples](docs/examples/)

### Additional Resources

[](#additional-resources)

- `IMPLEMENTATION_SUMMARY.md` - Implementation progress
- `REQUIREMENTS.md` - Requirements
- `TEST_SUITE_SUMMARY.md` - Tests
- `VALUATION_MATRIX.md` - Valuation

License
-------

[](#license)

MIT License - see LICENSE file for details.

Support
-------

[](#support)

For issues and questions, please use the GitHub issue tracker.

###  Health Score

35

—

LowBetter than 77% of packages

Maintenance93

Actively maintained with recent releases

Popularity0

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity34

Early-stage or recently created project

 Bus Factor1

Top contributor holds 76.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

36d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/117408?v=4)[Azahari Zaman](/maintainers/azaharizaman)[@azaharizaman](https://github.com/azaharizaman)

---

Top Contributors

[![azaharizaman](https://avatars.githubusercontent.com/u/117408?v=4)](https://github.com/azaharizaman "azaharizaman (470 commits)")[![Copilot](https://avatars.githubusercontent.com/in/1143301?v=4)](https://github.com/Copilot "Copilot (139 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")

### Embed Badge

![Health badge](/badges/azaharizaman-nexus-sales/health.svg)

```
[![Health](https://phpackages.com/badges/azaharizaman-nexus-sales/health.svg)](https://phpackages.com/packages/azaharizaman-nexus-sales)
```

###  Alternatives

[symfony/lock

Creates and manages locks, a mechanism to provide exclusive access to a shared resource

515135.1M619](/packages/symfony-lock)[matomo/matomo

Matomo is the leading Free/Libre open analytics platform

21.6k38.2k](/packages/matomo-matomo)[phpro/soap-client

A general purpose SoapClient library

8955.9M52](/packages/phpro-soap-client)[ecotone/ecotone

Enterprise architecture layer for Laravel and Symfony — CQRS, Event Sourcing, Durable Workflows (Sagas, Orchestrators), Projections, and Outbox messaging via PHP attributes.

562565.8k41](/packages/ecotone-ecotone)[civicrm/civicrm-core

Open source constituent relationship management for non-profits, NGOs and advocacy organizations.

744284.3k34](/packages/civicrm-civicrm-core)[illuminate/broadcasting

The Illuminate Broadcasting package.

7126.9M199](/packages/illuminate-broadcasting)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
