///|
pub fn customs_document(
hs_code : String,
description : String,
declared_value : Money,
origin : String,
restricted : Bool,
) -> CustomsDocument {
{ hs_code, description, declared_value, origin, restricted }
}
///|
fn customs_hs_code_valid(code : String) -> Bool {
code.length() >= 4 && code.length() <= 10
}
///|
fn customs_reason(reasons : Array[String], reason : String) -> Unit {
reasons.push(reason)
}
///|
pub fn assess_customs(
document : CustomsDocument,
duty_bp : Int,
) -> CustomsAssessment {
let reasons : Array[String] = []
let duty = document.declared_value
.max(Money::zero())
.percent_bp(duty_bp.max(0))
if document.restricted {
customs_reason(reasons, "restricted goods require an import permit")
{ decision: Reject, duty, reasons }
} else {
if !customs_hs_code_valid(document.hs_code) {
customs_reason(reasons, "HS code length is outside the supported range")
}
if document.description.trim().length() < 3 {
customs_reason(reasons, "description is too short for declaration")
}
if document.declared_value.cents < 0 {
customs_reason(reasons, "declared value is negative")
}
if document.origin.trim().length() == 0 {
customs_reason(reasons, "origin is missing")
}
{
decision: if reasons.length() == 0 {
Clear
} else {
Review
},
duty,
reasons,
}
}
}
///|
pub fn CustomsAssessment::is_clear(self : CustomsAssessment) -> Bool {
self.decision == Clear
}
///|
pub fn CustomsAssessment::requires_review(self : CustomsAssessment) -> Bool {
self.decision == Review
}
///|
pub fn CustomsAssessment::is_rejected(self : CustomsAssessment) -> Bool {
self.decision == Reject
}
///|
pub fn CustomsAssessment::reason_count(self : CustomsAssessment) -> Int {
self.reasons.length()
}