# Release Summary — 2026-03-20 --- ## 1. QCR Sheet Creation (Non-EB Lead) - Added **QCR** button in the Non-EB lead row dropdown (leads list page). - Clicking QCR copies the existing RFQ Google Sheet for that lead, renames the copy by replacing "RFQ" with "QCR" in the filename, and places it in the same parent folder. - The created sheet's Google File ID is saved to `leads.misc` (as `qcr_sheet_id`). - Lead status is updated to `qcr_created` upon successful creation. - If a QCR sheet already exists for the lead, the existing sheet URL is returned directly (no duplicate creation). - A full-screen "Creating RFQ/QCR file, this may take a while, please wait..." overlay is shown during the AJAX call and hidden on completion. --- ## 2. RFQ/QCR Parent Folder ID — Environment Variable - `RFQ_PARENT_FOLDER_ID` is now loaded from the `.env` file instead of being hardcoded in `RfqConfig.php`. - Placeholder key added to `.env.sample` for environment setup reference. --- ## 3. RFQ/QCR File Viewers (Non-EB Lead Form) - Added a **"RFQ/QCR File Viewers"** searchable multi-select field (Select2) on the Non-EB lead create/edit form, positioned before the Sales Person and Status fields. - Populated with sales team email addresses. - At least one viewer must be selected (validated on submit). - Selected viewer emails are stored as a JSON array in a new database column `leads.rfq_qcr_viewers`. - When an RFQ or QCR sheet is created, the selected viewer emails are applied as Google Sheet **viewer** permissions automatically. > **DB Change Required:** > ```sql > ALTER TABLE leads ADD COLUMN rfq_qcr_viewers TEXT NULL; > ``` --- ## 4. Lead Attachment File Upload (All Mail Modals) - Added a **file upload control** (label, file input, "Upload & Add" button) inside the attachment section of all four mail modals: Internal Mail, Client Mail, Insurer Mail, and Placement Mail. - On upload: - File is saved to the server under `uploads/lead_files/`. - A record is inserted into the `lead_files` table. - The attachment selection list in the modal is refreshed automatically to include the newly uploaded file. --- ## 5. External CC Field (Client Mail & Placement Mail) - Added a manual **External CC** input field (comma-separated email addresses) to: - **Client Mail modal** — visible only when sending a Client Mail (hidden for Insurer Mail). - **Placement Mail modal** — always visible. - On send: 1. The field value is validated as a comma-separated list of valid email addresses. Invalid entries show an error toast. 2. If valid external emails are present, a **Bootstrap confirmation modal** warns the user that the mail will be sent to external addresses. 3. On confirmation, the mail is sent; on cancel, the action is aborted. - **Merge strategy:** - **Placement Mail**: external CC emails are merged directly into the CC array (both are email strings) on the client side before the AJAX call. - **Client Mail**: external CC emails are kept as a separate field and merged into the CC list on the server side, after internal user CC addresses are resolved from user IDs. ---