1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
use ;
use crateCurrency;
/// Represents additional price modifications such as tax, discount, or fixed fees.
///
/// This enum is used to define adjustments that can be applied to a `PricingDetail`.
/// These adjustments are later converted and applied using a `CurrencyConverter`,
/// resulting in one or more `AppliedAdjustment` entries with actual values.
///
/// # Variants
///
/// - `Tax`:
/// Represents a tax to be applied as a percentage of the current sell price.
/// Useful for applying VAT, Tax, or sales tax.
///
/// - `name`: A human-readable label (e.g., `"Tax 11%"`)
/// - `percentage`: The tax rate as a percentage (e.g., `11.0` for 11%)
///
/// - `Discount`:
/// Represents a discount applied as a percentage of the current sell price.
/// Useful for promotions or campaigns.
///
/// - `name`: A human-readable label (e.g., `"Promo New Year"`)
/// - `percentage`: The discount rate as a percentage (e.g., `5.0` for 5%)
///
/// - `Fixed`:
/// Represents a fixed fee adjustment, such as a service or admin fee.
/// This amount can be in a different currency and will be converted accordingly.
///
/// Use `sell_currency` as the default currency for fixed amount adjustments.
/// Caller is responsible for providing the correct currency context.
///
/// - `name`: A human-readable label (e.g., `"Admin Fee"`)
/// - `amount`: The raw fixed amount before conversion
/// - `currency`: The original currency of the fixed amount
///
/// # Example
///
/// ```rust
/// use pricing_kit::{Currency, PriceAdjustment};
/// let discount = PriceAdjustment::Discount {
/// name: "Year End Promo".into(),
/// percentage: 5.0,
/// };
///
/// let tax = PriceAdjustment::Tax {
/// name: "Tax 11%".into(),
/// percentage: 11.0,
/// };
///
/// let fixed_fee = PriceAdjustment::Fixed {
/// name: "Admin Fee".into(),
/// amount: 2.0,
/// currency: Currency::new("USD", "US Dollar"),
/// };
/// ```
///
/// Adjustments are intended to be applied in order using `PricingDetail::apply_adjustments()`.
/// Represents a final, applied price adjustment (e.g., tax, discount, or fixed fee)
/// that has been calculated and converted to the target sell currency.
///
/// This structure is typically the result of applying a `PriceAdjustment`
/// to a `PricingDetail` after performing all necessary conversions.
///
/// # Fields
///
/// - `kind`: A string label indicating the type of adjustment: `"Tax"`, `"Discount"`, or `"Fixed"`.
/// - `name`: A human-readable name of the adjustment (e.g., `"Tax 11%"`, `"Promo New Year"`).
/// - `percentage`: Optional percentage value used for `"Tax"` and `"Discount"` adjustments.
/// - `original_currency`: Currency in which the original adjustment was defined, if applicable (usually only for fixed adjustments).
/// - `original_amount`: Original amount of the adjustment before conversion, if applicable.
/// - `applied_amount`: The final amount after calculation and conversion, always expressed in the target `sell_currency`.
///
/// # Example (JSON)
///
/// ```json
/// {
/// "kind": "Tax",
/// "name": "Tax 11%",
/// "percentage": 11.0,
/// "original_currency": {
/// "code": "IDR",
/// "name": "Indonesian Rupiah"
/// },
/// "original_amount": 1996500.0,
/// "applied_amount": 1996500.0
/// }
/// ```
///
/// This struct is intended to be serialization-friendly for logs, APIs, and reporting.