| 
0
 | 
     1 <!doctype html>
 | 
| 
 | 
     2 <head>
 | 
| 
 | 
     3   <title>Kalkulator</title>
 | 
| 
 | 
     4   <meta name="viewport" content="width=device-width">
 | 
| 
 | 
     5   <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
 | 
| 
 | 
     6   <style type="text/css">
 | 
| 
 | 
     7     body {
 | 
| 
 | 
     8       font-size: 12px;
 | 
| 
 | 
     9       font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
 | 
| 
 | 
    10       line-height: 1.5;
 | 
| 
 | 
    11       margin: 0px;
 | 
| 
 | 
    12       background-color: #eee;
 | 
| 
 | 
    13     }
 | 
| 
 | 
    14     #content {
 | 
| 
 | 
    15       width: 100%;
 | 
| 
 | 
    16       min-height: 100vh;
 | 
| 
 | 
    17       padding: 10px;
 | 
| 
 | 
    18       margin: auto;
 | 
| 
 | 
    19       background-color: #fff;
 | 
| 
 | 
    20     }
 | 
| 
 | 
    21     @media (min-width: 600px) {
 | 
| 
 | 
    22       #content {
 | 
| 
 | 
    23         width: 500px;
 | 
| 
 | 
    24       }
 | 
| 
 | 
    25     }
 | 
| 
 | 
    26     * { box-sizing: border-box; }
 | 
| 
 | 
    27     ul { padding-left: 20px; }
 | 
| 
 | 
    28     #n, .js { display: none; }
 | 
| 
 | 
    29     input, button, select, option, .js { font-size: 150%; }
 | 
| 
 | 
    30   </style>
 | 
| 
 | 
    31 </head>
 | 
| 
 | 
    32 <body>
 | 
| 
 | 
    33   <div id="content">
 | 
| 
 | 
    34     <h1>Konversi buat nitip</h1>
 | 
| 
 | 
    35     <form>
 | 
| 
 | 
    36       <p>
 | 
| 
 | 
    37         <label for="x">Jumlah dalam yen:</label>
 | 
| 
 | 
    38         <br>
 | 
| 
 | 
    39         <input id="x" name="x" type="number" autofocus>
 | 
| 
 | 
    40       </p>
 | 
| 
 | 
    41       <p>
 | 
| 
 | 
    42         <button type="submit">Hitung</button>
 | 
| 
 | 
    43         <button type="reset">Hapus</button>
 | 
| 
 | 
    44       </p>
 | 
| 
 | 
    45     </form>
 | 
| 
 | 
    46     <div class="js" id="loading">
 | 
| 
 | 
    47       <p>Memuat data nilai tukar...</p>
 | 
| 
 | 
    48     </div>
 | 
| 
 | 
    49     <div class="js" id="ok">
 | 
| 
 | 
    50       <p>
 | 
| 
 | 
    51         Biaya:
 | 
| 
 | 
    52       </p>
 | 
| 
 | 
    53       <ul>
 | 
| 
 | 
    54         <li>
 | 
| 
 | 
    55           Bank transfer:
 | 
| 
 | 
    56           <span id="result-bank"></span> IDR
 | 
| 
 | 
    57           (<span id="rate-text"></span> IDR/JPY)
 | 
| 
 | 
    58         </li>
 | 
| 
4
 | 
    59 
 | 
| 
 | 
    60         <li>
 | 
| 
 | 
    61           Bank transfer (alt):
 | 
| 
 | 
    62           <span id="result-bank-bni"></span> IDR
 | 
| 
 | 
    63           (<span id="rate-text-bni"></span> IDR/JPY)
 | 
| 
 | 
    64         </li>
 | 
| 
 | 
    65 
 | 
| 
0
 | 
    66         <li>
 | 
| 
 | 
    67           PayPal:
 | 
| 
 | 
    68           <span id="result-paypal"></span> JPY
 | 
| 
 | 
    69         </li>
 | 
| 
 | 
    70       </ul>
 | 
| 
 | 
    71     </div>
 | 
| 
 | 
    72     <div class="js" id="error">
 | 
| 
 | 
    73       <p>Koneksi ke server nilai tukar bermasalah.</p>
 | 
| 
 | 
    74     </div>
 | 
| 
 | 
    75 
 | 
| 
 | 
    76     <hr>
 | 
| 
 | 
    77     <ul>
 | 
| 
 | 
    78       <li>Ongkir, cukai, dll tidak termasuk.</li>
 | 
| 
 | 
    79       <li>Berhubung sudah punya timbangan, ongkir (estimasi) bisa dihitung sebelum dikirim.</li>
 | 
| 
 | 
    80       <li><a href="http://www.post.japanpost.jp/int/charge/list/ems1_en.html">Tabel ongkir EMS</a>.</li>
 | 
| 
 | 
    81       <li>Perhitungan:
 | 
| 
 | 
    82         <ul>
 | 
| 
 | 
    83           <li>Bank: <code>jumlah × 1.07 × nilai_tukar</code>, dibulatkan ke seribuan terdekat.</li>
 | 
| 
13
 | 
    84           <li>Bank (alt): <code>jumlah × 1.02 × nilai_tukar + (25000 * ceil(jumlah / 35000))</code>, dibulatkan ke seribuan terdekat. Rekeningnya sama.</li>
 | 
| 
0
 | 
    85           <li>PayPal: <code>jumlah × 1.05</code>, dibulatkan ke satuan terdekat.</li>
 | 
| 
 | 
    86         </ul>
 | 
| 
 | 
    87       </li>
 | 
| 
 | 
    88       <li>Jangan lupa memastikan jumlah setelah pajak dan ongkir (lokal).</li>
 | 
| 
 | 
    89       <li>Data nilai tukar didapat dari layanan <a href="http://fixer.io/">Fixer.io</a>.</li>
 | 
| 
10
 | 
    90       <li>Data nilai tukar "(alt)" didapat dari <a href="http://bni.co.id/informasivalas.aspx">BNI</a>.</li>
 | 
| 
0
 | 
    91     </ul>
 | 
| 
 | 
    92   </div>
 | 
| 
 | 
    93 
 | 
| 
2
 | 
    94   <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
 | 
| 
0
 | 
    95   <script>
 | 
| 
4
 | 
    96     var input = function() { return parseFloat($xForm.val()); }
 | 
| 
 | 
    97 
 | 
| 
 | 
    98     var $loading = $("#loading");
 | 
| 
 | 
    99     var $doButton = $("button[type=submit]");
 | 
| 
 | 
   100     var $xForm = $("#x");
 | 
| 
 | 
   101 
 | 
| 
 | 
   102     var locks = {};
 | 
| 
 | 
   103     var lock = function(isLoading) {
 | 
| 
7
 | 
   104       if (!isLoading && (locks.fixer === true || locks.bni === true)) { return; }
 | 
| 
4
 | 
   105       $loading.toggle(isLoading);
 | 
| 
 | 
   106       $doButton.attr("disabled", isLoading);
 | 
| 
 | 
   107     };
 | 
| 
 | 
   108 
 | 
| 
 | 
   109     var rates = {};
 | 
| 
 | 
   110 
 | 
| 
 | 
   111     var displayResult = function() {
 | 
| 
 | 
   112       if (rates.fixer === undefined || rates.bni === undefined) { return; }
 | 
| 
 | 
   113       var x = input();
 | 
| 
 | 
   114 
 | 
| 
 | 
   115       $("#rate-text").text(rates.fixer.toLocaleString());
 | 
| 
11
 | 
   116       $("#result-bank").text((Math.ceil(x * 1.07 * rates.fixer / 1000) * 1000).toLocaleString());
 | 
| 
4
 | 
   117 
 | 
| 
 | 
   118       if (rates.bni !== 0) {
 | 
| 
 | 
   119         $("#rate-text-bni").text(rates.bni.toLocaleString());
 | 
| 
13
 | 
   120         $("#result-bank-bni").text((Math.ceil(x * 1.02 * rates.bni / 1000) * 1000 + (25000 * Math.ceil(x / 35000))).toLocaleString());
 | 
| 
4
 | 
   121       } else {
 | 
| 
 | 
   122         $("#rate-text-bni").text('x');
 | 
| 
 | 
   123         $("#result-bank-bni").text('x');
 | 
| 
 | 
   124       };
 | 
| 
 | 
   125 
 | 
| 
 | 
   126       $("#result-paypal").text((Math.round(x * 1.05)).toLocaleString());
 | 
| 
 | 
   127       $("#ok").show();
 | 
| 
 | 
   128       lock(false);
 | 
| 
 | 
   129     };
 | 
| 
 | 
   130 
 | 
| 
12
 | 
   131     var fetchFixer = function() {
 | 
| 
 | 
   132       if (rates.fixer !== undefined) { return; }
 | 
| 
 | 
   133 
 | 
| 
 | 
   134       lock(true);
 | 
| 
 | 
   135       locks.fixer = true;
 | 
| 
 | 
   136 
 | 
| 
 | 
   137       $.getJSON("https://api.fixer.io/latest", { base: "JPY", symbols: "IDR" })
 | 
| 
 | 
   138       .done(function(data) {
 | 
| 
 | 
   139         rates.fixer = parseFloat(data.rates["IDR"]);
 | 
| 
 | 
   140 
 | 
| 
 | 
   141         displayResult();
 | 
| 
 | 
   142       })
 | 
| 
 | 
   143       .fail(function() {
 | 
| 
 | 
   144         $("#error").show();
 | 
| 
 | 
   145       })
 | 
| 
 | 
   146       .always(function() {
 | 
| 
 | 
   147         locks.fixer = false;
 | 
| 
 | 
   148         lock(false);
 | 
| 
 | 
   149       });
 | 
| 
 | 
   150     };
 | 
| 
 | 
   151 
 | 
| 
 | 
   152     var fetchBni = function() {
 | 
| 
 | 
   153       if (rates.bni !== undefined) { return; }
 | 
| 
 | 
   154 
 | 
| 
 | 
   155       lock(true);
 | 
| 
 | 
   156       locks.bni = true;
 | 
| 
 | 
   157 
 | 
| 
 | 
   158       $.get("bni-jpyidr.txt")
 | 
| 
 | 
   159       .done(function(data) {
 | 
| 
 | 
   160         if (data === "") {
 | 
| 
 | 
   161           rates.bni = 0;
 | 
| 
 | 
   162         } else {
 | 
| 
 | 
   163           rates.bni = parseFloat(data);
 | 
| 
 | 
   164         }
 | 
| 
 | 
   165 
 | 
| 
 | 
   166         displayResult();
 | 
| 
 | 
   167       })
 | 
| 
 | 
   168       .fail(function() {
 | 
| 
 | 
   169         $("#error").show();
 | 
| 
 | 
   170       })
 | 
| 
 | 
   171       .always(function() {
 | 
| 
 | 
   172         locks.bni = false;
 | 
| 
 | 
   173         lock(false);
 | 
| 
 | 
   174       });
 | 
| 
 | 
   175     };
 | 
| 
 | 
   176 
 | 
| 
4
 | 
   177     var action = function(e) {
 | 
| 
 | 
   178       e.preventDefault()
 | 
| 
 | 
   179       $(".js").hide()
 | 
| 
 | 
   180 
 | 
| 
 | 
   181       var x = input();
 | 
| 
 | 
   182 
 | 
| 
 | 
   183       if (x === NaN || x === undefined) { return false; };
 | 
| 
0
 | 
   184 
 | 
| 
12
 | 
   185       fetchFixer();
 | 
| 
 | 
   186       fetchBni();
 | 
| 
4
 | 
   187 
 | 
| 
 | 
   188       displayResult();
 | 
| 
 | 
   189     };
 | 
| 
 | 
   190 
 | 
| 
0
 | 
   191     $("form").submit(action)
 | 
| 
4
 | 
   192     $("button[type=reset]").click(function(e) { xForm.focus(); });
 | 
| 
0
 | 
   193   </script>
 | 
| 
 | 
   194 </body>
 |