///|
pub fn customs_line(
code : String,
declared_value : Money,
duty_bp : Int,
insurance_bp : Int,
) -> CustomsLine {
{
code,
declared_value,
duty_bp: duty_bp.max(0),
insurance_bp: insurance_bp.max(0),
}
}
///|
pub fn customs_duty(line : CustomsLine) -> Money {
line.declared_value.percent_bp(line.duty_bp)
}
///|
pub fn customs_insurance(line : CustomsLine) -> Money {
line.declared_value.percent_bp(line.insurance_bp)
}
///|
pub fn calculate_customs(lines : Array[CustomsLine]) -> CustomsSummary {
let mut declared = Money::zero()
let mut duty = Money::zero()
let mut insurance = Money::zero()
for line in lines {
declared = declared.add(line.declared_value.max(Money::zero()))
duty = duty.add(customs_duty(line))
insurance = insurance.add(customs_insurance(line))
}
{
declared_value: declared,
duty,
insurance,
total: declared.add(duty).add(insurance),
}
}
///|
pub fn CustomsLine::is_valid(self : CustomsLine) -> Bool {
self.code.length() > 0 &&
self.declared_value.cents >= 0 &&
self.duty_bp <= 10000 &&
self.insurance_bp <= 10000
}
///|
pub fn CustomsSummary::effective_duty_bp(self : CustomsSummary) -> Int {
if self.declared_value.cents <= 0 {
0
} else {
self.duty.cents * 10000 / self.declared_value.cents
}
}
///|
pub fn CustomsSummary::is_empty(self : CustomsSummary) -> Bool {
self.declared_value.is_zero() &&
self.duty.is_zero() &&
self.insurance.is_zero()
}