This commit is contained in:
parent
749f525f83
commit
b0666841f6
7 changed files with 139 additions and 31 deletions
|
|
@ -234,22 +234,33 @@ export inline constexpr std::int64_t kMaxQuantity = 99;
|
|||
export inline constexpr std::string_view kNoSaleMessage =
|
||||
"Catcrafts does not sell or ship to the United States or Canada.";
|
||||
|
||||
// The sanctions refusal, in different words on purpose: kNoSaleMessage states
|
||||
// a choice, this states a prohibition. Naming the reason here rather than only
|
||||
// on the terms page — unlike the insurance one — because "sanctions" is the
|
||||
// whole answer: nothing about the shop could change it, and a buyer told only
|
||||
// "no" would rightly ask why.
|
||||
export inline constexpr std::string_view kSanctionsMessage =
|
||||
"Catcrafts cannot sell or ship to Russia, Belarus or North Korea: "
|
||||
"EU sanctions prohibit exporting consumer electronics there.";
|
||||
|
||||
// The two shipping refusals, worded once.
|
||||
//
|
||||
// Since the shop stopped carrying its own rate table, the carrier's coverage
|
||||
// IS the shop's coverage: no bracket for a country means no price exists to
|
||||
// charge, and a parcel above every bracket is one the carrier will not take.
|
||||
// Both refuse rather than guess — a quote the shop cannot honour is worse than
|
||||
// a no — and both name a way forward, because a bare "can't" makes the buyer
|
||||
// guess whether to try again or give up.
|
||||
// a no. The uncovered-country refusal is final: no carrier service means the
|
||||
// shop does not ship there, and offering to arrange it by hand would promise
|
||||
// exactly the ad-hoc export the shop decided not to do. The too-heavy refusal
|
||||
// still names the quantity that WOULD fit, because that buyer has an order the
|
||||
// shop can take — just not in one parcel.
|
||||
//
|
||||
// Kept as {cc}/{n} templates rather than format strings because they have two
|
||||
// consumers: the handler fills them for its field errors, and the buy page
|
||||
// hands them to the total preview verbatim to fill client-side. Same sentence
|
||||
// before and after the submit, from one definition.
|
||||
export inline constexpr std::string_view kNoShippingTemplate =
|
||||
"No carrier rate for {cc} is available right now, so this order can't be "
|
||||
"priced. Email orders@catcrafts.net and it gets arranged by hand.";
|
||||
"No carrier rate for {cc} is available, so Catcrafts can't ship there.";
|
||||
|
||||
export inline constexpr std::string_view kTooHeavyTemplate =
|
||||
"That is more than fits one parcel to {cc} — up to {n} per order. For a "
|
||||
|
|
@ -257,10 +268,11 @@ export inline constexpr std::string_view kTooHeavyTemplate =
|
|||
|
||||
// The degenerate case: a destination whose heaviest bracket does not even carry
|
||||
// one boxed unit. "Order fewer" is not advice when fewer is zero, so it gets
|
||||
// its own sentence.
|
||||
// its own sentence — and like the uncovered country, it is a final no: what
|
||||
// the carrier can't take, the shop doesn't ship.
|
||||
export inline constexpr std::string_view kTooHeavyNoneTemplate =
|
||||
"A parcel this heavy can't be shipped to {cc} by any rate available. "
|
||||
"Email orders@catcrafts.net.";
|
||||
"A parcel this heavy can't be shipped to {cc} by any rate available, "
|
||||
"so this order can't be placed.";
|
||||
|
||||
export std::string FillShipMessage(std::string_view tmpl, std::string_view cc,
|
||||
std::int64_t n) {
|
||||
|
|
@ -346,6 +358,11 @@ export CheckoutResult ValidateCheckout(const Fields& f) {
|
|||
r.errors.push_back({ "country", "Pick a country — it decides shipping and VAT treatment." });
|
||||
} else if (!LooksLikeCountryCode(country)) {
|
||||
r.errors.push_back({ "country", "Country must be a two-letter code." });
|
||||
} else if (Money::IsSanctioned(r.value.country)) {
|
||||
// Checked before the general refusal because SellsTo denies both and
|
||||
// the words differ: this one says the law forbids the sale, not that
|
||||
// the shop chose not to make it.
|
||||
r.errors.push_back({ "country", std::string(kSanctionsMessage) });
|
||||
} else if (!Money::SellsTo(r.value.country)) {
|
||||
// The refusal happens here, in validation, rather than at the payment
|
||||
// step: no order record, no payment link, nothing charged to undo.
|
||||
|
|
|
|||
Loading…
Reference in a new issue