SP

Features Overview

A complete reference of every feature in Surveyor POS.


1. Day Rental System

The standard rental system tracks equipment rented by the day.

Data model:

  • Rental — the rental agreement (customer, branch, totals, deposit)
  • RentalItems — one row per piece of equipment in the rental
  • Specification — an individual unit of equipment (serial number, price per day, condition, status)
  • EquipmentCategory — the equipment type and its category

Lifecycle:

  1. Admin or worker opens the Rental POS and selects a customer
  2. Equipment is chosen by serial number; price is calculated automatically as price_per_day × duration_days
  3. Selected specs are marked rented (hidden from future availability)
  4. Items are returned individually via the Return workflow; specs revert to available
  5. Late fees accrue automatically via the nightly app:calculate-rental-late-fees command

Financial tracking per rental:

Field Description
total_price Sum of all item prices at time of creation
total_paid Sum of all recorded payments
late_fee Total accumulated late fees
damage_fee Manually entered damage charges
discount Discount applied at creation
deposit_amount Bond/deposit collected upfront
deposit_returned Boolean — whether deposit was refunded

Rental extension: Admins and workers can extend an active rental by adding extra days to all unreturned items. The due date shifts forward, the rental duration is recalculated, and the additional cost is added to total_price. Only items not yet returned are extended. An audit log entry is created for every extension.

PDF receipt: Available on every rental's show page via the Download PDF button.


2. Point Rental System

A parallel rental system that uses a point-based pricing model, typically for specialised survey instruments or project-based work.

Data model mirrors the day rental system:

  • PointRentalPointRentalItemsPointSpecificationPointEquipmentPointCategory

Key difference: Specifications use price_per_point instead of price_per_day. The PointRentalItems table also stores a points field.

Everything else (payments, deposits, late fees, PDF, CSV exports) works identically to the standard rental system.


3. Booking Requests

Customers can submit equipment booking requests from their dashboard without needing to visit in person.

Workflow:

Customer submits booking request
        ↓
SMS sent to customer (confirmation) + SMS sent to all branch workers (new request alert)
        ↓
Admin or Worker sees pending badge on sidebar
        ↓
Staff reviews items, dates, notes
        ↓
    ┌───────────┐
    │  Approve  │ → Rental/PointRental auto-created → SMS sent to customer
    └───────────┘
    ┌───────────┐
    │  Reject   │ → Reason recorded → SMS sent to customer with reason
    └───────────┘
Customer can cancel their own pending requests

Customer actions:

  • Submit a booking for either day rental or point rental equipment
  • Select multiple items and specify duration (days) per item
  • See an estimated total before submitting
  • The booking form shows a blue information banner confirming which branch will receive the request
  • View status of all past requests (pending / approved / rejected / cancelled)
  • Cancel pending requests

Admin and Worker actions:

  • Filter requests by status (pending / approved / rejected / cancelled)
  • Sidebar badge shows live pending count
  • Approve → rental is created automatically, equipment marked as rented
  • Reject → reason required, SMS sent
  • Bulk approve / bulk reject — select multiple pending bookings from the list with checkboxes, then approve or reject them all in one action; a reason is required for bulk rejection

Availability check at approval time: Equipment is not reserved when a booking is submitted. When the booking is approved, the system checks that every item is still available inside a database transaction. If any item is no longer available (e.g. rented out by another booking in the meantime), the approval is blocked and the admin/worker is shown an error. This prevents double-booking without locking equipment speculatively.

Booking auto-expiry: The scheduled command app:auto-expire-bookings runs daily at 02:00 and automatically rejects any pending booking that has been waiting for more than 3 days. The customer is notified by SMS. The expiry window can be changed via the --days option.

SMS notifications (Wigal):

  • On submission to customer: "Your [day/point] booking request for [N] item(s) has been submitted to [Branch]. Our team will review it and notify you once a decision is made."
  • On submission to each branch worker (with phone): "New [day/point] booking request from [Name] for [N] item(s) at [Branch]. Please review booking #[ID]."
  • Approval: "Your [day/point] rental booking request has been approved! Please visit us to collect your equipment."
  • Rejection / cancellation / auto-expiry: SMS sent with the reason or expiry notice

4. Payment Recording

Partial and full payments can be recorded against any rental or point rental.

Payment methods: Cash, Mobile Money, Bank Transfer, Other

Each payment record stores:

  • Amount
  • Method
  • Notes
  • Who recorded it (polymorphic — admin or worker)
  • Timestamp

The rental's total_paid is automatically recalculated as the sum of all payments when a new payment is saved. The financial summary on the rental show page colour-codes the balance row (green = fully paid, red = outstanding).


5. Deposit & Bond Tracking

Every rental can have an optional deposit collected upfront (deposit_amount). The rental show page displays:

  • Deposit amount collected
  • Whether it has been returned
  • Date returned (if applicable)

Admins can mark a deposit as returned via the Return Deposit button, which requires a SweetAlert confirmation and records the action in the audit log.


6. Equipment Availability

The Equipment Availability page is available to both admins (/admin/availability) and workers (/worker/availability). It shows which equipment is currently available or rented for any date range.

  • Default view: today → 7 days ahead
  • Queries RentalItems and PointRentalItems where returned_at IS NULL to determine what is out
  • Four tables: Available Day Equipment, Rented Day Equipment, Available Point Equipment, Rented Point Equipment

7. Maintenance Logs

Track the service history of every piece of equipment.

Log fields:

Field Options
Equipment Day or point specification (serial number)
Type Routine, Repair, Inspection
Status Scheduled, In Progress, Completed
Notes Free text
Started at Date/time
Completed at Date/time
Recorded by Admin or worker (polymorphic)

Logs are paginated and filterable. Each spec's maintenance history is accessible from its detail page.


8. Project & Task Management

Projects are linked to a customer and can contain multiple tasks.

  • Tasks can be assigned to workers
  • Tasks have a status and comment thread
  • Project files (documents, survey reports, images) can be uploaded and downloaded by the assigned customer
  • Workers see their assigned tasks under My Tasks

9. Reports & CSV Exports

Available reports under Admin → Financial Reports:

Report Description CSV Export
Revenue Summary Income breakdown by period
Outstanding Balances All rentals with unpaid balance Yes
Overdue Items All items past their due date Yes
Equipment Revenue Per-equipment income
Customer Statements Per-customer financial summary Yes
Worker Performance Approvals, rejections, revenue per worker for a date range

CSV files are downloaded directly from the browser (no server-side file storage).


10. Audit Log

Every significant action is recorded with:

  • Action identifier (e.g., rental_created, booking_approved, deposit_returned)
  • Human-readable description
  • Who performed it (admin or worker)
  • What it was performed on (polymorphic — the affected model)
  • Old and new values (JSON, where applicable)
  • Branch and timestamp

The audit log is filterable by action type and date range. It is read-only — no records can be deleted from the UI.


11. Dashboards

15. Global Search

A search bar is available in the top navigation on every admin and worker page. Searches are scoped to the current branch.

Searchable entities:

Entity Matched on
Customers Name, phone number, email
Day Rentals Rental ID, customer name
Point Rentals Point Rental ID, customer name
Equipment Serials (Day) Serial number
Equipment Serials (Point) Serial number
Booking Requests Booking ID, customer name, customer phone

Results are grouped by type and show up to 10 per category, each with a direct link to the record.

Admin search: GET /admin/search?q=... Worker search: GET /worker/search?q=...


Admin & Worker Dashboard

The admin and worker dashboards each show two rows of operational stat cards and two data panels at the bottom.

Primary stats row:

  • Open Tasks
  • Day Rentals (total for branch)
  • Point Rentals (total for branch)
  • Customers

Operational stats row:

  • Pending Booking Requests (amber — links to filtered booking list)
  • Active Items Out (combined count of unreturned day + point rental items, with breakdown)
  • Overdue Items (shows in red text with red border when count > 0)
  • Revenue This Month (GHS sum of total_paid across day and point rentals for the current month)

Utilisation row (between stat cards and bottom panels):

  • Day Equipment Utilisation — progress bar showing what percentage of day specifications at the branch are currently rented
  • Point Equipment Utilisation — same for point specifications

Bottom panels:

  • Recent Pending Booking Requests — the 5 most recent pending bookings with customer name, type, item count, preferred start date, and a Review link
  • Due for Return Today — all rental items whose due_date is today (unreturned), showing equipment name, serial number, customer, and a View link to the rental

Customer Portal

Customers have their own portal at /user/dashboard with:

  • Dashboard — total outstanding balance (highlighted red if > 0), overdue alert, active rented items with days remaining, rental counts
  • Rentals — full history of day rentals with balances
  • Point Rentals — full history of point rentals
  • Bookings — submit and track booking requests
  • Projects — view and download project files

12. Multi-Branch Support

All data is scoped to a branch. Admins select the active branch via a branch switcher on the dashboard. The selected branch ID is stored in the session (selected_branch_id) and applied to all queries automatically.

Workers are tied to a specific branch. Customers are also branch-scoped.


13. SMS Notifications (Wigal)

Wigal SMS is used for:

Trigger Recipient Message
Booking request submitted Customer Submission confirmation with branch name
Booking request submitted All workers at the branch (with phone) New request alert with booking ID
Booking approved Customer Approval confirmation
Booking rejected Customer Rejection with reason
Booking cancelled Customer Cancellation confirmation
Booking auto-expired Customer Auto-rejection notice after 3 days pending
Rental item due tomorrow Customer Reminder SMS
Rental item overdue (daily) Customer Overdue notice including accrued late fee amount in GHS
Phone verification (OTP) User/Worker 6-digit OTP code
Equipment becomes available (waitlist) Waiting customer Availability notice with equipment name

SMS failures are logged to storage/logs/laravel.log and do not interrupt the main operation.


14. Authentication & Security

Three independent auth guards:

Guard Login URL Email verification
admin /admin/login Required
worker /worker/login Required
web (user) /login Required

Each guard has its own forgot-password, reset-password, and verify-email flows. Admin and worker accounts are created by admins; customer accounts can self-register.

Customer password policy: Customer accounts do not require a password. Customers log in via a phone OTP sent to their registered number. The password field is not shown on the registration form or the admin/worker "Add Customer" form. A random password is stored internally to satisfy database constraints but is never used for authentication.


15. Waitlist

When all units of a specific piece of equipment are rented out, customers can join a waitlist for that serial number.

Customer flow:

  • From the equipment listing, click Join Waitlist to be queued for a specific serial.
  • My Waitlist (/user/waitlist) shows all active and historical entries with status badges.
  • Active entries (status waiting) can be cancelled.

Status lifecycle: waitingnotifiedfulfilled or cancelled

Automatic SMS notification: When a specification's status changes to available (e.g., after a return), all customers with waiting entries for that serial are automatically notified by SMS and their status is updated to notified. This is handled by Eloquent model observers (SpecificationObserver, PointSpecificationObserver) that fire on every status update.

Admin / Worker management:

  • Bookings → Waitlist shows all entries for the current branch with filter tabs (status, rental type).
  • Waiting count is shown as a badge on the Waitlist sidebar link.
  • Staff can cancel individual entries from the table.

16. Branch Transfers

Admins can physically move an available piece of equipment from one branch to another. Every transfer is recorded with a full audit trail.

Rules:

  • Only equipment with status available can be transferred (rented items are blocked).
  • Cannot transfer to the same branch.
  • Both day-rental (Specification) and point-rental (PointSpecification) equipment are supported.

What happens on transfer:

  1. The specification's branch_id is updated to the target branch immediately.
  2. A SpecificationTransfer record is created with from_branch_id, to_branch_id, the actor, and optional notes.
  3. An audit log entry (specification_transferred) is written.

Admin UI: Operations → Branch Transfers (/admin/specification-transfers)

  • Left panel: form to initiate a new transfer (type toggle day/point, equipment selector, target branch, optional notes).
  • Right panel: paginated history showing all transfers in/out of the current branch with direction badges (green "In", amber "Out").