Setting the file. One moment.
Store Currency · Rp Source Wordpress · wix/skills · Skills Docs
ContentsBack to the top of the page 39.41
PLUGIN READ PLANS
lib/store-currency.js
lib/ store-currency.js
JavaScript · 101 lines · 5 KB
14
//
15 // The per-order field is still worth reading: a store CAN legitimately hold orders in more than
16 // one currency (multi-currency plugins), and in that case the order's own value is the true one.
17 // So the rule is: trust the order's value when it is a plausible ISO code, fall back to the
18 // store's setting when it is not, and refuse when neither yields one. Never infer a code from a
19 // symbol -- "$" is at least a dozen different currencies.
20
21 const ISO_4217 = / ^ [A-Z] {3}$ / ;
22
23 // The symbols worth recognising -- not to RESOLVE a currency from, but to notice when the store's
24 // declared currency and the order's mangled field are talking about different money. A store set
25 // to ILS whose order says "$" is not an ILS order with a broken field; it is an order this code
26 // cannot read, and falling back would relabel dollars as shekels.
27 //
28 // Deliberately not a lookup table from symbol to code: "$" is USD, CAD, AUD, MXN, SGD and more,
29 // and picking one silently misstates money. This maps a code to the symbols it may legitimately
30 // appear as, and is used only to CORROBORATE a fallback, never to produce one.
31 const SYMBOLS_BY_CODE = {
32 ILS: [ '₪' , '₪' , '₪' , 'NIS' ],
33 USD: [ '$' , '$' , 'US$' ],
34 EUR: [ '€' , '€' , '€' ],
35 GBP: [ '£' , '£' , '£' ],
36 JPY: [ '¥' , '¥' , '¥' ],
37 AUD: [ '$' , 'A$' , '$' ],
38 CAD: [ '$' , 'C$' , '$' ],
39 };
40
41 function readStoreCurrency ( generalSettings ) {
42 if ( ! Array. isArray (generalSettings)) return null ;
43 const setting = generalSettings. find (( entry ) => entry && entry.id === 'woocommerce_currency' );
44 const value = setting && typeof setting.value === 'string' ? setting.value. trim (). toUpperCase () : '' ;
45 return ISO_4217 . test (value) ? value : null ;
46 }
47
48 // Shape is not proof. `ABC`, `XXX` and `ZZZ` all match /^[A-Z]{3}$/ and none of them is money the
49 // target can hold, so a code is accepted only if one of the two sides actually recognises it.
50 function plausibleCode ( code , known ) {
51 if ( ! ISO_4217 . test (code)) return false ;
52 return known. length === 0 || known. includes (code);
53 }
54
55 // `knownCurrencies` is the set the source or target actually supports -- WooCommerce publishes one
56 // at /wc/v3/data/currencies, and the target site declares its own. Pass it when you have it;
57 // with none, shape is all that is left and the caller is told so.
58 function resolveOrderCurrency ( order , storeCurrency , { knownCurrencies = [] } = {}) {
59 const known = (knownCurrencies || []). map (( c ) => String (c). toUpperCase ());
60 const declared = order && typeof order.currency === 'string' ? order.currency. trim () : '' ;
61 const upper = declared. toUpperCase ();
62
63 if ( ISO_4217 . test (upper)) {
64 if ( plausibleCode (upper, known)) return { currency: upper, source: 'order' };
65 return {
66 currency: null ,
67 source: null ,
68 finding: { code: 'order-currency-unknown' , declared, note: 'shaped like a code but not one this store or target supports' },
69 };
70 }
71
72 // The order's field is not a code. Falling back to the store default is only safe when the
73 // mangled value does not CONTRADICT it -- otherwise a "$" order in an ILS store becomes ILS.
74 if (storeCurrency && ISO_4217 . test (storeCurrency)) {
75 const expected = SYMBOLS_BY_CODE [storeCurrency] || [];
76 const agrees = declared. length === 0 || expected. some (( symbol ) => symbol. toUpperCase () === upper);
77 if ( ! agrees) {
78 return {
79 currency: null ,
80 source: null ,
81 // The important one. This is money, and the two sources of truth disagree.
82 finding: { code: 'order-currency-contradicts-store' , declared, storeCurrency },
83 };
84 }
85 return {
86 currency: storeCurrency,
87 source: 'store-settings' ,
88 // Reported, not silent: a store that mangles this field is a store whose other
89 // currency-bearing fields are suspect too.
90 finding: { code: 'order-currency-not-iso' , declared: declared || null , corroboratedBy: declared ? 'symbol-matches-store-currency' : 'field-empty' },
91 };
92 }
93
94 return {
95 currency: null ,
96 source: null ,
97 finding: { code: 'currency-unresolvable' , declared: declared || null },
98 };
99 }
100
101 module . exports = { ISO_4217, SYMBOLS_BY_CODE, readStoreCurrency, resolveOrderCurrency };