---
title: SAIF.Services.Printing business rules
summary: Enumerated business rules with per-rule trigger, enforcement, and outcomes.
status: draft
owner: SAIF Doc Gen
last_reviewed: 2026-07-30
library: SAIF.Services.Printing
reference_type: package
---

# SAIF.Services.Printing business rules

This page captures the operational rules enforced by the printing, distribution, and report workflow code in `SAIF.Services.Printing`.

## BR-001: Distribution mode follows the Asynchronous flag

| Field | Value |
| --- | --- |
| **Statement** | Document distribution uses either a direct xPression SOAP call or an MSMQ-backed asynchronous queue path based on `clsPrint.Asynchronous`. |
| **Trigger** | A caller invokes `clsPrint.distributeDocument` or `ReportBase.Distribute`. |
| **Enforcement** | `clsPrint.distributeDocument()` branches on `If m_Async Then ... Else ...` before choosing the queue or SOAP path. |
| **Outcome** | The same report payload can be distributed immediately or queued for later processing without changing the caller-facing method signature. |
| **Confidence** | Verified |
| **Source** | `Services\SAIF.Services.Printing\clsPrint.vb` |

---

## BR-002: Asynchronous distribution must commit or abort an MSMQ transaction

| Field | Value |
| --- | --- |
| **Statement** | The asynchronous distribution path commits a transactional MSMQ send on success and aborts the transaction on failure. |
| **Trigger** | `clsPrint.distributeDocument()` runs with `Asynchronous = True`. |
| **Enforcement** | `StartMQTransaction`, `m_Queue.Send`, and `EndMQTransaction(True/False)` coordinate transactional message delivery inside `clsPrint.distributeDocument()`. |
| **Outcome** | Queue-based print requests do not leave an active transaction open after success or exception handling. |
| **Confidence** | Verified |
| **Source** | `Services\SAIF.Services.Printing\clsPrint.vb` |

---

## BR-003: Report rendering selects the default printer by execution platform

| Field | Value |
| --- | --- |
| **Statement** | `ReportBase.Render` resolves the default printer from `clsSecurityPrincipal` using the `Web` platform when `_environmentService.IsWeb` is true, and `Windows` otherwise. |
| **Trigger** | A caller invokes `ReportBase.Render`. |
| **Enforcement** | `ReportBase.Render` sets the platform enum, creates `clsSecurityPrincipal`, and assigns `xPrint.Printer = x.GetDefaultPrinter()`. |
| **Outcome** | Render operations use a platform-appropriate default printer before the preview request is submitted. |
| **Confidence** | Verified |
| **Source** | `Services\SAIF.Services.Printing\Reporting\ReportBase.vb` |

---

## BR-004: Rendered bytes are reused until overwrite is requested

| Field | Value |
| --- | --- |
| **Statement** | `ReportBase` reuses the cached `m_reportFile` content until the caller requests overwrite or no rendered bytes exist yet. |
| **Trigger** | A caller invokes `Render`, `Print`, or `Save`. |
| **Enforcement** | `Render`, `Print`, and `Save` each test the current rendered state before deciding whether to regenerate output. |
| **Outcome** | Repeated print and save operations avoid unnecessary xPression preview calls for the same report instance. |
| **Confidence** | Verified |
| **Source** | `Services\SAIF.Services.Printing\Reporting\ReportBase.vb` |

---

## BR-005: Output profiles switch between standard and draft PDF modes

| Field | Value |
| --- | --- |
| **Statement** | `ReportBase.SetDefaultProfile` selects `PDF`, while `ReportBase.SetDraftProfile` selects `PDF_Draft_Watermark`. |
| **Trigger** | A caller invokes `SetDefaultProfile` or `SetDraftProfile` before rendering. |
| **Enforcement** | The methods assign `PROFILE_DEFAULT` or `PROFILE_DRAFT` to `OutputProfile`. |
| **Outcome** | Subsequent render, print, and save operations use either the standard PDF profile or the draft-watermark profile. |
| **Confidence** | Verified |
| **Source** | `Services\SAIF.Services.Printing\Reporting\ReportBase.vb` |

---

## BR-006: SSRS distribution is not implemented

| Field | Value |
| --- | --- |
| **Statement** | `clsRSPrint` does not support report distribution. |
| **Trigger** | A caller invokes `clsRSPrint.DistributeDocument`. |
| **Enforcement** | The method body contains `Throw New NotImplementedException`. |
| **Outcome** | Consumers must use the xPression-based `clsPrint` path for distribution scenarios. |
| **Confidence** | Verified |
| **Source** | `Services\SAIF.Services.Printing\clsRSPrint.vb` |

---

## BR-007: Package name normalization strips a trailing .pkg extension

| Field | Value |
| --- | --- |
| **Statement** | `clsPrint.Package` strips a trailing `.pkg` extension (case-insensitive) from any value assigned to it before the name is used in preview, print, or distribution requests. |
| **Trigger** | A caller sets `clsPrint.Package` directly, or indirectly through `previewPDF`, `previewDocument`, or `distributeDocument`, each of which assigns the incoming package name to the `Package` property. |
| **Enforcement** | The `Package` property setter checks `Right(Value, 4).ToLower = ".pkg"` and, when true, stores `Left(Value, Value.Length - 4)` instead of the raw value. |
| **Outcome** | xPression preview, print, and distribution calls always receive a package name without a `.pkg` suffix regardless of whether the caller supplied one. |
| **Confidence** | Verified |
| **Source** | `Services\SAIF.Services.Printing\clsPrint.vb` |

## Related documentation
- [Index](index.md)
- [Overview](overview.md)
- [Architecture](architecture.md)
- [Dependencies](dependencies.md)
- [Operations and processes](operations-processes.md)
- [Configuration](configuration.md)
- [API reference](api/index.md)

## Sources
- `Services\SAIF.Services.Printing\clsPrint.vb`
- `Services\SAIF.Services.Printing\clsRSPrint.vb`
- `Services\SAIF.Services.Printing\Reporting\ReportBase.vb`
