# Business rules — smsa2020

Evidence date: 2026-10-03.

Source: `git@bitbucket.org:overdrive/smsa2020.git`, `master` at `6c61e14` (2020-02-10).

There is no business-rules document in the source repository. Rules below are taken from code and from sentences shown to the applicant. Each rule is marked **Implemented** or **Inferred**. Nothing here is a new product decision.

The words SMSA do not appear in a rule. The visitor-facing event name in the terms sentence is Vodacom Super Hero Sunday 2020.

## Event selection

**BR-001 — Home and sign-in use one code.** **Implemented.** `IndexController::indexAction` and `ApplicationController::loginAction` set `$Code` to `5E37C335A16AA`. The visitor cannot pick another event on those pages.

**BR-002 — Unknown code stops the page.** **Implemented.** If `getProfile` does not return `AC`, the action prints "Sorry this page does not exits" and exits.

**BR-003 — Public categories hide team and hidden rows.** **Implemented.** `getAccreditationCategoryPublic` selects `AccreditationCategory_view` where `AID` matches and `Teams = 0` and `hidden = 0`, ordered by `Category`.

**BR-004 — Roles are the rows for that event.** **Implemented.** `getAccreditationRoleLive` selects `AccreditationRoles_view` where `AID` matches, ordered by `Role`. The method name says "Live". The SQL has no further live or active predicate.

**BR-005 — Linked events on the home form are those still open by DateTo.** **Implemented.** `getAllWhere("AID = '{AC}' AND DateTo >= '{today}'")`. The checkbox label is `Acc_Secondary`, `DateFrom`, and `Location`.

## Application capture

**BR-006 — A submit is stored on `AccreditationApplycation`.** **Implemented.** Posted `data` plus `AC`, `TID`, `FID`, `DateApply`, `Ref`, and `History` = `None`.

**BR-007 — The reference is 6 uppercase hex characters from 3 random bytes.** **Implemented.** `random_id`. No uniqueness check.

**BR-008 — An empty picture is replaced with a built-in JPEG data-URI.** **Implemented.** `applyAction` when `User_pic` is `""`.

**BR-009 — Missing days are stored as an empty string.** **Implemented.** The home wizard does not post `DaysAttending`.

**BR-010 — One email address should not be reused for the same event.** **Implemented** in the browser only. `checkemailAction` counts existing rows. The insert does not enforce it. **Inferred** that the intended rule is one application email per event. The server does not guarantee it.

**BR-011 — Required answers.** **Implemented** as CSS classes for the jQuery validator, not as server rules. Required: first name, surname, email, mobile, ID or passport number, organisation, category, role, reason for application, terms accepted. Photo is required unless the role's `photo` value is 1. Producer name and producer email are required when the media block is visible.

**BR-012 — Category 1 shows media fields when the event is not media-only.** **Implemented.** `ChangeSelectCat`: if `MediaOnly` is not greater than 0 and the category value is `1`, `#MediaOnly` is shown and `.MediaOnly` becomes required. If the event's `MediaOnly` is already 1, the block is shown from PHP and this branch does not run.

**BR-013 — A role with SupplierReg 1 shows the SA Rugby supplier note.** **Implemented.** The note says the owner, director, or manager of a services company who needs the load-in/out schedule before event day must register at `http://supplier.sarugby.online`. The application does not check that registration.

**BR-014 — The reason text is described as the basis for approval and zone access.** **Implemented** as help text under `Reason_for_pplication`: "Accreditation approval and zone access is dependent on the accuracy of your submission." No code scores that text.

**BR-015 — Terms must be accepted in the browser.** **Implemented.** Checkbox `data[acceptTerms]` class `required`. The visible acceptance sentence says the pass holder accepts that Vodacom Super Hero Sunday 2020 has sole discretion on the level of access, and that parties comply with stadium management rules and the Safety of Sports and Recreational Events Act of 2010. The modal body is the database field `TermsAndConditions`.

**BR-016 — The event note is optional.** **Implemented.** `data[acceptnotes]` is not class `required`.

**BR-017 — A photo larger than 2097152 bytes is refused in the browser.** **Implemented.** The alert text says 1.5mb. The server does not check size.

**BR-018 — Help text asks for a JPG headshot even if the person applied before.** **Implemented** copy. The file input accepts `image/*`, not only JPEG.

**BR-019 — Extra linked events are additional inserts.** **Implemented.** When posted `apply` compares greater than 0, each value is inserted as another row with `AC` set to that value, same reference and same other fields. The checkbox value is `OID`, not a demonstrated `AC`. Whether `OID` is an accreditation id is **Unknown / Requires Confirmation**.

**BR-020 — A signed-in applicant is sent to the profile instead of the apply action.** **Implemented.** `isloggedIN` when `AAID > 0`.

## Close

**BR-021 — After the close instant, GET shows the closed page.** **Implemented.** Close instant is `CloseDate` concatenated with ` 24:00:00`. If that timestamp minus now is less than 1, the closed script is selected. How PHP parses `24:00:00` (same calendar day versus the next midnight) is **Unknown / Requires Confirmation** for the server's PHP build.

**BR-022 — The closed page tells the person to email the event contact.** **Implemented.** `ContactName` and `ContactEmail`.

**BR-023 — A POST after close still inserts.** **Implemented.** `applyAction` does not return after selecting the closed script.

## Mail

**BR-024 — Application mail is sent only when the event has `EmailNotes`.** **Implemented.**

**BR-025 — The message body is the template with placeholders replaced.** **Implemented.** `[ACCREDITATIONNAME]`, `[CONTACTNAME]`, `[CONTACTTELEPHONE]`, `[CONTACTEMAIL]`, `[REFNUMBER]`, `[APPLICANTNAME]`. Decline also replaces `[REASONNOTE]`.

**BR-026 — The subject the applicant receives is the fixed Super Hero Sunday notification subject.** **Implemented.** The "Application Confirmation" subject built in `EmailApplicant` is not passed to `sendMail`.

**BR-027 — Attendance confirm sends `EmailAttandanceConfirmed`.** **Implemented.** Subject inside `sendMail` is still the fixed notification subject. A local `$subject` variable "Attendance Confimation" is unused.

**BR-028 — Attendance decline sends `EmailRejected` only when that field is non-empty.** **Implemented.** Reason text: "Applicant confirmed NON-ATTENDANCE / CANCELLATION for this event."

## Sign-in and profile

**BR-029 — Sign-in matches accreditation id, email, and reference.** **Implemented.** No password. The reference is the credential.

**BR-030 — Empty email or empty reference does not call the server.** **Implemented** in `GoToProfile` after removing whitespace for the emptiness test. The values posted are the unsanitised inputs.

**BR-031 — Failed sign-in shows "Bad credentials."** **Implemented.**

**BR-032 — Profile status labels and locks.** **Implemented** in `profile.phtml`.

| State | Label | Inputs disabled |
|---|---|---|
| `Pending == 1` | Pending | no |
| else `Status == 0` and apply time before last update | In Review | no |
| else `Status == 1` | Confirmed | yes |
| else `Status == 2` | Declined | yes |
| else `Status == 3` | Approved | yes |
| else | New Application | no |

Pending shows `RejectMessage` under the heading "Requirement". Declined shows `DeclinedMessage`.

**BR-033 — Confirmed, Declined, and Approved cannot be edited in the form.** **Implemented** by disabling inputs. **Not implemented** on `updateAction`, which updates by `AAID` with no status check and no session check.

**BR-034 — Services and zones on the profile are display-only.** **Implemented.** Headings "Service Approved" and "Zones Approved". The applicant does not post zone or service changes from this view.

**BR-035 — Decline is a status change.** **Implemented.** `att` 2 sets `Status` 2, `History` "Declined by Applicant", `DeclinedDate`, and clears `AttendanceKey`.

**BR-036 — Confirm attendance does not approve or decline the application.** **Implemented.** It sets `AttendanceRequest` 1, stores the response time, and clears `AttendanceKey`. `Status` is unchanged.

**BR-037 — Attendance links do not require the sign-in session.** **Implemented.** `attendanceAction` does not call `isloggedIN`. The key is the lookup.

## Access that is not a business rule in code

**Inferred, not stated by a comment:** administrators approve applications in another system. This repository reads `Status`, `Pending`, services, and zones, and does not set Confirmed or Approved.

**Not a coded rule:** the Safety of Sports and Recreational Events Act is cited in the terms sentence and is not referenced by any condition.

**Not a coded permission model:** `application.ini.bak` names layouts `admin`, `union`, `referee`, `gir`, and `accreditations`. Only `application/layouts/default.phtml` exists. No controller checks those roles.
