# UpdatePurchasePaymentTerm

## Permission Scope

purchasePricing

## Overview

UpdatePurchasePaymentTerm changes the live definition of a purchase payment term without rewriting any historical snapshots already copied onto purchase orders or purchase bills.

## Business Rules

- Target payment term must exist
- Updated schedule lines must continue to satisfy all create-time validation rules
- Existing purchase orders and purchase bills keep their original snapshots after the term is updated
- Updating an inactive term is allowed so it can be corrected before future reactivation
- Company ownership of the term cannot be changed

## Process Flow

```mermaid
flowchart TD
    A[Receive update request] --> B{Payment term exists?}
    B -->|No| C[Return PAYMENT_TERM_NOT_FOUND]
    B -->|Yes| D{Schedule data valid?}
    D -->|No| E[Return validation error]
    D -->|Yes| F[Update payment term and schedule lines]
    F --> G[Return updated term]
```

## External Dependencies

- [organization::GetCompany](../../../organization/docs/queries/GetCompany.md) - Preserve and validate existing company scope

## Error Scenarios

- **PAYMENT_TERM_NOT_FOUND**: Referenced purchase payment term does not exist
- **EMPTY_SCHEDULE**: No payment term schedule lines were provided
- **INVALID_INSTALLMENT_TOTAL**: Percentage-based installment lines do not total 100 percent
- **INVALID_SCHEDULE_LINE**: A schedule line contains a negative percentage or negative fixed amount
- **IMMUTABLE_COMPANY_SCOPE**: Update attempted to move the term into another company

## Test Cases

- updates name and schedule lines on an active payment term
- updates an inactive payment term without reactivating it
- preserves historical purchase-order snapshots after update
- preserves historical purchase-bill snapshots after update
- returns error when payment term does not exist
- returns error when the updated schedule is empty
- returns error when updated schedule is invalid
- returns error when an updated schedule line is invalid
- returns error when company scope is changed
- inserts schedule lines with null-coalesced defaults for optional fields
