contrib: Kill `refund`
[nit.git] / contrib / refund / src / refund_json.nit
diff --git a/contrib/refund/src/refund_json.nit b/contrib/refund/src/refund_json.nit
deleted file mode 100644 (file)
index 7c5e4d0..0000000
+++ /dev/null
@@ -1,351 +0,0 @@
-# This file is part of NIT ( http://www.nitlanguage.org ).
-#
-# Copyright 2015 Alexandre Terrasa <alexandre@moz-code.org>
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#     http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# JSON handling for `refund`.
-module refund_json
-
-import refund_base
-import json::static
-
-redef class RefundProcessor
-
-       redef fun process(input_file, output_file) do
-               self.output_file = output_file
-               var json = load_input(input_file)
-               var sheet = new ReclamationSheet.from_json(self, json)
-               var res = process_refunds(sheet)
-               write_output(res.to_pretty_json, output_file)
-       end
-
-       # Computes allowed refunds for a given `ReclamationSheet`.
-       fun process_refunds(sheet: ReclamationSheet): JsonObject do
-               # update stats
-               var stats = load_stats
-               stats.inc("total_treatments")
-               # compute refunds
-               current_refunds.clear
-               var json = new JsonObject
-               json["dossier"] = sheet.file.to_s
-               json["mois"] = sheet.month.to_s
-               var arr = new JsonArray
-               var sum = 0.0.to_dollar
-               for recl in sheet.recls do
-                       var refund = process_refund(sheet, recl)
-                       var obj = new JsonObject
-                       obj["soin"] = recl.care_id
-                       obj["date"] = recl.date.to_s
-                       obj["montant"] = refund.to_s
-                       arr.add obj
-                       sum += refund
-                       # update stats for care
-                       stats.inc("total_{recl.care_id}")
-               end
-               save_stats(stats)
-               json["remboursements"] = arr
-               json["total"] = sum.to_s
-               return json
-       end
-
-       # Loads the input string and returns its content as a JsonObject.
-       #
-       # Dies if the file cannot be read or does not contain a valid JSONObject.
-       fun load_input(file: String): JsonObject do
-               if not file.file_exists then
-                       die("File `{file}` not found.")
-                       abort
-               end
-               var ptr = new FileReader.open(file)
-               var json = ptr.read_all.parse_json
-               if json isa JsonParseError then
-                       die("Wrong input file ({json.message})")
-                       abort
-               else if json == null then
-                       die("Unable to parse input file as json (got null)")
-                       abort
-               else if not json isa JsonObject then
-                       die("Wrong input type (expected JsonObject got {json.class_name})")
-                       abort
-               end
-               ptr.close
-               return json
-       end
-
-       # Writes `str` in path specified by `file`.
-       #
-       # Used to produce output and stats.
-       fun write_output(str: String, file: String) do
-               var ofs = new FileWriter.open(file)
-               ofs.write(str)
-               ofs.write("\n")
-               ofs.close
-       end
-
-       # UTILS
-
-       # Does `json` contains `key`? Dies otherwise.
-       private fun check_key(json: JsonObject, key: String) do
-               if json.has_key(key) then return
-               die("Malformed input (missing key {key})")
-       end
-
-       # Does `str` match the regex `re`.
-       private fun check_format(str, re: String): Bool do
-               return str.has(re.to_re)
-       end
-
-       redef fun die(msg) do
-               # save error
-               var obj = new JsonObject
-               obj["message"] = msg
-               write_output(obj.to_pretty_json, output_file)
-               # update stats
-               var stats = load_stats
-               stats.inc("total_reject")
-               save_stats(stats)
-               # leave
-               exit 1
-       end
-
-       redef fun show_stats do print load_stats.to_json_object.to_pretty_json
-
-       redef fun load_stats do
-               # If no stats found, return a new object
-               if not stats_file.file_exists then return new RefundStats
-               # Try to read from file
-               var ifs = new FileReader.open(stats_file)
-               var content = ifs.read_all.parse_json
-               ifs.close
-               # If file is corrupted, return a new object
-               if not content isa JsonObject then return new RefundStats
-               # Return file contained stats
-               return new RefundStats.from_json(content)
-       end
-
-       redef fun save_stats(stats) do
-               write_output(stats.to_json_object.to_pretty_json, stats_file)
-       end
-end
-
-redef class RefundStats
-
-       # Inits `self` from the content of a JsonObject
-       init from_json(json: JsonObject) do
-               for k, v in json do self[k] = v.as(Int)
-       end
-
-       # Outputs `self` as a JSON string.
-       fun to_json_object: JsonObject do
-               var obj = new JsonObject
-               for k, v in self do obj[k] = v
-               return obj
-       end
-end
-
-redef class ReclamationSheet
-
-       # Inits `self` from the content of a `JsonObject`.
-       init from_json(proc: RefundProcessor, json: JsonObject) do
-               file = new ReclFile.from_json(proc, json)
-               month = new ReclMonth.from_json(proc, json)
-               recls = parse_recls(proc, json)
-               init(file, month)
-       end
-
-       # Parses and checks the given `json` then returns an array of `Reclamation` instances.
-       private fun parse_recls(proc: RefundProcessor, json: JsonObject): Array[Reclamation] do
-               proc.check_key(json, "reclamations")
-               var res = new Array[Reclamation]
-               var recls = json["reclamations"]
-               if recls == null then
-                       proc.die("Wrong type for `number` (expected JsonArray got null)")
-                       abort
-               else if not recls isa JsonArray then
-                       proc.die("Wrong type for `number` (expected JsonArray got {recls.class_name})")
-                       abort
-               end
-               var i = 0
-               for obj in recls do
-                       if obj == null then
-                               proc.die("Wrong type for `reclamations#{i}` (expected JsonObject got null)")
-                               abort
-                       else if not obj isa JsonObject then
-                               proc.die("Wrong type for `reclamations#{i}` " +
-                                       "(expected JsonObject got {obj.class_name})")
-                               abort
-                       end
-                       var recl = new Reclamation.from_json(proc, obj)
-                       if not month.has(recl.date) then
-                               proc.die("Wrong `mois` for `soin` with id `{recl.care_id}`")
-                               abort
-                       end
-                       if file.contract.care_by_id(recl.care_id) == null then
-                               proc.die("Unknown `soin` with id `{recl.care_id}`")
-                               abort
-                       end
-                       res.add recl
-                       i += 1
-               end
-               return res
-       end
-end
-
-redef class ReclFile
-       # Inits `self` from the content of a JsonObject.
-       init from_json(proc: RefundProcessor, json: JsonObject) do
-               proc.check_key(json, "dossier")
-               var id = json["dossier"]
-               if id == null then
-                       proc.die("Wrong type for `dossier` (expected String got null)")
-                       abort
-               else if not id isa String then
-                       proc.die("Wrong type for `dossier` (expected String got {id.class_name})")
-                       abort
-               end
-               # Check format
-               parse_contract(proc, id)
-               parse_client(proc, id)
-               init(id)
-       end
-
-       # Tries to parse the contract from `file_id` string.
-       private fun parse_contract(proc: RefundProcessor, file_id: String) do
-               var kind = file_id.first.to_s
-               if not proc.check_format(kind, "^[A-E]\{1\}$") then
-                       proc.die("Wrong contract (expected A, B, C, D or E got {kind})")
-               end
-               contract = contract_factory(proc, kind)
-       end
-
-       # Tries to parse the client number from the `file_id` string.
-       private fun parse_client(proc: RefundProcessor, file_id: String) do
-               var num = file_id.substring_from(1)
-               if not proc.check_format(num, "^[0-9]\{6\}$") then
-                       proc.die("Wrong format for `number` (expected XXXXXX got {num})")
-                       abort
-               end
-               client = new Client(num)
-       end
-end
-
-redef class ReclMonth
-       # Inits `self` from a `JsonObject`.
-       init from_json(proc: RefundProcessor, json: JsonObject) do
-               proc.check_key(json, "mois")
-               var month = json["mois"]
-               if month == null then
-                       proc.die("Wrong type for `mois` (expected String got null)")
-                       return
-               else if not month isa String then
-                       proc.die("Wrong type for `mois` (expected String got {month.class_name})")
-                       return
-               end
-               if not proc.check_format(month, "^[0-9]\{4\}-[0-9]\{2\}$") then
-                       proc.die("Wrong format for `mois` (expected AAAA-MM got {month})")
-                       return
-               end
-               from_string(proc, month)
-       end
-
-       # Inits `self` from a string representation formatted as `AAAA-MM`.
-       init from_string(proc: RefundProcessor, str: String) do
-               var parts = str.split("-")
-               var year = parts[0].to_i
-               var month = parts[1].to_i
-               if month < 1 or month > 12 then
-                       proc.die("Wrong format for `mois` (expected AAAA-MM got {str})")
-                       return
-               end
-               date = new ReclDate(year, month, 1)
-               init(date)
-       end
-end
-
-redef class ReclDate
-       # Inits `self` from a `JsonObject`.
-       #
-       # Dies if the `json` input is invalid.
-       init from_json(proc: RefundProcessor, json: JsonObject) do
-               proc.check_key(json, "date")
-               var date = json["date"]
-               if date == null then
-                       proc.die("Wrong type for `date` (expected String got null)")
-                       abort
-               else if not date isa String then
-                       proc.die("Wrong type for `date` (expected String got {date.class_name})")
-                       abort
-               end
-               if not proc.check_format(date, "^[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}$") then
-                       proc.die("Wrong format for `date` (expected AAAA-MM-DD got {date})")
-                       abort
-               end
-               from_string(proc, date)
-       end
-
-       # Inits `self` from its string representation formatted as `AAAA-MM`.
-       init from_string(proc: RefundProcessor, str: String) do
-               var parts = str.split("-")
-               year = parts[0].to_i
-               month = parts[1].to_i
-               day = parts[2].to_i
-               if month < 1 or month > 12 or day < 1 or day > 31 then
-                       proc.die("Wrong format for `mois` (expected AAAA-MM got {str})")
-                       abort
-               end
-               init(year, month, day)
-       end
-end
-
-redef class Reclamation
-       # Inits `self` from a `JsonObject`.
-       init from_json(proc: RefundProcessor, json: JsonObject) do
-               care_id = parse_care_id(proc, json)
-               date = new ReclDate.from_json(proc, json)
-               fees = parse_fees(proc, json)
-               init(care_id, date, fees)
-       end
-
-       # Inits `self` from its string representation formatted as `Int`.
-       private fun parse_care_id(proc: RefundProcessor, json: JsonObject): Int do
-               proc.check_key(json, "soin")
-               var id = json["soin"]
-               if id == null then
-                       proc.die("Wrong type for `soin` (expected Int got null)")
-                       abort
-               else if not id isa Int then
-                       proc.die("Wrong type for `soin` (expected Int got {id.class_name})")
-                       abort
-               end
-               return id
-       end
-
-       # Inits `self` from its string representation formatted as `0.00$`.
-       private fun parse_fees(proc: RefundProcessor, json: JsonObject): Dollar do
-               proc.check_key(json, "montant")
-               var fees = json["montant"]
-               if fees == null then
-                       proc.die("Wrong type for `fees` (expected String got null)")
-                       abort
-               else if not fees isa String then
-                       proc.die("Wrong type for `fees` (expected String got {fees.class_name})")
-                       abort
-               end
-               if not proc.check_format(fees, "^[0-9]+((\\.|\\,)[0-9]+)?\\$$") then
-                       proc.die("Wrong format for `montant` (expected XX.XX$ got {fees})")
-                       abort
-               end
-               return new Dollar.from_float(fees.basename("$").to_f)
-       end
-end