# Admin Tools & Data Maintenance

Items on the tools menu control rarely accessed but important setup and configuration tools for OPSCOM. Data Maintenance options are also here.

# Data Maintenance Articles

<p class="callout info">Data maintenance is crucial for ensuring the accuracy, reliability, and optimal performance of any system.</p>

Regular data maintenance helps to:

- **Improve Data Accuracy:** By identifying and correcting errors, inconsistencies, and redundancies, data maintenance ensures that the information you rely on is trustworthy and precise.
- **Enhance System Performance:** Clean and well-organized data leads to faster processing, quicker searches, and more efficient operations within the system, preventing slowdowns and crashes.
- **Facilitate Informed Decision-Making:** Accurate and up-to-date data provides a clear and reliable foundation for analysis, reporting, and strategic planning, leading to better business decisions.
- **Ensure Compliance and Security:** Maintaining data integrity helps meet regulatory compliance requirements and reduces the risk of security vulnerabilities associated with outdated or corrupted information.
- **Reduce Operational Costs:** By minimizing errors and improving efficiency, data maintenance helps avoid costly reworks, resource waste, and potential financial losses due to inaccurate information.

The following articles all pertain to Data Maintenance Activities:

- ##### [Preparing to Import your User Data](https://opscom.wiki/books/new-client-onboarding/page/preparing-to-import-your-user-data)
- ##### [Purge Old Data - Explained](https://opscom.wiki/books/setup-configuration-for-admins/page/purge-old-explained)
- ##### [Purging Incidents ](https://opscom.wiki/books/setup-configuration-for-admins/page/purging-incidents)
- ##### [Resolve Duplicate Options](https://opscom.wiki/books/setup-configuration-for-admins/page/resolve-duplicate-options)
- ##### [Merging Vehicles](https://opscom.wiki/books/the-opscom-admin-portal/page/merge-vehicles)
- ##### [Merging Users](https://opscom.wiki/books/the-opscom-admin-portal/page/merge-user)
- [##### Archive or Disabling a User](https://opscom.wiki/books/the-opscom-admin-portal/page/archiving-or-disabling-a-user)
- [##### Archiving and Restoring Permits](https://opscom.wiki/books/the-opscom-admin-portal/page/archiving-and-restoring-permits)

# Using the Database Importer (Beta)

<p class="callout info">The **Database Importer** in OPSCOM provides administrators with a powerful tool to import existing data into the system using CSV files. This functionality is essential for initial data migration, mass updates, or integrating data from external systems, ensuring that your OPSCOM database is populated and maintained efficiently. <span style="text-decoration: underline;">This tool is currently in **BETA**.</span></p>

### Setup &amp; Configuration

1. Hover over **Tools**, then click **Data Importer - BETA** to access the tool.

##### <span style="text-decoration: underline;">Permissions Requirements</span>

If the **Data Importer** page is not visible, the user's account does not have the necessary permissions enabled. To allow a user to import or manage data, the following permissions must be configured:

- **Manage tables**: This permission allows the user to view the **Manage Tables** page and utilize the upload functionality for importing data. It does **NOT** grant the ability to reset tables.
- **Reset tables**: This permission grants the ability to empty (reset) tables. It does **NOT** allow the user to see the **Manage Tables** page unless **Manage tables** is also enabled.

These permissions can be found under the **Systems** tab of the permissions management page. Enable them to grant a user access to the **Database Importer** functionality. For more information on configuring permissions, [please refer to the User Roles and Permissions wiki article.](https://opscom.wiki/books/setup-configuration-for-admins/page/manage-roles-and-permissions)

---

### Using this Feature

The **Database Importer** allows data to be imported into a select number of tables within OPSCOM.

##### <span style="text-decoration: underline;">Currently Supported Tables for Import</span>

- **UserProfile**
- **OffenceLocations**
- **Vehicle**
- **Permits**
- **Violations**

##### <span style="text-decoration: underline;">Importing Data into a Table</span>

<p class="callout warning">Note - There is a limit of <span style="text-decoration: underline;">**10000**</span> records to be imported in one batch. This includes the header row.</p>

To begin a new import:

1. Click the **Upload** button next to the desired destination table that you wish to import information into.
2. A modal window will open, prompting you to select the CSV file. Your imported CSV file can be **comma-differentiated** or **semi-colon-differentiated**.
3. Once a file has been selected, click **Submit** to begin the upload process.
4. After the CSV file has been successfully uploaded, the **Table Import** screen will appear.

---

<p class="callout warning">Converting Fields to Text to Avoid Truncating Leading Zeros - When converting data from Excel to CSV, issues can arise, such as the truncation of leading zeros in numbers (e.g., student IDs, staff numbers). To prevent this, you can force Excel to treat cells as text before converting to CSV as below:</p>

1. <span style="color: rgb(230, 126, 35);">Open a new sheet in your Excel workbook.</span>
2. <span style="color: rgb(230, 126, 35);">In cell A1 of the *new* sheet, type the formula: `="'"&` then click on cell A1 of your *original* spreadsheet. (This formula is: equals sign, double quote, apostrophe, double quote, ampersand, then the cell reference.)</span>
3. <span style="color: rgb(230, 126, 35);">Drag this formula down and across through the same number of rows and columns as your original data. This will replicate your data on the new page, but an apostrophe (`'`) will be placed in front of all values, forcing Excel to treat them as text.</span>
4. <span style="color: rgb(230, 126, 35);">Save the new sheet as a `.CSV` file. Ensure you only save the new page. This method effectively preserves leading zeros during the CSV conversion.</span>

---

##### <span style="text-decoration: underline;">Column Matching</span>

On the **Table Import** screen, you will match the columns from your imported CSV file to the corresponding columns in the destination table within OPSCOM.

- This step informs the program where each piece of data from your CSV file belongs in the destination table.
- If your CSV file contained recognized column names, the system will automatically pre-select the appropriate matches.
- For detailed information on each column's purpose, whether it is required or optional, and specific formatting, please refer to the [Importer Field Descriptions guide](https://opscom.wiki/books/for-administrators-staff/page/importer-field-descriptions).

Once the columns have been properly matched and you click the **Process** button, you will be redirected back to the main page while the import is completed in the background.

##### <span style="text-decoration: underline;">Post-Import Processing and Settings</span>

After the initial import of data into the base table, some tables run additional processing on the information to establish relationships and apply default settings. These processes run separately from the initial import and are not affected by the duplicate settings chosen for the import.

##### <span style="text-decoration: underline;">Status Emails</span>

Over the course of the import process, a total of two emails will be sent to the user who initiated the import:

- The **first email** is sent after the data from the CSV has been inserted into the temporary table. It records the number of rows that were successfully imported and the rows that failed due to being malformed.
- The **second email** is sent after the data has been inserted into the base table and post-processing is complete. It contains the number of records that were updated, the number of records inserted, and any relevant information from the post-import processing that occurred.

##### <span style="text-decoration: underline;">Table-Specific Post-Processing Details</span>

- **Permits**: 
    - If the user association column is matched, the created permit will automatically have a booking created for the associated user via a `PermitJoin` record.
    - If the option was selected during import, newly-created permits booked to users will be automatically marked as paid. Otherwise, they will be located in the users' carts, requiring users to complete payment.
- **UserProfile**: 
    - When users are imported, if a `LoginSource` is not provided, it will be automatically set to **OPSCOM**.
    - Newly created users are automatically set to **enabled**.
- **Vehicle**: 
    - If the user association column is matched, the created vehicle will be automatically associated with the user via a `VehicleJoin` record.
    - If the alert column is matched, an alert will be created and automatically attached to the associated vehicle via an `AlertComments` record. The vehicle will also be flagged. The list of vehicles being marked with alerts may also be called a **hotlist**.
- **Violations**: 
    - Any violations created that do not have an `Issued Date` and `Due Date` will have one automatically generated for them at the time of import.
- **OffenceLocations**: 
    - This table has no specific post-processing.

##### <span style="text-decoration: underline;">Order of Operations for Related Imports</span>

Imports that contain related information should generally be done in a specific order, as some tables contain information that references another table. While imports *can* be done out of order, records may not be associated correctly if their dependencies aren't met. In general, the tables a record requires should be imported *before* that record's table.

<div class="horizontal-scroll-wrapper" id="bkmrk-table-to-import-requ"><div class="table-block-component"><div _ngcontent-ng-c3621026028="" class="table-block has-export-button"><div _ngcontent-ng-c3621026028="" class="table-content not-end-of-paragraph" not-end-of-paragraph=""><table data-sourcepos="93:1-99:291" style="width: 103.333%; height: 375px;"><tbody><tr data-sourcepos="93:1-93:403"><th align="left" data-sourcepos="93:1-93:17" style="width: 16.2098%;">Table to Import</th><th align="left" data-sourcepos="93:19-93:46" style="width: 15.9654%;">Requires (Imported Before)</th><th align="left" data-sourcepos="93:48-93:401" style="width: 67.8248%;">Notes</th></tr><tr data-sourcepos="95:1-95:403"><td align="left" data-sourcepos="95:1-95:17" style="width: 16.2098%;">**UserProfile**</td><td align="left" data-sourcepos="95:19-95:46" style="width: 15.9654%;">(None)</td><td align="left" data-sourcepos="95:48-95:401" style="width: 67.8248%;">This should generally be the **first** table imported.</td></tr><tr data-sourcepos="96:1-96:391"><td align="left" data-sourcepos="96:1-96:14" style="width: 16.2098%;">**Vehicles**</td><td align="left" data-sourcepos="96:16-96:32" style="width: 15.9654%;">**UserProfile**</td><td align="left" data-sourcepos="96:34-96:389" style="width: 67.8248%;">Having the user record created before the vehicle allows the user to be associated with the vehicle by a `VehicleJoin` record created during post-import processing.</td></tr><tr data-sourcepos="97:1-97:410"><td align="left" data-sourcepos="97:1-97:22" style="width: 16.2098%;">**OffenceLocations**</td><td align="left" data-sourcepos="97:24-97:51" style="width: 15.9654%;">(None)</td><td align="left" data-sourcepos="97:53-97:408" style="width: 67.8248%;">Does not require any data beforehand but should be imported before **Violations** to ensure proper location marking.</td></tr><tr data-sourcepos="98:1-98:399"><td align="left" data-sourcepos="98:1-98:13" style="width: 16.2098%;">**Permits**</td><td align="left" data-sourcepos="98:15-98:45" style="width: 15.9654%;">**Vehicles**, **UserProfile**</td><td align="left" data-sourcepos="98:47-98:397" style="width: 67.8248%;">Having a vehicle record created before the permit allows the permit to be associated with the vehicle by a `PermitJoin` record created during post-import processing. If there is also an associated user record, the permit can be marked as paid by joining the user and permit through a payment record (if the option was selected).</td></tr><tr data-sourcepos="99:1-99:291"><td align="left" data-sourcepos="99:1-99:16" style="width: 16.2098%;">**Violations**</td><td align="left" data-sourcepos="99:18-99:70" style="width: 15.9654%;">**Vehicles**, **UserProfile**, **OffenceLocations**</td><td align="left" data-sourcepos="99:72-99:289" style="width: 67.8248%;">A violation requires the existence of a vehicle record beforehand for the violation to be created at all. Offence locations should be imported before violations for the violation to have its location properly marked.</td></tr></tbody></table>

</div></div></div></div>##### <span style="text-decoration: underline;">User-Association Settings</span>

Some tables include additional post-processing to associate newly-created records with existing users. For this to work, the unique identifier for the user (**UserUUID** or **Email**) must be selected consistently for both the user's primary record and any associated records (Vehicles, Permits). Ensure the same value is selected for both sections during the import setup.

The tables that currently have this user-association option are:

- **Vehicles**
- **Permits**

##### <span style="text-decoration: underline;">Unique Identifiers &amp; Duplicate Settings</span>

The **Unique Identifiers** are the columns used to determine if a record's information is unique. If the information in these columns is duplicated in the file or already exists in the system, it will be handled based on your selected **Duplicate Settings**:

- **Ignoring a duplicate**: The system will do nothing with the duplicate record.
- **Overwrite existing**: The information in the new record will replace the existing record with the same unique identifier.

The number of columns that mark a record as unique varies by table:

- **UserProfile**: Uses one identifier, which can be either **UserUUID** or **Email**. If both are supplied, **UserUUID** takes precedence.
- **OffenceLocations**: Uses one identifier, which is **LocationName**.
- **Vehicle**: Uses one identifier, which is **Plate**.
- **Permits**: Uses two primary identifiers: **PermitNo** and **LotNameID**. Both are required to make a unique record, meaning identical `PermitNo` values can exist if they have different `LotNameID` values.
- **Violations**: Uses one identifier, which is **Ticket**.

##### <span style="text-decoration: underline;">Foreign Lookup Columns</span>

Some data in one table originates from another table and is stored as an ID in the destination table (known as a foreign key).

- Data in these columns should be entered as normal text in your CSV. The system will automatically look for a match in the corresponding lookup table.
- If a matching value is found (e.g., a "Colour" name in the `VehicleColour` table), the system will input the correct ID value into the destination table.
- If no matching value is found in the lookup table, the system will enter a `Null` value instead.

Below is a list of common foreign lookup columns and their source tables:

<div class="horizontal-scroll-wrapper" id="bkmrk-inserting-into-table"><div class="table-block-component"><div _ngcontent-ng-c3621026028="" class="table-block has-export-button"><div _ngcontent-ng-c3621026028="" class="table-content not-end-of-paragraph" not-end-of-paragraph=""><table data-sourcepos="135:1-148:71"><tbody><tr data-sourcepos="135:1-135:73"><th align="left" data-sourcepos="135:1-135:22">Inserting Into Table</th><th align="left" data-sourcepos="135:24-135:46">Column Inserting Into</th><th align="left" data-sourcepos="135:48-135:71">Sourced From Table</th></tr><tr data-sourcepos="137:1-137:59"><td align="left" data-sourcepos="137:1-137:17">**UserProfile**</td><td align="left" data-sourcepos="137:19-137:41">`prov`</td><td align="left" data-sourcepos="137:43-137:57">**Provinces**</td></tr><tr data-sourcepos="138:1-138:64"><td align="left" data-sourcepos="138:1-138:22"> </td><td align="left" data-sourcepos="138:24-138:46">`UserTypeID`</td><td align="left" data-sourcepos="138:48-138:62">**UserTypes**</td></tr><tr data-sourcepos="139:1-139:55"><td align="left" data-sourcepos="139:1-139:13">**Vehicle**</td><td align="left" data-sourcepos="139:15-139:37">`ProvID`</td><td align="left" data-sourcepos="139:39-139:53">**Provinces**</td></tr><tr data-sourcepos="140:1-140:69"><td align="left" data-sourcepos="140:1-140:22"> </td><td align="left" data-sourcepos="140:24-140:46">`ColourID`</td><td align="left" data-sourcepos="140:48-140:67">**VehicleColours**</td></tr><tr data-sourcepos="141:1-141:66"><td align="left" data-sourcepos="141:1-141:22"> </td><td align="left" data-sourcepos="141:24-141:46">`MakeID`</td><td align="left" data-sourcepos="141:48-141:64">**VehicleMake**</td></tr><tr data-sourcepos="142:1-142:66"><td align="left" data-sourcepos="142:1-142:22"> </td><td align="left" data-sourcepos="142:24-142:46">`TypeID`</td><td align="left" data-sourcepos="142:48-142:64">**VehicleType**</td></tr><tr data-sourcepos="143:1-143:71"><td align="left" data-sourcepos="143:1-143:22"> </td><td align="left" data-sourcepos="143:24-143:46">`PlateTypeID`</td><td align="left" data-sourcepos="143:48-143:69">**VehiclePlateType**</td></tr><tr data-sourcepos="144:1-144:53"><td align="left" data-sourcepos="144:1-144:13">**Permits**</td><td align="left" data-sourcepos="144:15-144:37">`LotNameID`</td><td align="left" data-sourcepos="144:39-144:51">**LotName**</td></tr><tr data-sourcepos="145:1-145:66"><td align="left" data-sourcepos="145:1-145:22"> </td><td align="left" data-sourcepos="145:24-145:46">`StateID`</td><td align="left" data-sourcepos="145:48-145:64">**PermitState**</td></tr><tr data-sourcepos="146:1-146:56"><td align="left" data-sourcepos="146:1-146:16">**Violations**</td><td align="left" data-sourcepos="146:18-146:40">`VehicleID`</td><td align="left" data-sourcepos="146:42-146:54">**Vehicle**</td></tr><tr data-sourcepos="147:1-147:69"><td align="left" data-sourcepos="147:1-147:22"> </td><td align="left" data-sourcepos="147:24-147:46">`TicketType`</td><td align="left" data-sourcepos="147:48-147:67">**TicketCategory**</td></tr><tr data-sourcepos="148:1-148:71"><td align="left" data-sourcepos="148:1-148:22"> </td><td align="left" data-sourcepos="148:24-148:46">`LocationID`</td><td align="left" data-sourcepos="148:48-148:69">**OffenceLocations**</td></tr></tbody></table>

</div></div></div></div>##### <span style="text-decoration: underline;">Table Reset</span>

In addition to importing data, the **Database Importer** page also allows for the **purging** of an entire table's contents.

1. Click the **Reset** button next to the table you wish to empty.
2. A new modal window will open, prompting you to confirm that you wish to delete the contents of the table.
    
    
    - <p class="callout warning">**Irreversible Action:** This action is permanent. Once the data is deleted, it cannot be recovered. Ensure you are absolutely certain before proceeding.  
        </p>
3. If you are certain the data should be deleted, type **DELETE** (in all caps) into the confirmation text field and press the **Delete** button.
4. The selected table will then be purged of all records.

##### <span style="text-decoration: underline;">Related Table Purges</span>

Some tables are closely connected to the records of a related table. Removing the data they contain will also purge the contents of the related table:

- Purging the **Vehicle** table will also purge the **VehicleJoin** table.
- Purging the **Permits** table will also purge the **PermitJoin** table.

<p class="callout info">**Note:** Only the table contents are deleted; the table structure itself remains intact.</p>

---

### <span style="color: rgb(22, 145, 121);">Best Practices &amp; Considerations</span>

- <span style="color: rgb(22, 145, 121);">**Data Preparation is Key**: Ensure your CSV file is meticulously prepared. Accurate data, correct formatting, and adherence to specified column names (if known) will significantly reduce import errors.</span>
- <span style="color: rgb(22, 145, 121);">**Backup Before Import**: While not explicitly a system feature, it's a best practice to ensure you have recent system backups before performing large-scale imports or table resets.</span>
- <span style="color: rgb(22, 145, 121);">**Understand Dependencies**: Always review the "Order of Operations" before importing, especially when dealing with related tables like UserProfile, Vehicles, and Permits. Importing out of order can lead to unassociated records.</span>
- <span style="color: rgb(22, 145, 121);">**Handle Duplicates Strategically**: Choose your "Duplicate Settings" (Ignore or Overwrite) carefully based on whether you intend to add new unique records or update existing ones.</span>
- <span style="color: rgb(22, 145, 121);">**Monitor Status Emails**: Pay close attention to the status emails sent during the import process. They provide crucial feedback on success rates and potential issues.</span>

# Importer Field Descriptions

<p class="callout info">This article provides a comprehensive guide to the fields used within the [OPSCOM Database Importer](https://opscom.wiki/books/setup-configuration-for-admins/page/using-the-database-importer-beta). For each supported table, you'll find a list of column names, their internal system names, their requirement level (Unique ID, Recommended, Optional), data type, and a detailed description, ensuring you can prepare your CSV files accurately for successful data imports.</p>

### Understanding Field Requirements

When preparing your CSV files for import, it's essential to understand the different levels of field requirements:

- **Unique ID Fields**: These fields are **required** and are crucial for identifying a record as a unique entity in the system *before* it's assigned an internal ID. They represent the bare minimum information needed to import a distinct record.
- **Recommended Fields**: While not technically mandatory for a record to be created, these fields contain information that makes the record a genuinely useful entity within the system. Examples include a user's first and last names or the fine value on a violation. A record can exist without them, but its utility will be limited.
- **Optional Fields**: These fields are not required, and a record without them can still function as a useful entity. They contain supplemental information that can be filled in later or isn't essential for the basic functionality of the record, such as a vehicle's manufacturing year.

---

### Importer Columns

Below is a detailed breakdown of the columns available for each supported import table, including their internal names, requirement levels, types, and descriptions.

##### <span style="text-decoration: underline;">UserProfile Table</span>

<table data-autosize="false" data-layout="default" data-number-column="false" data-table-local-id="34de21e8-eca7-41cf-bd0b-f7c79465c2c8" data-table-width="1432" id="bkmrk-column-name-internal" style="width: 100%;"><tbody><tr><th class="pm-table-header-content-wrap" data-colwidth="213" style="width: 10.6079%;">**Column Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="169" style="width: 14.8987%;">**Internal Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="198" style="width: 16.5673%;">**Requirement**

</th><th class="pm-table-header-content-wrap" data-colwidth="204" style="width: 17.1639%;">**Type**

</th><th class="pm-table-header-content-wrap" data-colwidth="634" style="width: 40.7622%;">**Description**

</th></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">User Unique ID (UUID)

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">UserUUID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#ffbdad" data-colwidth="198" style="background-color: rgb(255, 189, 173); width: 16.5673%;">Unique ID

- This or Email is Required

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The primary identifier. If UUID is not supplied, email will be used as the key identifier instead.

This value identifies the user as a unique record and it or the email is required to import a record.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Email Address

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">email

</td><td class="pm-table-cell-content-wrap" data-cell-background="#ffbdad" data-colwidth="198" style="background-color: rgb(255, 189, 173); width: 16.5673%;">Unique ID

- This or UUID is Required

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The secondary identifier. If UUID is not supplied, email will be used as the key identifier instead.

This value identifies the user as a unique record and it or the UUID is required to import a record.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Username

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">username

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="198" style="background-color: rgb(255, 250, 230); width: 16.5673%;">Recommended

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The username of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">First Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">firstName

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="198" style="background-color: rgb(255, 250, 230); width: 16.5673%;">Recommended

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The first name of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Middle Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">middleName

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The middle name of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Last Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">lastName

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="198" style="background-color: rgb(255, 250, 230); width: 16.5673%;">Recommended

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The last name of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Password

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">password

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The password of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">User Type

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">UserTypeID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="198" style="background-color: rgb(255, 250, 230); width: 16.5673%;">Recommended

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="204" style="background-color: rgb(230, 252, 255); width: 17.1639%;">Foreign Key

- UserTypes Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The user type of the user. Attaches to the UserTypes table.

The values supplied by the user in the uploaded file are expected to be values from the TypeName column of the UserTypes table, as these are the values that will be matched against.

The values in the uploaded file must be an exact match to the values in the TypeName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The UserTypeID from the UserTypes table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Street Address

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">street

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The street address of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">City

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">city

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The city of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Province/

State

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">prov

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="204" style="background-color: rgb(230, 252, 255); width: 17.1639%;">Foreign Key

- Provinces Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The province or state of the user. Attaches to the Provinces table.

The values supplied by the user in the uploaded file are expected to be values from the ProvName column of the Provinces table, as these are the values that will be matched against. These are the long names of the province and not the abbreviation; as in, Ontario and not ON.

The values in the uploaded file must be an exact match to the values in the ProvName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The ProvID from the Provinces table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Postal Code

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">postal

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The postal or ZIP code of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Cellphone Number

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">phonecell

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The cellphone number of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Employee Number

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">employNo

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The employee number of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Student Number

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">studentNo

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The student number of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Secondary Phone Number

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">sPhone

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The secondary phone number of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Date of Birth

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">DOB

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The date of birth of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Preferred Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">preferredname

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The preferred name of the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Public Comment

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">publicComment

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The public comment for the user. Visible to the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Private Comment

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">privateComment

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The private comment for the user. Not visible to the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="213" style="width: 10.6079%;">Login Source

</td><td class="pm-table-cell-content-wrap" data-colwidth="169" style="width: 14.8987%;">loginSource

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="198" style="background-color: rgb(171, 245, 209); width: 16.5673%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 17.1639%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="634" style="width: 40.7622%;">The method by which the user logs into the system.

If a login source is not supplied for a user, it will be set to OPSCOM by default.

</td></tr></tbody></table>

##### <span style="text-decoration: underline;">OffenseLocations Table</span>

For additional information on this table, [refer to this wiki article.](https://opscom.wiki/books/setup-configuration-for-admins/page/locations)

<table data-autosize="false" data-layout="default" data-number-column="false" data-table-local-id="0ef2ab71-8dd8-4958-be50-675be36f2d20" data-table-width="1444" id="bkmrk-column-name-internal-1" style="width: 100%;"><tbody><tr><th class="pm-table-header-content-wrap" data-colwidth="204" style="width: 11.7976%;">**Column Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="179" style="width: 12.9938%;">**Internal Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="196" style="width: 17.2825%;">**Requirement**

</th><th class="pm-table-header-content-wrap" data-colwidth="216" style="width: 16.329%;">**Type**

</th><th class="pm-table-header-content-wrap" data-colwidth="643" style="width: 41.5971%;">**Description**

</th></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 11.7976%;">Location Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="179" style="width: 12.9938%;">LocationName

</td><td class="pm-table-cell-content-wrap" data-cell-background="#ffbdad" data-colwidth="196" style="background-color: rgb(255, 189, 173); width: 17.2825%;">Unique ID

- Required

</td><td class="pm-table-cell-content-wrap" data-colwidth="216" style="width: 16.329%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 41.5971%;">The name of the location being imported. This value identifies the location as a unique record and is required to import a record.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 11.7976%;">Writer Visible

</td><td class="pm-table-cell-content-wrap" data-colwidth="179" style="width: 12.9938%;">WriterVisible

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="196" style="background-color: rgb(171, 245, 209); width: 17.2825%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="216" style="width: 16.329%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 41.5971%;">Whether the writer of a violation of a ticket made in the location is visible to the user.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="204" style="width: 11.7976%;">GIS Number

</td><td class="pm-table-cell-content-wrap" data-colwidth="179" style="width: 12.9938%;">GisNo

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="196" style="background-color: rgb(171, 245, 209); width: 17.2825%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="216" style="width: 16.329%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 41.5971%;">The GIS number is a geographic location code and is only used by certain clients. Associated with GIS maps ([https://www.gismaps.org/](https://www.gismaps.org/)).

</td></tr></tbody></table>

##### <span style="text-decoration: underline;">Vehicle Table</span>

<table data-autosize="false" data-layout="default" data-number-column="false" data-table-local-id="14f41f65-23f3-4710-bd69-c44f45ca4823" data-table-width="1456" id="bkmrk-column-name-internal-2" style="width: 100%;"><tbody><tr><th class="pm-table-header-content-wrap" data-colwidth="196" style="width: 12.1573%;">**Column Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="184" style="width: 10.9654%;">**Internal Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="211" style="width: 16.6865%;">**Requirement**

</th><th class="pm-table-header-content-wrap" data-colwidth="215" style="width: 22.4069%;">**Type**

</th><th class="pm-table-header-content-wrap" data-colwidth="643" style="width: 37.903%;">**Description**

</th></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="196" style="width: 12.1573%;">Licence Plate

</td><td class="pm-table-cell-content-wrap" data-colwidth="184" style="width: 10.9654%;">Plate

</td><td class="pm-table-cell-content-wrap" data-cell-background="#ffbdad" data-colwidth="211" style="background-color: rgb(255, 189, 173); width: 16.6865%;">Unique ID

- Required

</td><td class="pm-table-cell-content-wrap" data-colwidth="215" style="width: 22.4069%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 37.903%;">The license plate number of the vehicle.

This value identifies the vehicle as a unique record and is required to import a record.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="196" style="width: 12.1573%;">Vehicle Year

</td><td class="pm-table-cell-content-wrap" data-colwidth="184" style="width: 10.9654%;">Year

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="211" style="background-color: rgb(171, 245, 209); width: 16.6865%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="215" style="width: 22.4069%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 37.903%;">The year of the vehicle.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="196" style="width: 12.1573%;">Active Vehicle

</td><td class="pm-table-cell-content-wrap" data-colwidth="184" style="width: 10.9654%;">active

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="211" style="background-color: rgb(171, 245, 209); width: 16.6865%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="215" style="width: 22.4069%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 37.903%;">Indicates whether the vehicle is active or not.

If not supplied, vehicles will be set to active by default.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="196" style="width: 12.1573%;">Plate Type Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="184" style="width: 10.9654%;">PlateTypeID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="211" style="background-color: rgb(171, 245, 209); width: 16.6865%;">Optional

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="215" style="background-color: rgb(230, 252, 255); width: 22.4069%;">Foreign Key

- VehiclePlateType Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 37.903%;">The plate type of the vehicle. Attaches to the VehiclePlateType table.

The values supplied by the user in the uploaded file are expected to be values from the TypeName column of the VehiclePlateType table, as these are the values that will be matched against.

The values in the uploaded file must be an exact match to the values in the TypeName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The TypeID from the VehiclePlateType table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="196" style="width: 12.1573%;">Province/

State

</td><td class="pm-table-cell-content-wrap" data-colwidth="184" style="width: 10.9654%;">ProvID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="211" style="background-color: rgb(171, 245, 209); width: 16.6865%;">Optional

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="215" style="background-color: rgb(230, 252, 255); width: 22.4069%;">Foreign Key

- Provinces Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 37.903%;">The province or state of the user. Attaches to the Provinces table.

The values supplied by the user in the uploaded file are expected to be values from the ProvName column of the Provinces table, as these are the values that will be matched against. These are the long names of the province and not the abbreviation; as in, Ontario and not ON.

The values in the uploaded file must be an exact match to the values in the ProvName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The ProvID from the Provinces table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="196" style="width: 12.1573%;">Vehicle Make Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="184" style="width: 10.9654%;">MakeID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="211" style="background-color: rgb(171, 245, 209); width: 16.6865%;">Optional

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="215" style="background-color: rgb(230, 252, 255); width: 22.4069%;">Foreign Key

- VehicleMake Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 37.903%;">The make of the vehicle. Attaches to the VehicleMake table.

The values supplied by the user in the uploaded file are expected to be values from the MakeName column of the VehicleMake table, as these are the values that will be matched against.

The values in the uploaded file must be an exact match to the values in the MakeName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The MakeID from the VehicleMake table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="196" style="width: 12.1573%;">Vehicle Type Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="184" style="width: 10.9654%;">TypeID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="211" style="background-color: rgb(171, 245, 209); width: 16.6865%;">Optional

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="215" style="background-color: rgb(230, 252, 255); width: 22.4069%;">Foreign Key

- VehicleType Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 37.903%;">The type of the vehicle. Attaches to the VehicleType table.

The values supplied by the user in the uploaded file are expected to be values from the TypeName column of the VehicleType table, as these are the values that will be matched against.

The values in the uploaded file must be an exact match to the values in the TypeName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The TypeID from the VehicleType table matching the name will inserted into the record in the base table.

The value will be left blank in the imported record if no matches are found.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="196" style="width: 12.1573%;">Vehicle Colour Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="184" style="width: 10.9654%;">ColourID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="211" style="background-color: rgb(171, 245, 209); width: 16.6865%;">Optional

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="215" style="background-color: rgb(230, 252, 255); width: 22.4069%;">Foreign Key

- VehicleColours Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 37.903%;">The colour of the vehicle. Attaches to the VehicleColours table.

The values supplied by the user in the uploaded file are expected to be values from the ColourName column of the VehicleColours table, as these are the values that will be matched against.

The values in the uploaded file must be an exact match to the values in the ColourName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The ColourID from the VehicleColours table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="196" style="width: 12.1573%;">VIN Number

</td><td class="pm-table-cell-content-wrap" data-colwidth="184" style="width: 10.9654%;">vin

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="211" style="background-color: rgb(171, 245, 209); width: 16.6865%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="215" style="width: 22.4069%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="643" style="width: 37.903%;">The Vehicle Identification Number (VIN) of the vehicle.

</td></tr></tbody></table>

##### <span style="text-decoration: underline;">Permits Table</span>

<table data-autosize="false" data-layout="default" data-number-column="false" data-table-local-id="c7e33b53-275e-44bf-93ca-43411a4730df" data-table-width="1458" id="bkmrk-column-name-internal-3" style="width: 100%;"><tbody><tr><th class="pm-table-header-content-wrap" data-colwidth="182" style="width: 10.4887%;">**Column Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="198" style="width: 11.5614%;">**Internal Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="193" style="width: 16.3285%;">**Requirement**

</th><th class="pm-table-header-content-wrap" data-colwidth="234" style="width: 18.9516%;">**Type**

</th><th class="pm-table-header-content-wrap" data-colwidth="646" style="width: 42.6698%;">**Description**

</th></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="182" style="width: 10.4887%;">Permit Number

</td><td class="pm-table-cell-content-wrap" data-colwidth="198" style="width: 11.5614%;">PermitNo

</td><td class="pm-table-cell-content-wrap" data-cell-background="#ffbdad" data-colwidth="193" style="background-color: rgb(255, 189, 173); width: 16.3285%;">Unique ID

- Required

</td><td class="pm-table-cell-content-wrap" data-colwidth="234" style="width: 18.9516%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="646" style="width: 42.6698%;">This field is the first primary identifier. Both it and LotNameID must be provided to create a new permit

This value identifies the permit as a unique record and is required to import a record.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="182" style="width: 10.4887%;">Lot Name (Long)

</td><td class="pm-table-cell-content-wrap" data-colwidth="198" style="width: 11.5614%;">LotNameID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#ffbdad" data-colwidth="193" style="background-color: rgb(255, 189, 173); width: 16.3285%;">Unique ID

- Required

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="234" style="background-color: rgb(230, 252, 255); width: 18.9516%;">Foreign Key

- LotNames Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="646" style="width: 42.6698%;">The long name of the lot associated with the permit. Attaches to the LotNames table.

This field is the second primary identifier. Both it and PermitNo must be provided to create a new permit.

This value identifies the permit as a unique record and is required to import a record.

The values supplied by the user in the uploaded file are expected to be values from the LotName column of the LotNames table, as these are the values that will be matched against. These are the long form version of the lot name, and not the lot short name.

The values in the uploaded file must be an exact match to the values in the LotName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The LotNameID from the LotNames table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="182" style="width: 10.4887%;">Visible

</td><td class="pm-table-cell-content-wrap" data-colwidth="198" style="width: 11.5614%;">visible

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="193" style="background-color: rgb(171, 245, 209); width: 16.3285%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="234" style="width: 18.9516%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="646" style="width: 42.6698%;">Indicates whether the permit is visible or not.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="182" style="width: 10.4887%;">Permit Status

</td><td class="pm-table-cell-content-wrap" data-colwidth="198" style="width: 11.5614%;">status

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="193" style="background-color: rgb(171, 245, 209); width: 16.3285%;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="234" style="width: 18.9516%;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="646" style="width: 42.6698%;">The status of the permit.

</td></tr><tr><td class="pm-table-cell-content-wrap" data-colwidth="182" style="width: 10.4887%;">Permit State

</td><td class="pm-table-cell-content-wrap" data-colwidth="198" style="width: 11.5614%;">StateID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="193" style="background-color: rgb(171, 245, 209); width: 16.3285%;">Optional

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="234" style="background-color: rgb(230, 252, 255); width: 18.9516%;">Foreign Key

- PermitState Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="646" style="width: 42.6698%;">The state of the permit.

</td></tr></tbody></table>

##### <span style="text-decoration: underline;">Violations Table</span>

<table data-autosize="false" data-layout="default" data-number-column="false" data-table-local-id="cce3a9a6-5070-476c-ac34-1d78e73c0615" data-table-width="1452" id="bkmrk-column-name-internal-4" style="width: 100%; height: 1402.77px;"><tbody><tr style="height: 46.5938px;"><th class="pm-table-header-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 46.5938px;">**Column Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 46.5938px;">**Internal Name**

</th><th class="pm-table-header-content-wrap" data-colwidth="197" style="width: 17.0441%; height: 46.5938px;">**Requirement**

</th><th class="pm-table-header-content-wrap" data-colwidth="230" style="width: 22.5264%; height: 46.5938px;">**Type**

</th><th class="pm-table-header-content-wrap" data-colwidth="647" style="width: 36.83%; height: 46.5938px;">**Description**

</th></tr><tr style="height: 80.1875px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 80.1875px;">Ticket Number

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 80.1875px;">Ticket

</td><td class="pm-table-cell-content-wrap" data-cell-background="#ffbdad" data-colwidth="197" style="background-color: rgb(255, 189, 173); width: 17.0441%; height: 80.1875px;">Unique ID

- Required

</td><td class="pm-table-cell-content-wrap" data-colwidth="230" style="width: 22.5264%; height: 80.1875px;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 80.1875px;">The unique identifier for the violation.

This value identifies the violation as a unique record and is required to import a record.

</td></tr><tr style="height: 315.344px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 315.344px;">Licence Plate

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 315.344px;">VehicleID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="197" style="background-color: rgb(255, 250, 230); width: 17.0441%; height: 315.344px;">Recommended

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="230" style="background-color: rgb(230, 252, 255); width: 22.5264%; height: 315.344px;">Foreign Key

- Vehicle Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 315.344px;">The license plate number of the associated vehicle. Attaches to the Vehicle table.

The values supplied by the user in the uploaded file are expected to be values from the Plate column of the Vehicle table, as these are the values that will be matched against.

The values in the uploaded file must be an exact match to the values in the Plate column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The VehicleID from the Vehicle table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr><tr style="height: 348.938px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 348.938px;">Ticket Type Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 348.938px;">TicketType

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="197" style="background-color: rgb(255, 250, 230); width: 17.0441%; height: 348.938px;">Recommended

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="230" style="background-color: rgb(230, 252, 255); width: 22.5264%; height: 348.938px;">Foreign Key

- TicketCategory Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 348.938px;">The type of the ticket. Attaches to the TicketCategory table.

The values supplied by the user in the uploaded file are expected to be values from the TicketTypeName column of the TicketCategory table, as these are the values that will be matched against.

The values in the uploaded file must be an exact match to the values in the TicketTypeName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The TicketTypeID from the TicketCategory table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr><tr style="height: 46.5938px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 46.5938px;">Fine Amount

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 46.5938px;">Fine

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="197" style="background-color: rgb(255, 250, 230); width: 17.0441%; height: 46.5938px;">Recommended

</td><td class="pm-table-cell-content-wrap" data-colwidth="230" style="width: 22.5264%; height: 46.5938px;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 46.5938px;">The amount of fine associated with the ticket.

</td></tr><tr style="height: 46.5938px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 46.5938px;">Towing Amount

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 46.5938px;">Towing

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="197" style="background-color: rgb(171, 245, 209); width: 17.0441%; height: 46.5938px;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="230" style="width: 22.5264%; height: 46.5938px;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 46.5938px;">The amount of towing charges associated with the ticket.

</td></tr><tr style="height: 46.5938px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 46.5938px;">Tax Amount

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 46.5938px;">taxAmount

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="197" style="background-color: rgb(171, 245, 209); width: 17.0441%; height: 46.5938px;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="230" style="width: 22.5264%; height: 46.5938px;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 46.5938px;">The amount of tax associated with the ticket.

</td></tr><tr style="height: 29.7969px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 29.7969px;">Issued Date

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 29.7969px;">Issued

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="197" style="background-color: rgb(255, 250, 230); width: 17.0441%; height: 29.7969px;">Recommended

</td><td class="pm-table-cell-content-wrap" data-colwidth="230" style="width: 22.5264%; height: 29.7969px;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 29.7969px;">The date the ticket was issued.

</td></tr><tr style="height: 29.7969px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 29.7969px;">Due Date

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 29.7969px;">Due

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="197" style="background-color: rgb(255, 250, 230); width: 17.0441%; height: 29.7969px;">Recommended

</td><td class="pm-table-cell-content-wrap" data-colwidth="230" style="width: 22.5264%; height: 29.7969px;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 29.7969px;">The due date for payment of the ticket.

</td></tr><tr style="height: 46.5938px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 46.5938px;">Ticket Writer

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 46.5938px;">Writer

</td><td class="pm-table-cell-content-wrap" data-cell-background="#abf5d1" data-colwidth="197" style="background-color: rgb(171, 245, 209); width: 17.0441%; height: 46.5938px;">Optional

</td><td class="pm-table-cell-content-wrap" data-colwidth="230" style="width: 22.5264%; height: 46.5938px;">Standard

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 46.5938px;">The admin who wrote the ticket.

</td></tr><tr style="height: 365.734px;"><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 10.7271%; height: 365.734px;">Violation Location Name

</td><td class="pm-table-cell-content-wrap" data-colwidth="188" style="width: 12.8725%; height: 365.734px;">LocationID

</td><td class="pm-table-cell-content-wrap" data-cell-background="#fffae6" data-colwidth="197" style="background-color: rgb(255, 250, 230); width: 17.0441%; height: 365.734px;">Recommended

</td><td class="pm-table-cell-content-wrap" data-cell-background="#e6fcff" data-colwidth="230" style="background-color: rgb(230, 252, 255); width: 22.5264%; height: 365.734px;">Foreign Key

- OffenceLocations Table

</td><td class="pm-table-cell-content-wrap" data-colwidth="647" style="width: 36.83%; height: 365.734px;">The name of the location where the violation occurred. Attaches to the OffenceLocations table.

The values supplied by the user in the uploaded file are expected to be values from the LocationName column of the OffenceLocations table, as these are the values that will be matched against.

The values in the uploaded file must be an exact match to the values in the LocationName column, matching the capitalization, spelling, and spacing exactly, or else it won’t be counted as a match.

The LocationID from the OffenceLocations table matching the name will inserted into the record in the base table. The value will be left blank in the imported record if no matches are found.

</td></tr></tbody></table>

---

### <span style="color: rgb(22, 145, 121);">Best Practices &amp; Considerations</span>

- <span style="color: rgb(22, 145, 121);">**Exact Matches for Foreign Keys**: For all `Foreign Key` type columns, the values in your CSV file **must** be an exact match (including capitalization, spelling, and spacing) to the corresponding `Name` column in the referenced OPSCOM table (e.g., `TypeName`, `ProvName`, `MakeName`, `LocationName`). Any mismatch will result in a blank or `Null` value in the imported record.</span>
- <span style="color: rgb(22, 145, 121);">**Prioritize Unique ID and Recommended Fields**: While optional fields offer additional detail, ensure all **Unique ID** fields are present and accurate, and **Recommended** fields are populated for maximum utility of the imported records.</span>
- <span style="color: rgb(22, 145, 121);">**Pre-Populate Reference Tables**: Before importing data that relies on foreign keys (e.g., Vehicles relying on Plate Types or Makes), ensure the corresponding reference tables (**VehiclePlateType**, **VehicleMake**, etc.) are already populated in OPSCOM with all the necessary values. This prevents `Null` values in your imported data.</span>
- <span style="color: rgb(22, 145, 121);">**Data Consistency**: Maintain consistent formatting for dates, phone numbers, and other standard fields within your CSV to avoid import errors.</span>
- <span style="color: rgb(22, 145, 121);">**Test with Small Batches**: For large imports, consider testing with a small batch of records first to verify that your column matching and data formatting are correct before importing the entire dataset.</span>

# Create or Refresh a Preview Space

<p class="callout info">Preview Spaces in OPSCOM provide clients and support staff with a secure, isolated testing environment that mirrors your live production system's data. These spaces are invaluable for testing new features, staging changes, or conducting training without impacting your operational system, ensuring a safe sandbox for development and learning.</p>


### Setup &amp; Configuration

Preview spaces are typically created on demand. Your production/live OPSCOM system is used to either create a new preview space or refresh an existing one with current or historical data.

##### <span style="text-decoration: underline;">Creating or Refreshing a Preview Space</span>

1. Click **Tools,** then **Database to Preview**.

From this page, you have two options for refreshing your preview database:

- **For Up-to-Date Information**: 
    1. Select **Backup Production Database**.
    2. Wait for the backup process to complete.
    3. Click the **Refresh Preview Database** button.
- **For an Older Backup**: 
    1. Select the specific date of the backup you wish to restore the preview database to.
    2. Click the **Refresh Preview Database** button.

<p class="callout warning">It may take a few minutes to refresh the database. Generally, a database is refreshed in 1-2 minutes, but it can take up to 15 minutes depending on the size of your database. A message will be displayed along the top of the screen notifying you when the database refresh is complete.</p>

Once the preview database has been refreshed, your preview system will automatically be created or updated. You can access the preview system by adding ".preview" before "OPSCOM.com" in your browser's address bar. For example, if your production space is `https://tomahawku.OPSCOM.com`, your preview space will be `https://tomahawku.preview.OPSCOM.com`.

---

### Using this Feature

##### <span style="text-decoration: underline;">Accessing Your Preview Space</span>

As an OPSCOM client, you can access your preview space directly by simply adding the ".preview." suffix to your subdomain name. For instance, if your production site is located at `https://yourorganization.OPSCOM.com`, your preview space can be found at `https://yourorganization.preview.OPSCOM.com`.

##### <span style="text-decoration: underline;">Preview Space Banner</span>

To clearly distinguish a preview space from a live production system, all preview spaces are denoted with an **amber warning banner** displayed prominently at the top of the page.

##### <span style="text-decoration: underline;">Locking and Unlocking Database Reset Option</span>

You can now lock and unlock preview and development OPSCOM databases to prevent them from being reset or refreshed accidentally.

1. On your preview site, click **Tools**, then **Reset Database**.
2. Toggle the lock/unlock setting as needed. 
    - You will be prompted to provide a **reason** for locking or unlocking the database.
    - A history of the previous 10 lock/unlock actions will be displayed below for your reference.

This feature allows you to ensure that if you are actively working on a preview/development system and do **NOT** wish for your changes to be reset or lost, you can place a lock. This lock notifies others attempting to refresh the database that a reset is not desired.

---

### <span style="color: rgb(22, 145, 121);">Best Practices &amp; Considerations</span>

- <span style="color: rgb(22, 145, 121);">**Testing and Training Benefits**: Preview spaces are extremely useful for testing and training purposes. They allow you to work with a copy of your live database, providing real data for exercises without any risk of affecting your production system. The database can be manually reset at any time, allowing you to "erase" training data and start testing scenarios from scratch.</span>
- <span style="color: rgb(22, 145, 121);">**Daily Data Backups**: Production/live data is backed up daily at **2 AM EST** and is available to push to the testing environment at any time. This means if you perform a refresh of your preview site, it will pull data captured the night before. This operation is specifically for providing relevant data for testing and preview during training or similar efforts and is separate from normal system backup procedures.</span>
- <span style="color: rgb(22, 145, 121);">**Automatic Deletion of Inactive Spaces**: Preview sites are automatically deleted after **7 days of no login activity**.</span>
    - <span style="color: rgb(22, 145, 121);">If you require a preview site for an extended period, please contact OPSCOM support staff, and an expiry date can be set.</span>
- <span style="color: rgb(22, 145, 121);">**Email Notifications are Suppressed**: No Emails Sent from Preview/Testing - All email notifications that would normally be sent from the server are captured and suppressed in preview/testing environments. Therefore, any email notifications generated within your preview space will **not** reach clients or external recipients. This is a deliberate security measure to prevent accidental communication from a non-production environment.</span>

# Resolve Duplicate Options

<p class="callout info">The **Resolve Duplicates** feature in OPSCOM allows administrators to identify and merge duplicates by email, student number, staff number and vehicle (plate) in the system. This is crucial for maintaining data accuracy, preventing operational errors, and ensuring that enforcement and permit management processes are based on clean, unique vehicle data. This article focuses on resolving duplicates by vehicle, however, the concept is the same for other data types.</p>

1. Click on **Tools**, hover over **Resolve Duplicates**, then click **By Vehicle.**

---

### Using this Feature

On the **Resolve Duplicates By Vehicle** page, you will be presented with options to define the criteria for identifying potential duplicate vehicle records.

##### <span style="text-decoration: underline;">Duplicate Identification Options</span>

There are two choices to generate a list of potential duplicates:

**Strict Duplicate**

<p class="callout info">**Purpose**: This option generates a list of vehicles where all three primary unique identifiers are **identical.** This is for finding exact, unambiguous duplicates. Unique identifiers are:</p>

- **Plate**
- **State/Province**
- **Plate Type**

**Include Different Plate Types**

<p class="callout info">**Purpose**: This option generates a list of vehicles where the **Plate** and **State/Province** are identical, but the **Plate Type** may differ. This is particularly useful for identifying potential input errors where a vehicle might have been entered twice with the correct plate and province, but an incorrect or unspecified plate type was initially used.</p>

**Example**: If a vehicle is a beige BMW sports car with plate **ABC123**, province **Ontario**, and an **unspecified** Plate Type, but there's another record for a beige BMW sports car with plate **ABC123**, province **Ontario**, and Plate Type **Passenger**, it is highly probable that these are the same vehicle entered as a duplicate. Comparing the vehicle description (make, model, color) can help confirm such cases.

##### <span style="text-decoration: underline;">Resolving Duplicates</span>

Once a list of potential duplicates is generated based on your chosen criteria:

1. Review the list carefully, paying close attention to vehicle descriptions and other details to confirm actual duplicates.
2. For each pair of duplicate records you wish to merge, click the **Merge** button provided next to the entries.
3. Clicking **Merge** will take you to the merge function window, where you can select which information to retain from the duplicate records and then finalize the merge.

[![2024-08-13_14-41-29.png](https://opscom.wiki/uploads/images/gallery/2024-08/2024-08-13-14-41-29.png)](https://opscom.wiki/uploads/images/gallery/2024-06/UZrimage.png)

---

### <span style="color: rgb(22, 145, 121);">Best Practices &amp; Considerations</span>

- <span style="color: rgb(22, 145, 121);">**Core Vehicle Identification**: In OPSCOM, vehicles are uniquely identified by three key pieces of information: **License Plate**, **Province / State**, and **Plate Type**. All three details are essential for a vehicle to be considered unique within the system (e.g., "ABC123" could be a passenger plate and also a commercial plate in the same province, requiring the plate type for distinction).</span>
- <span style="color: rgb(22, 145, 121);">**Careful Review**: Always thoroughly review potential duplicates before merging. Merging incorrect records can lead to data loss or inaccuracies.</span>
- <span style="color: rgb(22, 145, 121);">**Common Reasons for Duplicates**: Be aware of common scenarios that lead to duplicates:</span>
    - <span style="color: rgb(22, 145, 121);">**Mismatched vehicle information** (e.g., slight variations in plate number or state entry).</span>
    - <span style="color: rgb(22, 145, 121);">**Incorrectly entered plate numbers** or manual data entry errors.</span>
    - <span style="color: rgb(22, 145, 121);">**Orphaned vehicles** that are not properly linked to a user profile.</span>
    - <span style="color: rgb(22, 145, 121);">**Orphaned violations** that should be associated with a specific vehicle but are linked to a duplicate record.</span>
- <span style="color: rgb(22, 145, 121);">**Proactive Data Entry (Prevention)**: The more information included when adding a vehicle to the system, the better. Providing additional details helps the system recognize potential duplicates and reduces errors. In addition to the three key identifiers, it is highly recommended to include:</span>
    - <span style="color: rgb(22, 145, 121);">**Vehicle Colour**</span>
    - <span style="color: rgb(22, 145, 121);">**Vehicle Make**</span>
    - <span style="color: rgb(22, 145, 121);">**Vehicle Model**</span>
    - <span style="color: rgb(22, 145, 121);">**Vehicle Year** These details help to clearly identify specific vehicles and ensure they are properly recorded.</span>
- <span style="color: rgb(22, 145, 121);">**Data Retention**: When merging, OPSCOM typically allows you to select which data fields from the duplicate records you wish to preserve. Ensure you retain the most accurate and complete information.</span>
- <span style="color: rgb(22, 145, 121);">**Regular Maintenance**: Periodically run the **Resolve Duplicates** report to maintain a clean and accurate vehicle database, especially after periods of high user registration or manual data entry. **Duplicate vehicles can cause significant confusion, especially when multiple drivers are associated with the same vehicle, impacting permit management and enforcement accuracy.**</span>
- <span style="color: rgb(22, 145, 121);">**User Training**: If duplicate entries are a recurring issue, consider reviewing user training or data entry procedures to minimize future occurrences.</span>

# History Search

<p class="callout info">The **History Search** feature in OPSCOM allows administrators to quickly locate and review historical system activities and events. This tool is invaluable for auditing, troubleshooting, and investigating specific actions related to users, vehicles, or violations, providing a comprehensive log of system interactions.</p>

### Using this Feature

1\. Click **Tools**, then **History Search.** The **History Dump** page will be displayed.

You can search using a single identifier or a combination of them to narrow down your results.

##### <span style="text-decoration: underline;">Available Search Criteria</span>

- **Student/Employee Number**: Enter the identification number associated with a student or employee.
- **Violation Ticket**: Enter the specific number of a violation ticket.
- **History Description**: Enter keywords or phrases from the description of the historical event. This field allows for broad searches based on the recorded action.

##### <span style="text-decoration: underline;">Steps to Perform a History Search</span>

1. On the **History Dump** page, enter your desired search criteria into one or more of the available fields (e.g., enter a specific **Violation Ticket** number, as shown in the example) and click **Submit**.
2. All OPSCOM history records that match your entered search criteria will be displayed.

---

## <span style="color: rgb(22, 145, 121);">Best Practices &amp; Considerations</span>

- <span style="color: rgb(22, 145, 121);">**Combine Criteria for Precision**: To achieve more accurate and manageable results, especially in systems with extensive history logs, combine search criteria (e.g., a **Student/Employee Number** along with a specific **History Description** keyword).</span>
- <span style="color: rgb(22, 145, 121);">**Broad vs. Specific Searches**: Start with specific criteria if you know exactly what you're looking for. If you're unsure, use broader terms in the **History Description** field and then refine your search if needed.</span>
- <span style="color: rgb(22, 145, 121);">**Auditing and Troubleshooting**: This tool is excellent for auditing user actions, tracking changes, and troubleshooting issues by reviewing the sequence of events.</span>
- <span style="color: rgb(22, 145, 121);">**Regular Use**: Familiarize yourself with this feature for daily operations, as it can quickly answer questions about past system interactions without needing to navigate through multiple individual records.</span>

# Purge Old - Explained

<p class="callout info">The **Purge Old Data** feature in OPSCOM allows administrators to remove inactive historical records from the system. This process is essential for maintaining database efficiency, improving system performance, and ensuring that your data remains relevant and manageable by automatically archiving or deleting old, unused information. The only records that will be purged are ones that have not had any activity associated with them for more than 7 years.</p>

---

### Using this Feature

1\. Click **Tools**, then **Purge Old Data**.

When you click **Purge Old Data**, the system initiates a process to identify records that meet the purging criteria.

1. Upon activation, a **progress bar** will appear, indicating the number of records being identified for potential purging. The system compiles a list of any user activity and associated record updates that have occurred within the **last seven years**.
2. The compiled "activity list" determines which data to **exclude** from the purge. The script then proceeds to purge any data that is *not* on this active list.
3. To complete the process and execute the purge, click **Purge these records**.

<p class="callout warning">An important business rule is that any small update or activity on a record will "restart" its 7-year clock, meaning the record will then be excluded from purging for another seven years from that last activity date.</p>

### What Gets Purged?

The following record types will be purged if they have had **no activity in the last 7 years**:

- **User profiles**
- **Vehicles**
- **Violations**
- **Permits**
- **Appeals**
- **Temp Permits**
- **Payments**
- **Lockers**
- **Access Cards**
- **Gate Events**
- **Refunds**
- **Waitlist Records**
- **User History**

### What Does NOT Get Purged?

The following record types will **NOT** be purged, regardless of their last updated date, ensuring the retention of critical historical and incident-related information:

- **Incident Users**
- **Contact History**

---

### <span style="color: rgb(22, 145, 121);">Best Practices &amp; Considerations</span>

- <span style="color: rgb(22, 145, 121);">**Understand the 7-Year Rule**: Remember that any interaction or update restarts the 7-year inactivity clock for a record. This ensures that records with recent activity, even minor, are preserved.</span>
- <span style="color: rgb(22, 145, 121);">**Performance Benefits**: Regularly purging old data can significantly improve system performance by reducing database size and speeding up searches and reports.</span>
- <span style="color: rgb(22, 145, 121);">**Data Retention Policies**: Ensure this purge process aligns with your organization's data retention policies and legal compliance requirements.</span>
- <span style="color: rgb(22, 145, 121);">**Historical Context**: Be aware that while purged records are removed, essential incident and contact history data remains for long-term reference.</span>
- <span style="color: rgb(22, 145, 121);">**Schedule Appropriately**: Consider running this purge during off-peak hours to minimize any potential impact on system users, although the process is designed to be efficient.</span>

# Purging Incidents

<p class="callout info">The ability to purge incidents from OPSCOM allows administrators to permanently remove outdated incident records from the system. This process is critical for maintaining data relevance, complying with data retention policies, and optimizing database performance. This article outlines the two methods for incident purging: individual deletion via incident search and bulk deletion using the Purge Incidents tool.</p>

### Setup &amp; Configuration

To enable incident purging capabilities for an administrator, specific permissions must be granted.

- You must add the **Delete Incidents** permission to the specific administrator roles or individual administrators who require the ability to purge incident records. Consult your system administrator or the [User Roles and Permissions wiki article](https://opscom.wiki/books/setup-configuration-for-admins/page/manage-roles-and-permissions) for details on modifying permissions.

---

### Using this Feature

There are two primary methods for purging incidents in OPSCOM: individually through the **Incident Search**, or in bulk using the **Purge Incidents** tool.

##### <span style="text-decoration: underline;">Method 1: Using the Delete Incident Button (Individual Purge)</span>

This method allows for the deletion of a specific incident after searching for it.

1. **Search** for the incident you wish to purge using the standard Incident Search functionality.
2. Once the incident details are displayed, observe the **Delete Incident** button. 
    - The **Delete Incident** button will be **available** (active) only if the incident record is **older than 7 years**.
    - If the incident is **less than 7 years old**, the button will appear as **"Delete Not Available"** and will be greyed out, preventing deletion.
3. If the button is active, click the **Delete Incident** button.
4. Follow any subsequent prompts or confirmation messages to finalize the deletion of the incident.

##### Method 2: Using the Purge Incidents Tool (Bulk Purge)

This tool allows for searching and purging multiple incidents simultaneously based on specified criteria.

1. Click **Tools,** then **Purge Incidents**.
2. The **Search for Incidents to Purge** screen will be displayed.
3. **Enter your search criteria** into the available fields (e.g., date ranges, incident types, specific IDs). 
    - <p class="callout warning">The results displayed will be limited to the **oldest 300 records** that match your criteria.  
          
        **Note:** When entering a value for "Number of Instances," the search field functions as "greater than or equal to." Therefore, supplying "1" might still display incidents with more than one instance.</p>
4. Review the displayed list of incidents.
5. Enable the **Delete** checkbox next to each incident you wish to purge.
6. Click the **Purge Records** button.
7. A confirmation prompt will display. Click the **Delete** button within this prompt to confirm the action.

---

### <span style="color: rgb(22, 145, 121);">Best Practices &amp; Considerations</span>

- <span style="color: rgb(22, 145, 121);">**Irreversible Action**:</span>
    - <span style="color: rgb(22, 145, 121);">**Warning**: Purging incidents is a **permanent and irreversible action**. Once an incident is purged, its data cannot be recovered. Exercise extreme caution and verify your selections before proceeding.</span>
- <span style="color: rgb(22, 145, 121);">**7-Year Retention Rule**: Be aware of the system's built-in 7-year data retention policy for incidents. Incidents cannot be purged using the individual button method if they are newer than 7 years. The bulk purge tool will also primarily display older records.</span>
- <span style="color: rgb(22, 145, 121);">**Permissions Management**: Carefully manage the **Delete Incidents** permission, granting it only to trusted administrators who understand the irreversible nature of the action.</span>
- <span style="color: rgb(22, 145, 121);">**Audit Trail**: While the incident record itself is purged, ensure your organization has an appropriate audit trail or backup strategy if long-term historical access to all incident data is required for compliance or other purposes.</span>
- <span style="color: rgb(22, 145, 121);">**Pre-Purge Review**: Before using the **Purge Incidents Tool**, it is highly recommended to perform a thorough review of the search results and selected incidents to ensure no critical data is inadvertently removed.</span>

# Handheld Devices and Commons

<p class="callout info">The **Handhelds Devices** section in OPSCOM allows administrators to manage and configure handheld devices used for enforcement and data collection. This includes registering new devices, pushing messages, and updating device settings, ensuring seamless operation for field personnel and accurate data synchronization.</p>

[Refer to this wiki article for more information.](https://opscom.wiki/books/setup-configuration-for-admins/page/handhelds-devices-settings-handheld-commons)

# Managing Recurring and Onetime System Tasks

<p class="callout info">OPSCOM utilizes both recurring and onetime system tasks to automate various back-end processes, such as data synchronization, report generation, or system clean-up. This article guides OPSCOM administrators on how to access, monitor, enable, and disable these critical system tasks, ensuring efficient operation and maintenance of the OPSCOM environment.</p>

### Accessing System Tasks

1. Click **Tools (the Toolbox),** then click **View System Task Logs.**
2. On the **Scheduled Tasks** page, there are two sections, Recurring tasks and Onetime tasks. From this screen we can see stats on when the task has run and how long it took to run. We can also enable or disable tasks from running.

The **Scheduled Tasks** page is divided into two main sections: **Recurring tasks** and **Onetime tasks**. For each task listed, administrators can view its status, statistics, and manage its execution.

##### <span style="text-decoration: underline;">Key Information Displayed</span> 

- **Task Name**: The name of the system task.
- **Last Run**: The timestamp of the last time the task was executed.
- **Next Run**: The scheduled timestamp for the next execution of the task.
- **Average Duration**: The average time it takes for the task to complete its execution.
- **Enabled Status**: Indicates whether the task is currently active and configured to run.

##### <span style="text-decoration: underline;">Available Actions &amp; Buttons</span>

- **Enabled Checkbox**: 
    - Click the **Enabled** checkbox next to any task to **toggle** its status.
    - **Enable** (check the box) a task to allow it to run according to its schedule.
    - **Disable** (uncheck the box) a task to prevent it from running.
- **Logs Button**: 
    - Click the **Logs** button for any task to view a pop-up window.
    - This window provides detailed information and historical logs about the task's past executions, including success/failure status and specific output.

<p class="callout warning">Please be aware, there are other settings that may be important to set correctly before enabling any system task.</p>

[![image.png](https://opscom.wiki/uploads/images/gallery/2024-06/scaled-1680-/xTEimage.png)](https://opscom.wiki/uploads/images/gallery/2024-06/xTEimage.png)

---

### <span style="color: rgb(22, 145, 121);">Best Practices &amp; Considerations</span>

- <span style="color: rgb(22, 145, 121);">**Monitor Task Logs Regularly**: Periodically review the **Logs** for critical system tasks to ensure they are running successfully and completing without errors. This helps in proactive identification and resolution of potential issues.</span>
- <span style="color: rgb(22, 145, 121);">**Understand Task Impact**: Familiarize yourself with the purpose and function of each system task before enabling or disabling it, as they can affect data integrity, system performance, or automated processes.</span>
- <span style="color: rgb(22, 145, 121);">**Scheduled Maintenance**: Coordinate the scheduling of onetime tasks with periods of low system activity to minimize any potential impact on user experience.</span>