Skip to content

Contracts

Overview

The Contracts module in ALP (Australian Legal Practice) provides comprehensive contract management capabilities, including creation, tracking, digital signing, and lifecycle management of legal contracts.

Features

Contract Management

  • Create and manage contracts
  • Track contract status and lifecycle
  • Link contracts to matters, clients, or projects
  • Digital signature integration with DocuSeal
  • Document management and version control

Contract Statuses

  • Draft: Initial contract creation stage
    • Only contracts in Draft status can be deleted
    • Can be submitted for digital signing
  • Contract Design: Contract is in design phase and being prepared
  • Waiting For Client Signature: Contract has been submitted for client signature
  • Signed: Contract has been signed by all parties
    • For digital contracts, Signed status can only be changed to Expired
    • For non-digital contracts, can be changed to any status
  • Declined: Contract has been declined by one or more parties
  • Expired: Contract has reached its end date or manually marked as expired
    • For digital contracts, this is the only available status after Signed
    • Cannot be Terminated or Archived

Digital Signing Process

  1. Contract Creation and Design

    • Create contract in Draft status
    • Prepare contract documents and content
    • Move to Contract Design status when ready
  2. Submission Process

    • Submit contract for signing from Contract Design status
    • Status changes to Waiting For Client Signature
    • Add signing parties with contact details
    • Track signing progress
  3. Signing Status Flow

    • When all parties sign: Status changes to Signed
    • If any party declines: Status changes to Declined
    • For digital contracts:
      • Once Signed, can only be changed to Expired
      • Cannot be Terminated or Archived
    • For non-digital contracts:
      • Can be changed to any status
  4. Contract Completion

    • Digital contracts: Can only be marked as Expired after Signed
    • Non-digital contracts: Can be updated to any status based on business needs

User Interface

Contract List View

  • View all contracts with filtering and search
  • Sort by status, date, or contract type
  • Quick access to contract actions
  • Bulk status updates

Contract Detail View

Basic Information

  • Contract name and description
  • Contract type and status
  • Start and end dates
  • Contract amount and currency
  • Related entity (Matter/Client/Project) information

Documents Section

  • Upload and manage contract documents
  • View document history
  • Download documents
  • Submit documents for signing

Digital Signature Section

  • Create signature templates
  • View signing submissions
  • Track signing progress
  • Access signed documents

Permissions

Contract View (ContractView)

  • View contract details
  • Access contract documents
  • View signing status

Contract Create (ContractCreate)

  • Create new contracts
  • Import contracts
  • Create from templates

Contract Edit (ContractEdit)

  • Update contract details
  • Change contract status
  • Add/remove documents
  • Submit for signing
  • Manage contract parties

Contract Delete (ContractDelete)

  • Delete contracts (Draft status only)

Contract Types

  • Service Agreement
  • Employment Contract
  • Non-Disclosure Agreement
  • Partnership Agreement
  • License Agreement
  • And more...

Best Practices

Contract Creation

  1. Start with appropriate contract type
  2. Fill in all required information
  3. Attach necessary documents
  4. Review before submission
  5. Set up digital signing if required

Digital Signing

  1. Ensure all documents are finalized
  2. Verify party information
  3. Set up signature template correctly
  4. Submit for signing
  5. Monitor signing progress

Document Management

  1. Use clear file names
  2. Maintain version control
  3. Keep signed copies secure
  4. Archive old versions
  5. Track document changes

Integration Points

Matter Integration

  • Link contracts to legal matters
  • Track matter-specific contracts
  • Share documents between matter and contract

Client Integration

  • Associate contracts with clients
  • Track client-specific agreements
  • Manage client signing process

Project Integration

  • Connect contracts to projects
  • Track project-related agreements
  • Manage project documentation

Technical Details

API Endpoints

Contract Management

http
GET    /api/contracts              # List contracts
GET    /api/contracts/{id}         # Get contract details
POST   /api/contracts             # Create contract
PUT    /api/contracts/{id}        # Update contract
DELETE /api/contracts/{id}        # Delete contract (Draft only)

Digital Signing

http
GET    /api/contracts/{id}/template           # Get signature template
GET    /api/contracts/{id}/submissions        # Get signing submissions
POST   /api/contracts/docuseal/{id}/submitForSigning  # Submit for signing
POST   /api/contracts/{id}/submission/create  # Create signing submission

Security Considerations

  • Role-based access control
  • Document encryption
  • Secure digital signing
  • Audit trail of all actions
  • Data privacy compliance

Troubleshooting

Common Issues

  1. Cannot Delete Contract

    • Verify contract is in Draft status
    • Check user permissions
    • Ensure no active signing process
  2. Digital Signing Issues

    • Verify document format
    • Check party contact information
    • Confirm template setup
    • Validate submission details
  3. Document Management

    • Check file size limits
    • Verify supported formats
    • Ensure proper permissions

Support Resources

  • Technical support contact
  • Documentation updates
  • Training materials
  • Help desk tickets

Future Enhancements

  • AI-powered contract analysis
  • Automated contract review
  • Risk assessment automation
  • Enhanced template management
  • Advanced reporting features

Code Specifications

Data Models

Contract Model

csharp
public class Contract : BaseEntity
{
    public string ContractUUId { get; set; }
    public string ContractName { get; set; }
    public string ContractDescription { get; set; }
    public ContractType ContractType { get; set; }
    public ContractStatus Status { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public decimal? Amount { get; set; }
    public string Currency { get; set; }
    public bool IsSigned { get; set; }
    public string Comments { get; set; }
    
    // Related Entities
    public int? MatterId { get; set; }
    public int? ClientId { get; set; }
    public int? ProjectId { get; set; }
    
    // Digital Signing
    public string DigitalContractId { get; set; }
    public string DigitalContractSubmissionId { get; set; }
}

Contract DTOs

csharp
public class ContractDto
{
    public int Id { get; set; }
    public string ContractUUId { get; set; }
    public string ContractName { get; set; }
    public ContractType ContractType { get; set; }
    public ContractStatus Status { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public decimal? Amount { get; set; }
    public string Currency { get; set; }
    // ... other properties
}

public class CreateContractInput
{
    public string ContractName { get; set; }
    public string ContractDescription { get; set; }
    public ContractType ContractType { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public decimal? Amount { get; set; }
    public string Currency { get; set; }
    // ... other properties
}

public class UpdateContractInput
{
    public string ContractName { get; set; }
    public string ContractDescription { get; set; }
    public ContractStatus Status { get; set; }
    // ... other properties
}

Frontend Components

Contract List Component

vue
<!-- Contracts.vue -->
<template>
  <div class="p-4">
    <shad-card class="w-full">
      <shad-card-header>
        <shad-card-title>Contracts</shad-card-title>
        <shad-card-description>Manage your legal contracts</shad-card-description>
      </shad-card-header>
      <shad-card-content>
        <shad-data-table
          :columns="columns"
          :data="contracts"
          :searchValue="search"
          @search="handleSearch"
        >
          <!-- Table content -->
        </shad-data-table>
      </shad-card-content>
    </shad-card>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useStore } from 'vuex';
import { ContractStore } from '@/store/modules/contracts';

const store = useStore();
const search = ref('');

const columns = [
  { key: 'contractName', label: 'Contract Name' },
  { key: 'contractType', label: 'Type' },
  { key: 'status', label: 'Status' },
  { key: 'startDate', label: 'Start Date' },
  { key: 'endDate', label: 'End Date' },
  { key: 'actions', label: 'Actions' }
];

// ... component logic
</script>

Contract Detail Component

vue
<!-- Contract.vue -->
<template>
  <master-detail :backLink="{ name: 'Contracts' }">
    <div class="flex items-center justify-between">
      <div class="flex items-center">
        <span class="text-lg font-semibold">{{ contract?.contractName }}</span>
      </div>
      
      <!-- Status Badge and Actions -->
      <div class="flex items-center">
        <!-- Submit for Signing Button (Draft only) -->
        <shad-button
          v-if="contract?.status == ContractStatus.Draft"
          variant="outline"
          size="sm"
          class="mr-2"
          :disabled="state.submitting"
          @click="submitForSigning"
        >
          <iconify-icon
            :icon="state.submitting ? 'lucide:loader-circle' : 'lucide:signature'"
            class="mr-2"
            :class="{ 'fa-spin': state.submitting }"
          />
          {{ state.submitting ? "Submitting..." : "Submit for Signing" }}
        </shad-button>

        <!-- Status Badge -->
        <shad-button
          variant="outline"
          size="sm"
          @click="showUpdateStatusModal = true"
        >
          {{ contract?.status }}
        </shad-button>
      </div>
    </div>
  </master-detail>
</template>

<script setup lang="ts">
import { ref, computed, reactive } from 'vue';
import { useStore } from 'vuex';
import { ContractStore } from '@/store/modules/contracts';
import { ContractStatus } from '@/network/dtos/enumTypes';

// ... component logic
</script>

Contract Status Update Component

vue
<!-- UpdateContractStatus.vue -->
<template>
  <Dialog>
    <DialogContent>
      <DialogHeader>
        <DialogTitle>Update Contract Status</DialogTitle>
        <DialogDescription>
          For digital contracts, only Signed contracts can be changed to Expired status.
          Contracts without a Digital Contract ID can be changed to any status.
        </DialogDescription>
      </DialogHeader>

      <!-- Status selection UI -->
      <div class="flex w-full items-center gap-2">
        <!-- Status steps based on contract type -->
        <template v-for="status in visibleStatusSteps">
          <div class="flex flex-col items-center">
            <Button
              :disabled="isStatusDisabled(status.value)"
              @click="updateStatus"
            >
              {{ status.label }}
            </Button>
          </div>
        </template>
      </div>
    </DialogContent>
  </Dialog>
</template>

API Integration

Contract Service Interface

csharp
public interface IContractService
{
    Task<PaginatedDto<ContractListDto>> GetContracts(ContractFilterInput input, ContractRelatedEntity? relatedEntity);
    Task<ContractDto> GetById(int id);
    Task<ContractDto> CreateContract(CreateContractInput input);
    Task<ContractDto> UpdateContract(int id, UpdateContractInput input);
    Task DeleteContract(int id);
    Task ChangeStatus(List<int> ids, ContractStatus status);
    Task<DocuSealSubmission> HandleDigitalSigningProcess(int id, List<int> documentIds);
    // ... other methods
}

Vuex Store Module

typescript
// contracts.ts
export const ContractStore = {
  state: {
    contracts: [],
    currentContract: null,
    loading: false,
    error: null
  },
  
  getters: {
    GET_CONTRACTS: "GET_CONTRACTS",
    GET_CONTRACT: "GET_CONTRACT",
    // ... other getters
  },
  
  mutations: {
    SET_CONTRACTS: "SET_CONTRACTS",
    SET_CONTRACT: "SET_CONTRACT",
    SET_LOADING: "SET_LOADING",
    SET_ERROR: "SET_ERROR"
  },
  
  actions: {
    GET_CONTRACTS: "GET_CONTRACTS",
    GET_CONTRACT: "GET_CONTRACT",
    CREATE_CONTRACT: "CREATE_CONTRACT",
    UPDATE_CONTRACT: "UPDATE_CONTRACT",
    DELETE_CONTRACT: "DELETE_CONTRACT",
    SUBMIT_CONTRACT_FOR_SIGNING: "SUBMIT_CONTRACT_FOR_SIGNING"
  }
};

Digital Signing Integration

DocuSeal Service Interface

csharp
public interface IDocuSealService
{
    Task<string> GetDocusealFormBuilderToken(int contractId);
    Task<DocuSealTemplateDto> GetDocusealTemplate(int id);
    Task<DocuSealSubmissionsResponse> GetDocusealSubmissions(string contractId);
    Task<DocuSealSubmission> CreateSubmission(string contractId, DocuSealCreateSubmissionInput submission);
}

Digital Signing DTOs

csharp
public class DocuSealSubmitter
{
    public string Email { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
    public bool SendEmail { get; set; }
    public bool SendSms { get; set; }
}

public class DocuSealSubmissionItem
{
    public List<DocuSealSubmitter> Submitters { get; set; }
}

public class DocuSealCreateSubmissionInput
{
    public int TemplateId { get; set; }
    public List<DocuSealSubmissionItem> Submission { get; set; }
    public bool SendEmail { get; set; }
    public bool SendSms { get; set; }
    public string Order { get; set; }
}

Error Handling

Backend Error Handling

csharp
public async Task<ContractDto> CreateContract(CreateContractInput input)
{
    try
    {
        // Validation
        if (input == null)
            throw new ArgumentNullException(nameof(input));
            
        if (string.IsNullOrEmpty(input.ContractName))
            throw new ValidationException("Contract name is required");

        // Create contract
        var contract = _mapper.Map<Contract>(input);
        contract.Status = ContractStatus.Draft;
        
        await _contractRepository.InsertAsync(contract);
        await _unitOfWork.SaveChangesAsync();
        
        return _mapper.Map<ContractDto>(contract);
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error creating contract");
        throw;
    }
}

Frontend Error Handling

typescript
async function submitForSigning() {
  if (!contract.value?.id) return;
  
  state.submitting = true;
  try {
    await store.dispatch(ContractStore.actions.SUBMIT_CONTRACT_FOR_SIGNING, {
      id: contract.value.id.toString()
    });
    await fetchContract(); // Refresh contract data
    fireSuccessToast("Contract submitted for signing successfully");
  } catch (error) {
    fireErrorToast("Failed to submit contract for signing. Please try again.");
    console.error('Failed to submit contract for signing:', error);
  } finally {
    state.submitting = false;
  }
}

Security Implementation

Permission Attributes

csharp
[HttpGet]
[Can(Permissions.ContractView)]
public async Task<PaginatedDto<ContractListDto>> GetList([FromQuery] ContractFilterInput filterInput)
{
    return await _contractService.GetContracts(filterInput, filterInput.RelatedEntity);
}

[HttpDelete("{id}")]
[Can(Permissions.ContractDelete)]
public async Task Delete(int id)
{
    var contract = await _contractService.GetById(id);
    if (contract.Status != ContractStatus.Draft)
        throw new ValidationException("Only contracts in Draft status can be deleted");
        
    await _contractService.DeleteContract(id);
}

Frontend Permission Checks

vue
<template>
  <div class="flex justify-end mt-4 space-x-2">
    <alp-can permission="ContractEdit">
      <shad-button variant="outline" @click="editContract">
        <font-awesome-icon icon="fa-solid fa-edit" class="mr-2" />
        Edit Contract
      </shad-button>
    </alp-can>
    
    <alp-can permission="ContractDelete">
      <shad-button 
        variant="destructive" 
        @click="showDeleteWarning"
        v-if="contract?.status === ContractStatus.Draft"
      >
        <font-awesome-icon icon="fa-solid fa-trash" class="mr-2" />
        Delete Contract
      </shad-button>
    </alp-can>
  </div>
</template>

Released by DevOps Team