Cash Spell in Indonesian

For those who interested in cash spelling in Indonesian, here I share PLPGSQL code:

Usage:
SELECT cash_spell(1200000000.45, true);
'Satu Milyar Dua Ratus Juta Rupiah Empat Puluh Lima Sen'

Code:
CREATE OR REPLACE FUNCTION int_spell(i_val integer)
RETURNS text LANGUAGE 'plpgsql' IMMUTABLE STRICT
AS $BODY$
DECLARE
   _t text:=''::text;
   _SYMBOL text[]:=ARRAY['satu', 'dua', 'tiga', 'empat', 'lima', 'enam', 'tujuh', 'delapan', 'sembilan', 'sepuluh'
, 'sebelas', 'dua belas', 'tiga belas', 'empat belas', 'lima belas', 'enam belas', 'tujuh belas'
, 'delapan belas', 'sembilan belas'];
   _val integer:=i_val;
   _i integer;
BEGIN
   IF _val<1 OR _val>999 THEN
      RAISE EXCEPTION 'outside boundaries';
   END IF;

   _i:=(_val - (_val % 100)) / 100;
   IF _i>0 THEN
      IF _i>9 THEN
         RAISE EXCEPTION 'hundreds failed';
      END IF;
      IF _i = 1 THEN
         _t:='seratus';
      ELSE
         _t:=_SYMBOL[_i] || ' ratus';
      END IF;
      _val:=_val - (_i*100);
   END IF;

   IF _val>0 AND _val<20 THEN
      IF LENGTH(_t) > 0 THEN
         _t:= _t || ' ';
      END IF;
      _t:=_t || _SYMBOL[_val];
      _val:=0;
   END IF;

   _i:=(_val - (_val % 10)) / 10;
   IF _i>0 THEN
      IF _i>9 THEN
         RAISE EXCEPTION 'tenth failed';
      END IF;
      IF LENGTH(_t) > 0 THEN
         _t:= _t || ' ';
      END IF;
      IF _i = 1 THEN
         _t:= _t || 'sepuluh';
      ELSE
         _t:= _t || _SYMBOL[_i] || ' puluh';
      END IF;
      _val:=_val - (_i*10);
   END IF;

   IF _val>0 THEN
      IF LENGTH(_t) > 0 THEN
         _t:= _t || ' ';
      END IF;
      _t:=_t || _SYMBOL[_val];
   END IF;

   RETURN _t;
END;
$BODY$;
GRANT EXECUTE ON FUNCTION int_spell(integer) TO public;

CREATE OR REPLACE FUNCTION cash_spell(n numeric, b_initcap boolean)
RETURNS text LANGUAGE 'plpgsql' IMMUTABLE STRICT
AS $BODY$
DECLARE
   _t text:=''::text;
   _n numeric:=n;
   _frac numeric;
   _cent integer;
   _val integer;
   _suffix text[];
   _s text;
   _unit numeric;
BEGIN
   IF _n > 9999999999999999999999999999999999::numeric THEN
      RAISE EXCEPTION 'outside boundaries';
   END IF;

   IF _n < 0::numeric THEN
      RAISE EXCEPTION 'negative value';
   END IF;

   IF _n = 0::numeric THEN
      _t:='nol rupiah';
      IF b_initcap THEN
         _t:=initcap(_t);
      END IF;
      RETURN _t;
   END IF;

   _frac:= _n - floor(_n);
   _cent:= floor(_frac*100)::integer;

   _n:= _n - _frac; --remove fraction

   _suffix:=ARRAY['desiliun', 'noniliun', 'oktiliun', 'septiliun', 'sekstiliun', 'kuantiliun', 'kuadriliun',
'triliun', 'milyar', 'juta', 'ribu'];
   _unit:=1000000000000000000000000000000000::numeric;
   FOREACH _s IN ARRAY _suffix LOOP
      _val:=((_n - (_n % _unit)) / _unit)::integer;
      IF _val > 0 THEN
         IF LENGTH(_t)>0 THEN
            _t:=_t || ' ';
         END IF;
         IF _s = 'ribu' AND _val=1 THEN
            _t:= _t || 'seribu';
         ELSE
            _t:=_t || int_spell(_val) || ' ' || _s;
         END IF;
         _n:=_n - (_val * _unit);
      END IF;
      _unit:=_unit/1000;
   END LOOP;

   IF _n>0 THEN
      IF LENGTH(_t)>0 THEN
         _t:=_t || ' ';
      END IF;
      _t:=_t || int_spell(_n::integer);
   END IF;

   IF _cent>0 AND LENGTH(_t)=0 THEN
      _t:='nol';
   END IF;

   _t:=_t || ' rupiah';

   IF _cent>0 THEN
      _t:=_t || ' ';
      _t:=_t || int_spell(_cent) || ' sen';
   END IF;

   IF b_initcap THEN
      _t:=initcap(_t);
   END IF;

   RETURN _t;
END;
$BODY$;
GRANT EXECUTE ON FUNCTION cash_spell(numeric, boolean) TO public;

Advertisements
3 comments
  1. renia said:

    Bisa request yg english juga pak

  2. abdulyadi said:

    you can use cash_words(money) function

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: