> **DEPRECATED — UI IA archive only.**  
> Do **not** implement from this document. The living roadmap and Phase 1 structural work live in  
> [`sales_estimate_vue_refactor_specification.md`](./sales_estimate_vue_refactor_specification.md).  
> This file is retained as a historical record of the create-page layout / IA that the Vue shell must match.

---

# Technical & Design Specification: Sales Estimate Creation Interface
**Document Version:** 1.1 (archived)  
**Status:** DEPRECATED  
**Target Module:** `Modules/Sales`  
**Primary Target View:** `Modules/Sales/Resources/views/estimates/create.blade.php`  
**Follow-on Views (after create is proven):** `edit.blade.php`, `clone.blade.php`  
**Associated Stylesheet:** Minimal `public/assets/css/custom/estimates/estimate-modern.css` (grid / tabs / shell only); prefer existing VOM tokens and utility classes in Blade  
**Design Standard:** [VOM Frontend Style Guide v1.1](../design/VOM_Style_Guide.md) (Vue 3 · Blade · Tailwind CSS v4 Tokens · RTL-First Arabic)  
**Authority:** Superseded by the Vue refactor spec. Exploratory mock screens are non-binding.

---

## 0. Locked Delivery Decisions

1. **Layout / IA only** — no backend or save-semantics changes. Submit contract stays `action=save` | `save_new` | print via `is_print`, plus existing fiscal-year modals.
2. **Create first** — implement and validate create in local phases **1a–1d**; that is the first PR scope. Edit/clone is follow-on (decide while implementing; not required to merge create). Phases are validation checkpoints, not separate PRs.
3. **Vue children hard-frozen** — do not change `<create-estimate-component>`, `<customers-dropdown-component>`, `<attachments-component>`, `<rich-text-editor-component>`, or `<x-date-picker>` sources. Blade/CSS/page JS only.
4. **Draft badge** = **pre-persist UI state** on create (not an `EstimateStatusEnum` value). Domain statuses remain expired / active / planned / invoiced.
5. **Actions** reuse global `.headBtns` / `.fixed-btns` with the **existing Save icon dropdown** (+ back). In-page title row holds title + code + draft badge (hybrid Zone 1).
6. **Overview rail (Phase 1)** = metadata only (code, live dates, draft). Financial totals stay inside the products card; live rail money is deferred.
7. **Collateral** = tabbed Attachments · Terms · Notes (+ conditional custom fields). Attachments do not live on the context rail.

---

## 1. Executive Summary & Objective

This specification details the architecture, visual layout, data bindings, user interactions, and technical contract for modernizing the **Sales Estimate form** (create first; edit/clone follow) in VOM.

### Primary Goals:
1. **Ergonomic Workflow:** Separate high-frequency transactional data entry (products, dates, customer) from reference information (alerts, customer balance, document overview), eliminating visual clutter.
2. **Hybrid Title + Fixed Actions:** In-page title row (title, code, pre-persist draft) plus primary actions on the existing `.fixed-btns` / `.headBtns` **Save icon dropdown** (+ back) — same submit wiring as today.
3. **Dedicated Context Rail (RTL Left):** Alerts, non-interactive document overview (metadata), and customer identity/balance telemetry — no action buttons, no attachments.
4. **Focused Transactional Canvas (RTL Right):** Schedule/customer/description, line items, and tabbed collateral (attachments, terms, notes).
5. **Zero Backend Disruption:** 100% backward-compatible with Laravel estimate store/update and existing Vue child components (frozen for Phase 1).

---

## 2. Layout Blueprint & Wireframe

The interface layout follows an **Asymmetric 2-Column Split** (`~32%` Context Rail on the RTL leading side, `~68%` Transaction Canvas on the RTL trailing side), with a **non-sticky in-page title row** and **global fixed action buttons**.

```
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│  TITLE ROW (in-page, non-sticky)                                                                        │
│  [عرض سعر جديد]  [# QT-00012]  [مسودة / pre-persist draft]                                               │
│  Actions: existing .fixed-btns Save dropdown · Back  (not a sticky full-width action bar)               │
├────────────────────────────────────────┬────────────────────────────────────────────────────────────────┤
│                                        │                                                                │
│  ┌──────────────────────────────────┐  │  ┌──────────────────────────────────────────────────────────┐  │
│  │               ALERTS             │  │  │                    FORMS DATA FIELDS                     │  │
│  │  (Validation, Quota, Past Dates) │  │  │  (Customer, Issue Date, Due Date, Description)           │  │
│  └──────────────────────────────────┘  │  └──────────────────────────────────────────────────────────┘  │
│                                        │                                                                │
│  ┌──────────────────────────────────┐  │  ┌──────────────────────────────────────────────────────────┐  │
│  │     OVERVIEW WITHOUT ACTIONS     │  │  │                      PRODUCTS TABLE                      │  │
│  │  (Ref Code, Dates, Draft)        │  │  │   (<create-estimate-component> + in-card totals)          │  │
│  │  [Phase 1: no live money totals] │  │  │                                                          │  │
│  └──────────────────────────────────┘  │  └──────────────────────────────────────────────────────────┘  │
│                                        │                                                                │
│  ┌──────────────────────────────────┐  │  ┌──────────────────────────────────────────────────────────┐  │
│  │           CUSTOMER DATA          │  │  │ [ATTACHMENTS]  │ [TERMS]  │ [NOTES]  │ [CUSTOM?]         │  │
│  │  (Avatar, Name, Balance, Phone)  │  │  │ Active Tab Panel Content                                 │  │
│  └──────────────────────────────────┘  │  └──────────────────────────────────────────────────────────┘  │
│                                        │                                                                │
└────────────────────────────────────────┴────────────────────────────────────────────────────────────────┘
```

### Grid Dimensions & Responsiveness:
- **Desktop (`>= 1200px`):** Title row spans the content width. Main content splits into `col-xl-4` (Context Rail) and `col-xl-8` (Transaction Canvas).
- **Laptop / Small Desktop (`992px - 1199px`):** Splits into `col-lg-4` and `col-lg-8`.
- **Tablet & Mobile (`< 992px`):** Flex stacks vertically. Transaction Canvas renders on top (`order-1`), followed by Context Rail (`order-2`), ensuring data entry is prioritized on small touch screens.

---

## 3. Structural Zone Specifications

### Zone 1: `title & actions` (Hybrid — in-page title + `.fixed-btns`)
Split presentation: document identity in-page; actions stay on the global fixed-actions pattern already used by estimate create.

* **Title row (in-page, non-sticky):**
  - Prefer VOM token / utility classes for surface, border, radius, and padding.
  - **Page Title:** `<h1>` label `@lang('sales::estimates.new_estimate')` (edit/clone use their existing titles when adapted).
  - **Estimate Code Pill:** `# {{ $data['new_estimates_code'] }}` (or existing estimate code on edit).
  - **Status Badge:** Pre-persist draft on create (`@lang('Draft')` / مسودة). On edit/clone, show the estimate’s real domain status — not “draft” unless the document is still unsaved.
* **Actions (`.headBtns` / `.fixed-btns`):**
  - **Keep the existing Save icon dropdown** plus back/cancel control (Phase 1). Do not expand to a row of labeled save buttons in 1a–1d unless revisited later.
  - Reuse existing markup/JS hooks (`enhance-submit-action`, `dev-action-holder`, fiscal-year modals, `printClick`, double-submit disable).
  - Dropdown items map to current contract:
    - **Save & Close** → `action = save`
    - **Save & New** → `action = save_new`
    - **Save & Print** → `is_print = 1` + `action = save`
    - **Back / Cancel** → estimates index
  - Restyle lightly within the fixed-btns pattern if needed; do not introduce a second sticky command system that fights `mainStyle.css`.

---

### Zone 2: `alerts` (Context Rail — Top Card)
A dedicated container housing all conditional alerts, quota warnings, and validation error messages without disrupting form inputs.

* **Triggers & Content:**
  1. **Validation Error Summary:** Renders `@include('companyuser::errors.lists')` when form validation fails upon POST.
  2. **Subscription / Estimate Quota Limit:** Displays `@error('remaining')` in an error-tinted banner (`var(--color-error-tint)` with `var(--color-error)` border and text) if tenant has exceeded allowed estimate count.
  3. **Fiscal Year Warning Notice:** If the selected issue date precedes the company's active fiscal year start date, an alert notifies the user that a confirmation modal will be triggered on save.
* **Styling:**
  - Card container with `var(--radius-lg)`, padding `var(--space-4)`, subtle border.
  - Automatically collapses to `display: none` when no active alerts, warnings, or errors are present.

---

### Zone 3: `overview without actions` (Context Rail — Middle Card)
A clean, read-only document metadata widget. **Explicitly excludes action buttons** (actions live in `.fixed-btns`).

* **Visual Design:**
  - Standard card with header: icon `fa-info-circle`, title: `@lang('sales::estimates.estimate_overview')`.
  - Key-value row layout with subtle dashed or hairline dividers (`var(--color-border)`).
* **Displayed Telemetry (Phase 1):**
  - **الرقم المرجعي (Reference Code):** `# {{ $data['new_estimates_code'] }}`.
  - **تاريخ الإصدار (Issue Date):** Live-bound to date picker input (defaults to today's date formatted `YYYY-MM-DD`).
  - **تاريخ الاستحقاق (Due Date):** Live-bound to due date picker input.
  - **حالة المستند (Document Status):** Pre-persist draft pill on create; domain status on edit.
* **Deferred (post–Phase 1):** Live Subtotal / VAT / Grand Total on the rail. Money remains authoritative inside `<create-estimate-component>` until a later emit/DOM-sync pass.

---

### Zone 4: `customer data` (Context Rail — Bottom Card)
A reactive customer intelligence card that populates automatically when a customer is selected in the main form.

* **Visual Design:**
  - Card with header: icon `fa-user-circle-o`, title: `@lang('sales::estimates.customer_details')`.
  - Surface background: `var(--color-surface)` (`#F8FAFC`) with smooth border.
* **Component Elements:**
  - **Avatar Initial Badge:** 44px circular container (`--radius-full`) with teal tint background (`rgba(37, 179, 149, 0.12)`) displaying the first letter of the customer's legal name in bold teal.
  - **Customer Name:** Bold 14px text `#customer-name` (defaults to `@lang('sales::estimates.please_select_customer')`).
  - **Customer Type / Status:** Badge displaying "حساب تجاري" or "حساب فردي" / "Active Account".
  - **Contact Links:**
    - Phone: Click-to-call link (`href="tel:..."`) with `fa-phone` icon.
    - Email: Click-to-email link (`href="mailto:..."`) with `fa-envelope` icon.
  - **الرصيد الحالي (Current Balance):** Prominent monetary badge:
    - Neutral/Green when `balance >= 0`.
    - Warning/Red tint when `balance < 0` (Customer has outstanding debit).
* **Reactivity Hook:**
  - Reuse existing `@change` / `@mounted` → `handleCustomerChange` on `<customers-dropdown-component>`. Do not add a MutationObserver unless that hook proves insufficient.

---

### Zone 5: `forms data fields` (Transactional Canvas — Top Card)
The primary transaction parameters card positioned at the top of the main canvas.

* **Visual Design:**
  - Card container with `var(--radius-lg)`, padded at `var(--space-6)` (24px).
  - Header: Icon `fa-sliders`, title: `@lang('sales::estimates.estimate_details')`.
* **Field Grid Structure (Row 1 — 3 or 4 Columns):**
  1. **العميل (Customer Selector - 40% width):**
     - Vue Component: `<customers-dropdown-component>`.
     - Features: Searchable, remote pagination, `:create-new="true"` with quick-modal trigger, required field indicator (`*`).
  2. **تاريخ الإصدار (Issue Date - 30% width):**
     - Blade Component: `<x-date-picker name="issue_date">`.
     - Default: Current system date (`\App\Services\Date::now('date')`).
  3. **تاريخ الاستحقاق (Due Date - 30% width):**
     - Blade Component: `<x-date-picker name="due_date">`.
     - Default: Issue date or +30 days terms.
* **Field Grid Structure (Row 2 — 100% width):**
  - **الوصف / الملاحظات العامة (Description / Subject):**
    - Textarea with `maxlength="500"`, `rows="2"`.
    - Integrated character counter pill (`<span id="descCharCount">0</span>/500`) floated on the label line.
    - Placeholder: `@lang('sales::estimates.description_placeholder')`.

---

### Zone 6: `products table` (Transactional Canvas — Middle Card)
The core financial engine and multi-line item table for products and services.

* **Visual Design:**
  - Full card container spanning the canvas.
  - Edge-to-edge table presentation adhering to VOM Style Guide §4.2 (table borders align with card boundary; no artificial nested padding wrapper).
* **Vue Component Integration:**
  - Mounts `<create-estimate-component>`.
* **Features & Columns:**
  1. **بند المنتج / الخدمة (Item Selection):** Dropdown supporting inventory products, service items, and recipe bundles, with integrated "إضافة منتج جديد" modal trigger.
  2. **الوصف (Item Description):** Editable line description.
  3. **الكمية (Quantity):** Numerical stepper with minimum quantity alerts and negative inventory warnings.
  4. **سعر الوحدة (Unit Price):** Money input with currency symbol.
  5. **الخصم (Discount):** Toggleable flat amount or percentage discount per line.
  6. **نسبة الضريبة (VAT %):** Selectable tax rate (15% standard, zero-rated, exempt).
  7. **قيمة الضريبة (VAT Value):** Auto-calculated read-only figure.
  8. **الإجمالي شامل الضريبة (Gross Amount):** Auto-calculated total.
  9. **إجراءات (Row Action):** Delete line button (`fa-trash-o`).
* **Auxiliary Sections Inside Card:**
  - **حالة الضريبة (Tax Mode Selector):** Exclusive (`EXCLUSIVE`), Inclusive (`INCLUSIVE`), or No Taxes (`NO_TAXES`).
  - **رسوم أخرى (Other Fees):** Quick link/create for shipping fees, handling, or customs.
  - **Financial Summary Block:** Subtotal, discount total, tax summary by rate, and final Grand Total.

---

### Zone 7: `[attachments] [terms] [notes]` (Transactional Canvas — Bottom Tabbed Card)
A compact segmented tab card replacing tall, vertically stacked accordions.

* **Visual Design:**
  - Outer card container with clean segmented tab bar header:
    - Tab Bar: Background `var(--color-surface)`, radius `var(--radius-md)`, inline padding `4px`.
    - Tab Buttons: `vom-seg-tab-btn` with smooth active transition, active state styled with `var(--color-background)`, `var(--color-primary)` text, and `var(--shadow-sm)`.
* **Tab Items:**
  1. **Tab 1: المرفقات (`attachments`):**
     - Icon: `fa-paperclip`.
     - Content: `<attachments-component>` drag-and-drop zone with preloaded file previews, max file size validation (10MB), and file type badges.
  2. **Tab 2: الشروط والأحكام (`terms`):**
     - Icon: `fa-gavel`.
     - Content: `<rich-text-editor-component name="terms">` preloaded with default estimate terms from `$data['terms']`.
  3. **Tab 3: الملاحظات (`notes`):**
     - Icon: `fa-pencil-square-o`.
     - Content: `<rich-text-editor-component name="notes">` preloaded with `$data['notes']`.
  4. **Tab 4 (Conditional): الحقول الإضافية (`custom fields`):**
     - Displayed only if `($data['customFields'])->count() > 0`.
     - Icon: `fa-sliders`, count badge tag.
     - Content: Dynamic grid of custom text, date, and checkbox fields.

---

## 4. Technical Contract & Backend Compatibility

### HTTP Endpoint & Method:
- **Route:** `route('company.estimates.store', $subdomain)`
- **HTTP Method:** `POST`
- **Content-Type:** `multipart/form-data`
- **CSRF Protection:** `@csrf` hidden token included.

### Payload Parameter Dictionary:

| Parameter Name | Type | Presence | Description / Validation |
| :--- | :--- | :--- | :--- |
| `_token` | `string` | Mandatory | CSRF Token verification |
| `code` | `string` | Mandatory | Estimate reference code (`$data['new_estimates_code']`) |
| `customer_id` | `integer` | Mandatory | Foreign key of selected customer (`required, exists:customers,id`) |
| `issue_date` | `date` | Mandatory | Date of quote issuance (`required, date_format:Y-m-d`) |
| `due_date` | `date` | Mandatory | Quote expiration date (`required, date_format:Y-m-d, after_or_equal:issue_date`) |
| `description` | `string` | Optional | Overall quote summary (`max:500`) |
| `products` | `array` | Mandatory | Line items array from `<create-estimate-component>` |
| `products.*.product_id` | `integer`| Mandatory | Item ID |
| `products.*.quantity` | `numeric`| Mandatory | Quantity ordered (`min:0.01`) |
| `products.*.unit_price` | `numeric`| Mandatory | Unit price before tax |
| `products.*.discount` | `numeric`| Optional | Discount amount |
| `products.*.tax_id` | `integer`| Mandatory | Tax rule ID |
| `other_fees` | `array` | Optional | Additional linked fees payload |
| `custom_fields` | `array` | Optional | Dynamic custom field key-value pairs |
| `terms` | `string` | Optional | HTML / Rich text terms and conditions |
| `notes` | `string` | Optional | HTML / Rich text customer notes |
| `attachments` | `file[]` | Optional | Uploaded files via `<attachments-component>` |
| `form_design_id` | `integer` | Mandatory | Invoice/estimate PDF print design template ID |
| `action` | `string` | Mandatory | Submission trigger: `'save'`, `'save_new'`, or `'save_print'` |
| `remaining` | `integer` | Mandatory | Hidden quota balance validation check |
| `is_print` | `boolean` | Optional | Set to `1` when `Save & Print` is selected |

---

## 5. Client-Side Lifecycle & Interactivity

```mermaid
sequenceDiagram
    autonumber
    actor User as Salesperson
    participant UI as Estimate Page
    participant CustDrop as Customer Dropdown
    participant CustCard as Customer Data Card
    participant DatePick as Date Pickers
    participant Modal as Fiscal Year Modal
    participant Backend as Laravel Backend

    User->>CustDrop: Selects Customer
    CustDrop->>UI: Triggers @change (customer object)
    UI->>CustCard: Updates Avatar, Name, Phone, Email & Balance
    
    User->>DatePick: Modifies Issue Date
    UI->>UI: Recalculates if date < fiscal_year
    
    User->>UI: Clicks "حفظ وإغلاق" (Save & Close)
    alt Date is in Past Fiscal Year
        UI->>Modal: Opens #favoritesModalForSaveAndClose
        User->>Modal: Clicks "متابعة" (Continue)
        Modal->>Backend: Submits Form (action="save")
    else Normal Date
        UI->>Backend: Submits Form (action="save")
    end
    
    Backend-->>UI: 302 Redirect to Estimates Index / Print View
```

### Event Handling Logic:
1. **Customer card:**
   - Reuse the existing page-level `handleCustomerChange` wired from `<customers-dropdown-component>` `@change` / `@mounted` (no MutationObserver required if that hook already updates name, phone, email, balance).
   - Avatar initial derived from customer name when present; empty-state copy when none selected.
2. **Overview date mirror:**
   - Page JS mirrors issue/due date picker values into the overview card on change (Blade/jQuery only; date-picker component frozen).
3. **Tab Switching:**
   - Clicking `.vom-seg-tab-btn[data-seg="..."]` switches active classes on buttons and corresponding `.vom-seg-tab-pane` containers with zero layout reflow.
4. **Double Submission Prevention:**
   - Keep existing disable-on-submit behavior on `.fixed-btns` / `enhance-submit-action` controls.

---

## 6. VOM Style Guide v1.1 Compliance Matrix

| Element | Style Guide Rule | Implementation Spec |
| :--- | :--- | :--- |
| **Brand Signal** | Single primary teal (`#25B395`) | Primary CTA buttons, active tab indicators, link hover states, and positive balance figures. |
| **Surfaces** | Neutral surfaces (`#FFFFFF`, `#F8FAFC`) | Page background is `#F8FAFC`; cards and input surfaces are `#FFFFFF`. |
| **Borders** | Subtle boundaries (`#E2E8F0`) | All card containers and dividers use `1px solid var(--color-border)`. |
| **Typography** | Arbfont / Tajawal / Cairo | Font family `var(--font-family)`; Title 20px / 700; Section headers 16px / 600; Labels 13px / 500; Body 14px / 400. |
| **Spacing** | 4px base unit (`--space-*`) | Card padding 24px (`--space-6`); field margins 16px (`--space-4`); label gaps 8px (`--space-2`). |
| **Border Radius** | Hierarchy of radii | Inputs/Buttons: 6px (`--radius-md`); Cards: 8px (`--radius-lg`); Pills/Badges: 9999px (`--radius-full`). |
| **RTL Direction** | Native Arabic RTL | `direction: rtl`; logical CSS properties (`margin-inline-start`, `padding-inline-end`). Directional arrows mirrored. |

---

## 7. Edge Cases & Guardrails

1. **Past Fiscal Year Guardrail:**
   - If `issue_date` is earlier than the company's active fiscal year start date (`#fiscal_year`), form submission intercepts to trigger `#favoritesModalForSaveAndClose` or `#favoritesModalForSaveAndNew`.
2. **Quota Depletion (`$data['remaining'] <= 0`):**
   - If user reaches plan limit, the transactional form is superseded by `@include('info.limit_reached')`.
3. **Unsaved Form Protection:**
   - Detects dirty state on inputs. Navigating away prompts standard browser dialog to prevent accidental data loss.
4. **Empty Customer State:**
   - If no customer is chosen, `customer data` card displays an elegant empty state placeholder (*"يرجى تحديد العميل لعرض البيانات والرصيد"*).
5. **No Negative Balance Panic:**
   - Negative customer balance is formatted with a warning tint (`var(--color-error-tint)`) and currency suffix to distinguish credit from debit without jarring red flash.

---

## 8. Styling Approach

- Prefer **token / utility classes in Blade** for color, spacing, radius, and typography.
- Keep `estimate-modern.css` **minimal**: asymmetric grid shell, segmented tabs, and any fixed-btns label/layout tweaks that utilities cannot express cleanly.
- Do not dump estimate-specific layout into global `forms/frames.css`.
- Do not invent a parallel palette; reuse VOM brand teal and existing surfaces where tokens/classes exist.

---

## 9. Phased Delivery

Phases are **implementation / validation checkpoints only** — not separate PRs. **First PR = create 1a–1d.** Edit/clone is follow-on.

| Phase | Scope | Validate before next phase |
| :--- | :--- | :--- |
| **1a — Shell** | Restructure `create.blade.php` into title row + context rail + canvas; wire `.fixed-btns`; CSS utilities + minimal stylesheet | Create page renders 2-column IA; save/cancel/print still work |
| **1b — Context rail** | Alerts card, overview metadata + date mirror, customer card via `handleCustomerChange` | Rail matches Zone 2–4; empty/error states OK |
| **1c — Collateral tabs** | Move attachments / terms / notes (+ custom fields) into segmented tabs | No stacked full-height editors; fields still post correctly |
| **1d — Harden create** | Responsive order, double-submit, fiscal modals, unsaved guard, visual pass | Create ready → **first PR** |
| **2 — Edit / clone** | Copy/adapt create shell to `edit.blade.php` and `clone.blade.php` | Follow-on; scope decided while working |
| **Later (optional)** | Live overview money totals; shared Blade partials extraction | Only if still wanted |
