let optstring = function Some s -> s | None -> "" type mvt = { year : int; month : int; day : int; category : string; subcategory : string; amount : float; account : string; payee : string; notes : string; } let mvt year month day category subcategory amount account payee notes = { year = truncate year; month = truncate month; day = truncate day; category; subcategory = optstring subcategory; amount; account; payee; notes = optstring notes; } let after y m d l = Printf.sprintf "%04d-%02d-%02d" l.year l.month l.day > Printf.sprintf "%04d-%02d-%02d" y m d let until y m d l = Printf.sprintf "%04d-%02d-%02d" l.year l.month l.day <= Printf.sprintf "%04d-%02d-%02d" y m d let is_account_caisse m = m.account = "CAISSE" let is_account_courant m = m.account = "COURANT" let any_account _ = true let mvts fn = Sqlite3_utils.( with_db fn (fun db -> exec db "select Year, Month, Day, Category, Subcategory, Amount, \ AccountName, Payee, Notes from alldata" ~ty: Ty. ( nil, p3 float float float @>> p2 text (nullable text) @>> p1 float @>> p3 text text (nullable text), mvt ) ~f:Cursor.to_list)) |> Rresult.R.get_ok let solde ~cpt_filter ~at:(y, m, d) mvts = mvts |> List.filter (until y m d) |> List.filter cpt_filter |> List.map (fun m -> m.amount) |> List.fold_left ( +. ) 0. let balance ~cpt_filter ~from ~until mvts = solde ~cpt_filter ~at:until mvts -. solde ~cpt_filter ~at:from mvts let bilan ~cpt_filter ~from:(fy, fm, fd) ~until:(uy, um, ud) mvts () = let t = Hashtbl.create 164 in mvts |> List.filter (after fy fm fd) |> List.filter (until uy um ud) |> List.filter cpt_filter |> List.iter (fun mvt -> let i = mvt.category ^ ":" ^ mvt.subcategory in match Hashtbl.find_opt t i with | None -> Hashtbl.add t i mvt.amount | Some a -> Hashtbl.replace t i (mvt.amount +. a)); Hashtbl.iter (fun cat mont -> if mont < 0. then Printf.printf "%50s\t%04.02f\n" cat mont) t; Hashtbl.iter (fun cat mont -> if mont >= 0. then Printf.printf "%50s\t%04.02f\n" cat mont) t let main ~from:((yf, mf, df) as from) ~until:((yu, mu, du) as until) () = let ops = mvts "/home/matt/Téléchargements/NOVEMBRE2.mmb_update_2019-11-12.mmb" in let caisse_dbt = solde ~cpt_filter:is_account_caisse ~at:from ops and caisse_fin = solde ~cpt_filter:is_account_caisse ~at:until ops and courant_dbt = solde ~cpt_filter:is_account_courant ~at:from ops and courant_fin = solde ~cpt_filter:is_account_courant ~at:until ops in Printf.printf "%04d-%02d-%02d\n" yf mf df; Printf.printf "CAISSE : %.2f\n" caisse_dbt; Printf.printf "COURANT : %.2f\n" courant_dbt; bilan ~cpt_filter:any_account ~from ~until ops (); Printf.printf "%04d-%02d-%02d\n" yu mu du; Printf.printf "CAISSE : %.2f\n" caisse_fin; Printf.printf "COURANT : %.2f\n" courant_fin let () = main ~from:(2018, 11, 25) ~until:(2019, 10, 31) ()