# SetItemValuationPolicy

## Permission Scope

inventoryMaster

## Overview

setItemValuationPolicy assigns a specific valuation policy to an item in a company by creating (or re-pointing) its ItemValuation record, overriding the default policy that a first valuation-affecting movement would otherwise auto-assign. The assignment is keyed by item and company, and the policy must belong to that company since it carries the company's posting accounts.

Once the item has any InventoryLedger history in the company (movements in the company's sites), its policy there is frozen — changing the costing configuration mid-stream would corrupt the valuation history, and a backdated movement arriving after a change would be costed under the wrong configuration. History in other companies does not constrain the assignment.

## Business Rules

- The referenced item and valuation policy must exist
- The policy must belong to the assignment's company
- If no ItemValuation exists for the item and company, one is created
- Re-assigning the same policy is idempotent and returns the existing record
- Assigning a different policy is allowed only while the item has no InventoryLedger history in the company's sites
- Assigning a different policy once the item has ledger history in the company is rejected

## Process Flow

```mermaid
flowchart TD
    A[Receive assignment request] --> B{Item exists?}
    B -->|No| C[Return error: ITEM_NOT_FOUND]
    B -->|Yes| D{Policy exists?}
    D -->|No| E[Return error: VALUATION_POLICY_NOT_FOUND]
    D -->|Yes| N{Policy belongs to the company?}
    N -->|No| O[Return error: VALUATION_POLICY_COMPANY_MISMATCH]
    N -->|Yes| F{ItemValuation exists for item and company?}
    F -->|No| G[Create ItemValuation]
    F -->|Yes| H{Same policy?}
    H -->|Yes| I[Return existing record]
    H -->|No| J{InventoryLedger history exists in the company?}
    J -->|Yes| K[Return error: ITEM_VALUATION_POLICY_CHANGE_NOT_ALLOWED]
    J -->|No| L[Re-point policy]
    G --> M[Return item valuation]
    I --> M
    L --> M
```

## External Dependencies

- [item-management::Item](../../../item-management/docs/model/Item.md) - Validates the referenced item
- [inventory::InventoryLedger](../model/InventoryLedger.md) - Movement-history guard for policy changes
- [organization::Site](../../../organization/docs/model/Site.md) - Resolves the company of each moved site for the history guard

## Error Scenarios

- **ITEM_NOT_FOUND**: Referenced item does not exist
- **VALUATION_POLICY_NOT_FOUND**: Referenced valuation policy does not exist
- **VALUATION_POLICY_COMPANY_MISMATCH**: Referenced valuation policy belongs to a different company
- **SITE_NOT_FOUND**: Referenced site does not exist
- **ITEM_VALUATION_POLICY_CHANGE_NOT_ALLOWED**: Valuation policy cannot be changed once the item has inventory ledger history

## Test Cases

- creates an item valuation when none exists
- returns existing item valuation when the same policy is already assigned
- reassigns the policy when the item has no ledger history
- reassigns the policy when the item has moved only in another company
- returns error when the item has ledger history in the company
- returns error when item does not exist
- returns error when valuation policy does not exist
- returns error when the policy belongs to a different company
