Credit Line Requests UI
Frontend screens for the Credit Line Requests module, located under the Contabilidad menu group, and the DocuSign Credit Contracts configuration screen under the Legal menu group.
Architecture Overview
The frontend follows the standard admon pattern:
- Views are under
frontend/client/src/views/ - Services extend the
Baseservice class and call the admon backend - Routes are registered in
frontend/client/src/routes/index.js - All services are registered as singletons in
frontend/client/src/services/index.js
Files
frontend/client/src/
├── routes/index.js # Added routes for both modules
├── services/
│ ├── credit-line-requests.service.js # API calls for request management
│ └── docusign-credit-contracts.service.js # API calls for contract config
├── views/
│ ├── credit-line-requests/
│ │ ├── index.vue # View shell (SectionTitle + Table)
│ │ ├── constants.js # Status/contract enums + CREDIT_LINE_PAGARE_FIELD
│ │ └── components/
│ │ ├── Table.vue # Main paginated table with filters + pagaré status badges
│ │ ├── CreditLineRequestDetail.vue # Container: fetches data + pagaré sub-flow actions
│ │ ├── CreditLineRequestInfo.vue # Request metadata display + pagaré file links
│ │ ├── CreditLineHistoryTab.vue # Credit line history accordion
│ │ └── CreditDocuments.vue # Document approval/rejection table (excludes pagaré docs)
│ └── docusign-credit-contracts/
│ ├── index.vue # View shell
│ └── components/
│ ├── Table.vue # DocuSign contracts list
│ └── ContractForm.offcanvas.vue # Create/edit form offcanvas
└── views/ticketsV2/components/
└── Information.offcanvas.vue # Extended with #extra-sidebar slotScreens
Credit Line Requests List
Route: /credit-line-requestsFile: views/credit-line-requests/index.vue + components/Table.vue
The main table shows all credit line requests with the following columns:
| Column | Description |
|---|---|
| Ticket | Formatted as #XXXXX, linked to ticket |
| Company | Company name with country flag |
| Assigned To | Legal executive assigned to the ticket |
| Requested Amount | Amount in local currency |
| Contract Status | Colored badge: no_contract / sent / created / signed / manual |
| Request Status | Colored badge: pending_commercial / approved_commercial / document_rejected / pagare_sent / pagare_review / pagare_validated / contract_sent / legal_review / active / rejected |
| SLA | Days since creation, color-coded: green (on time), yellow (delayed), red (overdue) |
| Actions | "Ver info" button to open the detail offcanvas |
Filter panel:
| Filter | Input Type |
|---|---|
| Company | Number input |
| Status | Multi-select (Select2) |
| Contract Status | Multi-select (Select2) |
| Date range | Date picker |
The Export CSV button triggers the DataTable streaming export via report=true query parameter.
Credit Line Request Detail (Offcanvas)
Component: views/ticketsV2/components/Information.offcanvas.vue (extended) Triggered by: "Ver info" in the table → informationOffcanvasRef.show(ticket_id, creditRequestId)
The standard Information.offcanvas.vue was extended backward-compatibly:
- New prop
hideRefundInfo(Boolean, defaultfalse): hides the three refund/transfer accordions. Set totruefor credit line requests to avoid showing irrelevant refund data. - New
extraIdref: passed toshow(ticket_id, extraId)and exposed via the#extra-sidebarslot. - New scoped slot
#extra-sidebar: rendersCreditLineRequestDetailwith props{ ticket, loading, extraId }. hide()resetsextraIdtonullso each open fetches fresh data.
The offcanvas renders the ticket detail on the right column and the credit-specific content (via #extra-sidebar) at the bottom of the left column.
CreditLineRequestDetail (Container)
File: views/credit-line-requests/components/CreditLineRequestDetail.vue
This is a data container component:
- Receives
{ ticket, loading, extraId }from the#extra-sidebarslot - Calls
api.creditLineRequests.getRequestDetail(extraId)viawatchEffect— re-fetches wheneverextraIdchanges - Renders two
Accordionblocks:- Request Info →
CreditLineRequestInfo - Documents →
CreditDocuments
- Request Info →
- On
@updatedfromCreditDocuments, re-fetches to reflect latest statuses
CreditLineRequestInfo
File: views/credit-line-requests/components/CreditLineRequestInfo.vue
Displays request metadata. No internal API calls — all data comes from the container.
Fields shown:
- Requester (from linked ticket)
- Requested amount and days
- Approved amount and days (if set)
- Request status badge
- Contract status badge
- Pagaré files (when present): a Download format link (
pagare_format) and a View signed link (pagare_signed), rendered inline in the info table
CreditDocuments
File: views/credit-line-requests/components/CreditDocuments.vue
Compact 2-column table for reviewing submitted documents:
| Column | Description |
|---|---|
| Document | document_name (bold); type=file shows "Ver archivo" link opening FilePreview.modal.vue; type=text shows raw value |
| Status (110px fixed) | Status badge, optional rejection reason, Approve/Reject icon buttons |
Approve flow: Swal confirmation → PATCH /credit-line-requests/{id}/documents/{documentId} with status: approved → emits updated.
Reject flow: Swal textarea prompt (required) → PATCH with status: rejected and rejection_reason → emits updated.
FilePreview.modal.vue is rendered via <Teleport to="body">.
Pagaré documents are excluded. The component computes visibleDocuments by filtering out pagare_format and pagare_signed (CREDIT_LINE_PAGARE_FIELD), so those are never shown in this generic list or counted by the bulk actions — they live in the dedicated pagaré section of CreditLineRequestDetail.
Permission gating. The approve/reject buttons and the bulk action bar are only rendered when the user has the credit-line-requests-review-documents permission (canReviewDocuments via useAuthStore().can(...)). The "Ver archivo" preview and file re-upload remain available without it.
Pagaré Sub-Flow (inside CreditLineRequestDetail)
File: views/credit-line-requests/components/CreditLineRequestDetail.vue
For Mexico (creditRequest.requires_pagare === true), CreditLineRequestDetail renders status-driven alert panels above the request accordions. Only one panel shows at a time, based on the request status:
| Panel (computed flag) | Shown when | Content / action |
|---|---|---|
showDocumentRejectedNotice | status document_rejected | Warning: a KYC/KYB document was rejected; waiting for the client to re-upload |
showUploadPagareFormat | status approved_commercial, requires pagaré, all required docs approved, not yet approved, has credit-line-requests-manage | File input + Upload pagaré format button → POST /pagare/format |
showPagareSentWaiting | status pagare_sent | Warning: waiting for the client's signed upload + a link to download the uploaded format |
showPagareReview | status pagare_review, has credit-line-requests-review-documents | Link to view the signed pagaré + Validate / Reject buttons → PATCH /pagare/validate |
Computed helpers:
requiresPagare←creditRequest.requires_pagarepagareFormatDoc/pagareSignedDoc← documents matched byCREDIT_LINE_PAGARE_FIELD.FORMAT/.SIGNEDpagareApproved←pagareSignedDoc.status === 'approved'requiredDocuments/allRequiredDocumentsApproved← required, non-pagaré documents (an empty list counts as "all approved", mirroring the backend)
Upload format flow: select a PDF/DOC/DOCX → Swal confirm → uploadPagareFormat(id, formData) (multipart). On a 400 with pending_documents, a toast lists the still-pending documents.
Validate flow: Swal confirm → validatePagare(id, { status }). Approve advances to pagare_validated; reject returns to pagare_sent. After either action the detail is re-fetched and updated is emitted so the table row and offcanvas badge reflect the new status.
Contract gating. contractActionBase now allows the Create Contract action in approved_commercial or pagare_validated, and additionally requires pagareApproved when the country needs a pagaré — so for Mexico the contract button only appears once the signed pagaré is validated.
CreditLineHistoryTab
File: views/credit-line-requests/components/CreditLineHistoryTab.vue
Displays the company's credit line request history. Rendered as an additional accordion in CreditLineRequestDetail. Shows past requests with their statuses, amounts, and dates to give context when reviewing a new application.
DocuSign Credit Contracts Screen
Route: /docusign-credit-contractsMenu group: Legal
List (views/docusign-credit-contracts/index.vue + components/Table.vue)
Lists all registered DocuSign contract configurations. Columns:
| Column | Description |
|---|---|
| Name | Friendly name |
| Country | Locale flag + country name |
| Person Type | kyb or kyc badge |
| Template ID | DocuSign Template ID (truncated) |
| Active | Toggle badge |
| Actions | Edit button |
Filters: locale, person type, active status.
Create / Edit Form (components/ContractForm.offcanvas.vue)
Offcanvas form with the following fields:
| Field | Type | Notes |
|---|---|---|
| Name | Text | Required |
| Description | Textarea | Optional |
| DocuSign Template ID | Text | Required — obtain from DocuSign Templates admin |
| Country | Select (locales catalog) | Required |
| Person Type | Select (kyb / kyc) | Required |
| Active | Toggle | Only one active per locale + person type |
On create → POST /docusign-credit-contracts On edit → PATCH /docusign-credit-contracts/{id}
If activating a config when another is already active for the same locale + person type, the API will return 409 Conflict.
Services
CreditLineRequestsService
frontend/client/src/services/credit-line-requests.service.js
Extends Base with baseURL: process.env.ENVIA_ADMIN_API_HOSTNAME.
| Method | HTTP | Endpoint |
|---|---|---|
getRequests(filters) | GET | /credit-line-requests |
getRequestDetail(id) | GET | /credit-line-requests/{id} |
getCreditLineHistory(id) | GET | /credit-line-requests/{id}/credit-line-history |
updateRequestStatus(id, payload) | PATCH | /credit-line-requests/{id}/status |
updateRequestDetails(id, payload) | PATCH | /credit-line-requests/{id}/details |
updateDocumentStatus(requestId, documentId, payload) | PATCH | /credit-line-requests/{id}/documents/{documentId} |
bulkUpdateDocumentStatus(id, payload) | PATCH | /credit-line-requests/{id}/documents/bulk |
uploadPagareFormat(requestId, formData) | POST | /credit-line-requests/{id}/pagare/format (multipart) |
validatePagare(requestId, payload) | PATCH | /credit-line-requests/{id}/pagare/validate |
createContract(id) | POST | /credit-line-requests/{id}/contract |
downloadDocuments(id) | GET | /credit-line-requests/{id}/documents/download |
downloadSignedContract(id) | GET | /credit-line-requests/{id}/contract/signed-download |
syncSignedContract(id) | POST | /credit-line-requests/{id}/contract/signed-storage-sync |
DocusignCreditContractsService
frontend/client/src/services/docusign-credit-contracts.service.js
| Method | HTTP | Endpoint |
|---|---|---|
getContracts(filters) | GET | /docusign-credit-contracts |
create(payload) | POST | /docusign-credit-contracts |
getById(id) | GET | /docusign-credit-contracts/{id} |
update(id, payload) | PATCH | /docusign-credit-contracts/{id} |
Component Extension: Information.offcanvas.vue
This shared component was modified in a fully backward-compatible manner. All existing consumers (tickets, overweights, etc.) are unaffected because:
hideRefundInfodefaults tofalse— existing accordions are shown by defaultextraIdisnullby default — the#extra-sidebarslot renders nothing if not filledshow()signature change is additive (creditRequestId = nulldefault)
Usage from CreditLineRequests Table:
<InformationOffcanvas
ref="informationOffcanvasRef"
:hide-refund-info="true"
>
<template #extra-sidebar="{ ticket, loading, extraId }">
<CreditLineRequestDetail
:ticket="ticket"
:loading="loading"
:extra-id="extraId"
/>
</template>
</InformationOffcanvas>i18n Keys
All i18n keys are loaded from S3 JSON files (es-MX.json / en-US.json). Keys added for this module are under the creditLineRequests.* and docusignCreditContracts.* namespaces. The full key list is available in openspec/changes/credit-line-requests/TRANSLATIONS.md.
The pagaré sub-flow adds keys under creditLineRequests.pagare.* (e.g. title, downloadFormat, viewSigned, uploadFormat.*, waiting.notice, review.notice, actions.validate/actions.reject, documentRejectedNotice) and new request-status labels under creditLineRequests.status.* (document_rejected, pagare_sent, pagare_review, pagare_validated, contract_sent).
The client-facing pagaré signing instructions posted to the ticket are hardcoded in Spanish (they reference Envia's Monterrey legal office and Mexican legal requirements), reflecting that the pagaré step is currently Mexico-only. Other automatic ticket comments (format sent, validated, rejected) use i18n keys (creditLineRequests.pagare.*) resolved in the company's language with an English fallback.
System-generated ticket comments (inserted on DocuSign webhook events) are resolved in the company's language using the Translator class and fall back to English if the translation key is not found.
