blob: c1ba53d37fb759aad74c1c538794e281beb87f69 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
open Piaf
type pool = ((module Rapper_helper.CONNECTION), Caqti_error.t) Caqti_eio.Pool.t
let create_transaction client_id (db_pool : pool) (request : Request.t) =
Caqti_eio.Pool.use
(fun conn ->
let module C = (val conn : Rapper_helper.CONNECTION) in
C.with_transaction
@@ fun () ->
ignore @@ Query.lock client_id conn;
let client_opt =
Option.join @@ Result.to_option @@ Query.find_client client_id conn
in
match client_opt with
| Some client ->
let body = Result.to_option @@ Body.to_string request.body in
let json =
Option.map
(fun str ->
try Yojson.Safe.from_string str with
| _ -> `Null)
body
in
let decoded_op = Option.bind json (Utils.Decoder.decode Operation.decoder) in
let insert_result =
match decoded_op with
| Some (`Credit { value = _value; description = _desc } as op) ->
(match Query.execute_transaction ~client_id ~op conn with
| Ok _ as ok -> ok
| Error e -> Error (`DB e))
| Some (`Debit { value; description = _desc } as op) ->
let valid_debit =
let balance_after_op = client.balance - value in
not (balance_after_op < client.mov_limit * -1)
in
if valid_debit
then (
match Query.execute_transaction ~client_id ~op conn with
| Ok _ as ok -> ok
| Error e -> Error (`DB e))
else Error `InvalidValue
| None -> Error (`Decoder "Invalid operation")
in
(match insert_result with
| Ok () ->
let client =
Option.get
@@ Option.join
@@ Result.to_option
@@ Query.find_client client_id conn
in
let json : Yojson.Safe.t =
`Assoc [ "limite", `Int client.mov_limit; "saldo", `Int client.balance ]
in
Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK)
| Error _ -> Ok (Response.create (`Code 422)))
| None ->
Logs.info (fun m -> m "Não encontrei o cliente %d" client_id);
Ok (Response.create `Not_found))
db_pool
;;
let get_balance client_id (db_pool : pool) (_request : Request.t) =
Caqti_eio.Pool.use
(fun conn ->
let client_opt =
Option.join @@ Result.to_option @@ Query.find_client client_id conn
in
match client_opt with
| Some client ->
let transaction_list =
(* NOTE: Talvez isso aqui não seja uma boa ideia *)
Result.fold ~ok:Fun.id ~error:(fun _ -> []) @@ Query.transactions client_id conn
in
let json =
let time = Option.get @@ Ptime.of_float_s (Unix.time ()) in
Serializer.bank_statement time client transaction_list
in
Ok (Response.of_string ~body:(Yojson.Safe.to_string json) `OK)
| None ->
Logs.info (fun m -> m "Não encontrei o cliente %d" client_id);
Ok (Response.create `Not_found))
db_pool
;;
|