diff options
author | Ismaël Bouya <ismael.bouya@normalesup.org> | 2015-01-13 23:35:48 +0100 |
---|---|---|
committer | Ismaël Bouya <ismael.bouya@normalesup.org> | 2015-01-13 23:35:48 +0100 |
commit | 5172ecf855078938b00e9ac7f8dee2c2676f6e53 (patch) | |
tree | 586d6285d6d2aeb66a7a2458e01541ed78c8e174 /comptes | |
download | Public-5172ecf855078938b00e9ac7f8dee2c2676f6e53.tar.gz Public-5172ecf855078938b00e9ac7f8dee2c2676f6e53.tar.zst Public-5172ecf855078938b00e9ac7f8dee2c2676f6e53.zip |
Commit initial
Diffstat (limited to 'comptes')
-rwxr-xr-x | comptes | 446 |
1 files changed, 446 insertions, 0 deletions
@@ -0,0 +1,446 @@ | |||
1 | #!/usr/bin/en perl | ||
2 | # The MIT License (MIT) | ||
3 | # | ||
4 | # Copyright (c) 2011-2015 Ismaël Bouya http://www.normalesup.org/~bouya/ | ||
5 | # | ||
6 | # Permission is hereby granted, free of charge, to any person obtaining a copy | ||
7 | # of this software and associated documentation files (the "Software"), to deal | ||
8 | # in the Software without restriction, including without limitation the rights | ||
9 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
10 | # copies of the Software, and to permit persons to whom the Software is | ||
11 | # furnished to do so, subject to the following conditions: | ||
12 | # | ||
13 | # The above copyright notice and this permission notice shall be included in | ||
14 | # all copies or substantial portions of the Software. | ||
15 | # | ||
16 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
17 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
18 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
19 | # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
20 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
21 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
22 | # THE SOFTWARE. | ||
23 | |||
24 | use Switch; | ||
25 | use strict; | ||
26 | |||
27 | my $file = "comptes.data"; | ||
28 | |||
29 | my @actions=('Ajouter un participant'); | ||
30 | my %participants = (); | ||
31 | my @transactions = (); | ||
32 | my @descriptions = (); | ||
33 | my $evenement_def; | ||
34 | my $remboursements = ""; | ||
35 | |||
36 | if($#ARGV==0) { | ||
37 | open FILE, $ARGV[0] || die "Impossible de lire le fichier"; | ||
38 | $evenement_def = <FILE>; | ||
39 | chomp($evenement_def); | ||
40 | while(my $noms = <FILE>) { | ||
41 | if($noms eq "\n") { last; } | ||
42 | my ($numero,$nom) = split(/ /,$noms,2); | ||
43 | chomp($nom); | ||
44 | $participants{$nom} = $numero; | ||
45 | } | ||
46 | while(my $transaction = <FILE>) { | ||
47 | if($transaction eq "\n") { last; } | ||
48 | chomp($transaction); | ||
49 | push(@transactions,$transaction); | ||
50 | my $description = <FILE>; | ||
51 | chomp($description); | ||
52 | push(@descriptions,$description); | ||
53 | } | ||
54 | $file = $ARGV[0]; | ||
55 | } | ||
56 | |||
57 | GLOBALE: while(1) { | ||
58 | if(keys(%participants)>0) { | ||
59 | $actions[1]="Ajouter une dépense"; | ||
60 | $actions[2]="Enregistrer"; | ||
61 | } | ||
62 | if(scalar(@transactions)>0) { | ||
63 | $actions[3]="Voir les dépenses de quelqu'un"; | ||
64 | $actions[2]="Enregistrer"; | ||
65 | $actions[4]="Equilibrage"; | ||
66 | $actions[5]="Voir une transaction"; | ||
67 | } | ||
68 | |||
69 | my $action; | ||
70 | while(1) { | ||
71 | my $i = 1; | ||
72 | my $var; | ||
73 | my @vart = ( @actions, 'Sortir' ); | ||
74 | my $message = ''; | ||
75 | foreach $var ( @vart ) { | ||
76 | $message .= $i++.') '.$var."\n"; | ||
77 | } | ||
78 | print $message; | ||
79 | $var = <STDIN>; | ||
80 | chop($var); | ||
81 | if(/\D/ || $var < 1 || $var > $i) { | ||
82 | print "Mauvaise entrée\n"; | ||
83 | next; | ||
84 | } | ||
85 | $action = $vart[$var-1]; | ||
86 | last; | ||
87 | } | ||
88 | switch ($action) { | ||
89 | case "Ajouter un participant" { | ||
90 | print "Nom du participant\n"; | ||
91 | my $participant = <STDIN>; | ||
92 | chomp($participant); | ||
93 | $participants{$participant} = keys(%participants)+1; | ||
94 | } | ||
95 | case "Ajouter une dépense" { | ||
96 | print "Qui a payé ?\n"; | ||
97 | my $paye; | ||
98 | while(1) { | ||
99 | my $i = 1; | ||
100 | my $var; | ||
101 | my @vart = ( keys(%participants), "Annuler" ); | ||
102 | foreach $var ( @vart ) { | ||
103 | print $i++.') '.$var."\n"; | ||
104 | } | ||
105 | $var = <STDIN>; | ||
106 | chop($var); | ||
107 | if(/\D/ || $var < 1 || $var > $i) { | ||
108 | print "Mauvaise entrée\n"; | ||
109 | next; | ||
110 | } | ||
111 | $paye = $vart[$var-1]; | ||
112 | last; | ||
113 | } | ||
114 | if($paye eq "Annuler") { | ||
115 | next GLOBALE; | ||
116 | } | ||
117 | print "Quoi ?\n"; | ||
118 | my $description = <STDIN>; | ||
119 | chomp($description); | ||
120 | print "Combien ?\n"; | ||
121 | my $prix = <STDIN>; | ||
122 | chomp($prix); | ||
123 | print "Pour qui ?\n"; | ||
124 | my $repartition = ""; | ||
125 | my $total_parts = 0; | ||
126 | DESTS: while(1) { | ||
127 | my $dest; | ||
128 | while(1) { | ||
129 | my $i = 1; | ||
130 | my $var; | ||
131 | my @vart = ( keys(%participants), "Ajouter à tous", "Fini" ); | ||
132 | foreach $var ( @vart ) { | ||
133 | print $i++.') '.$var."\n"; | ||
134 | } | ||
135 | $var = <STDIN>; | ||
136 | chop($var); | ||
137 | if(/\D/ || $var < 1 || $var > $i) { | ||
138 | print "Mauvaise entrée\n"; | ||
139 | next; | ||
140 | } | ||
141 | $dest = $vart[$var-1]; | ||
142 | last; | ||
143 | } | ||
144 | switch($dest) { | ||
145 | case "Fini" { | ||
146 | if($repartition eq "") { print "Annulé\n"; } | ||
147 | elsif($total_parts == 0) { | ||
148 | print "Le nombre total de parts est nul, il faut en ajouter !\n"; | ||
149 | next DESTS; | ||
150 | } | ||
151 | else { | ||
152 | push(@transactions, $participants{$paye}.' '.$prix.$repartition); | ||
153 | push(@descriptions, $description); | ||
154 | } | ||
155 | last DESTS; | ||
156 | } | ||
157 | case "Ajouter à tous" { | ||
158 | print "Nombre de parts ?\n"; | ||
159 | my $parts = <STDIN>; | ||
160 | chomp($parts); | ||
161 | if(!($parts == 0)) { | ||
162 | foreach my $participant (keys(%participants)) { | ||
163 | $repartition .= ' '.$participants{$participant}.':'.scalar($parts); | ||
164 | $total_parts += scalar($parts); | ||
165 | } | ||
166 | } | ||
167 | } | ||
168 | else { | ||
169 | print "Nombre de parts ?\n"; | ||
170 | my $parts = <STDIN>; | ||
171 | chomp($parts); | ||
172 | if(!($parts == 0)) { | ||
173 | $repartition .= ' '.$participants{$dest}.':'.scalar($parts); | ||
174 | $total_parts += scalar($parts); | ||
175 | } | ||
176 | } | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | case "Voir les dépenses de quelqu'un" { | ||
181 | my $personne; | ||
182 | while(1) { | ||
183 | my $i = 1; | ||
184 | my $var; | ||
185 | my @vart = ( keys(%participants), "Annuler" ); | ||
186 | foreach $var ( @vart ) { | ||
187 | print $i++.') '.$var."\n"; | ||
188 | } | ||
189 | $var = <STDIN>; | ||
190 | chop($var); | ||
191 | if(/\D/ || $var < 1 || $var > $i) { | ||
192 | print "Mauvaise entrée\n"; | ||
193 | next; | ||
194 | } | ||
195 | $personne = $vart[$var-1]; | ||
196 | last; | ||
197 | } | ||
198 | if($personne eq "Annuler") { | ||
199 | next GLOBALE; | ||
200 | } | ||
201 | my $depenses = 0; | ||
202 | my $frais = 0; | ||
203 | foreach my $transaction (@transactions) { | ||
204 | my @table_trans = split(/ /,$transaction); | ||
205 | my $payeur = shift(@table_trans); | ||
206 | my $prix = shift(@table_trans); | ||
207 | if($payeur == $participants{$personne}) { | ||
208 | $depenses += $prix; | ||
209 | } | ||
210 | my $parts = 0; | ||
211 | my $frac = 0; | ||
212 | my $repartition; | ||
213 | foreach $repartition (@table_trans) { | ||
214 | my ($pers,$part) = split(/:/,$repartition); | ||
215 | if($pers == $participants{$personne}) { | ||
216 | $frac += $part; | ||
217 | } | ||
218 | $parts += $part; | ||
219 | } | ||
220 | $frais += $prix*$frac/$parts; | ||
221 | } | ||
222 | print $personne." a payé ".$depenses." EUR\n"; | ||
223 | print "et a pour ".sprintf("%.2f",$frais)." EUR de frais au total.\n"; | ||
224 | print "Il a donc un solde de ".sprintf("%.2f",$depenses-$frais)." EUR\n"; | ||
225 | my $pause = <STDIN>; | ||
226 | } | ||
227 | case "Voir une transaction" { | ||
228 | my $transaction; | ||
229 | while(1) { | ||
230 | my $i = 1; | ||
231 | my $var; | ||
232 | my @vart = ( @descriptions, "Annuler" ); | ||
233 | foreach $var ( @vart ) { | ||
234 | print $i++.') '.$var."\n"; | ||
235 | } | ||
236 | $var = <STDIN>; | ||
237 | chop($var); | ||
238 | if(/\D/ || $var < 1 || $var > $i) { | ||
239 | print "Mauvaise entrée\n"; | ||
240 | next; | ||
241 | } | ||
242 | $transaction = $var-1; | ||
243 | last; | ||
244 | } | ||
245 | my @table_trans = split(/ /,$transactions[$transaction]); | ||
246 | my $payeur = shift(@table_trans); | ||
247 | my $prix = shift(@table_trans); | ||
248 | my $Tparts = 0; | ||
249 | my $repartition; | ||
250 | my %parts; | ||
251 | foreach my $pers (keys(%participants)) { | ||
252 | if($payeur == $participants{$pers}) { | ||
253 | print $descriptions[$transaction]." (payé par ".$pers."), ".$prix." EUR\n"; | ||
254 | last | ||
255 | } | ||
256 | } | ||
257 | foreach $repartition (@table_trans) { | ||
258 | my ($pers,$part) = split(/:/,$repartition); | ||
259 | $Tparts += $part; | ||
260 | $parts{$pers} += $part; | ||
261 | } | ||
262 | foreach my $pers (keys(%participants)) { | ||
263 | if(!exists $parts{$participants{$pers}}) { | ||
264 | next; | ||
265 | } | ||
266 | print $pers.", ".$parts{$participants{$pers}}." part(s), soit ". $prix*$parts{$participants{$pers}}/$Tparts." EUR\n"; | ||
267 | } | ||
268 | my $pause = <STDIN>; | ||
269 | } | ||
270 | case "Enregistrer" { | ||
271 | print "Nom de l'événement ?"; | ||
272 | if(!($evenement_def eq "")) { | ||
273 | print " [".$evenement_def."]"; | ||
274 | } | ||
275 | print "\n"; | ||
276 | my $evenement = <STDIN>; | ||
277 | chomp($evenement); | ||
278 | if($evenement eq "") { | ||
279 | $evenement = $evenement_def; | ||
280 | } | ||
281 | open FILE, ">".$file; | ||
282 | print FILE $evenement."\n"; | ||
283 | my $key; | ||
284 | foreach $key (keys(%participants)) { | ||
285 | print FILE $participants{$key}." ".$key."\n"; | ||
286 | } | ||
287 | print FILE "\n"; | ||
288 | for(my $i=0;$i<scalar(@transactions);$i++) { | ||
289 | print FILE $transactions[$i]."\n"; | ||
290 | print FILE $descriptions[$i]."\n"; | ||
291 | } | ||
292 | print FILE "\n"; | ||
293 | print FILE $remboursements; | ||
294 | close FILE; | ||
295 | } | ||
296 | case "Equilibrage" { | ||
297 | my %Tdepenses = (); | ||
298 | my %Tfrais = (); | ||
299 | my %Tsolde = (); | ||
300 | $remboursements = ""; | ||
301 | foreach my $Ttransaction (@transactions) { | ||
302 | my @Ttable_trans = split(/ /,$Ttransaction); | ||
303 | my $Tpayeur = shift(@Ttable_trans); | ||
304 | my $Tprix = shift(@Ttable_trans); | ||
305 | $Tdepenses{$Tpayeur} = $Tdepenses{$Tpayeur} + $Tprix; | ||
306 | my $Tparts = 0; | ||
307 | my $Tfrac = 0; | ||
308 | my $Trepartition; | ||
309 | foreach $Trepartition (@Ttable_trans) { | ||
310 | my ($Tpers,$Tpart) = split(/:/,$Trepartition); | ||
311 | $Tparts += $Tpart; | ||
312 | } | ||
313 | foreach $Trepartition (@Ttable_trans) { | ||
314 | my ($Tpers,$Tpart) = split(/:/,$Trepartition); | ||
315 | $Tfrais{$Tpers} = $Tfrais{$Tpers} + $Tprix*$Tpart/$Tparts; | ||
316 | } | ||
317 | } | ||
318 | foreach my $Tpersonne (keys(%participants)) { | ||
319 | my $numero = $participants{$Tpersonne}; | ||
320 | $Tsolde{$Tpersonne} = sprintf("%.2f",$Tdepenses{$numero}-$Tfrais{$numero}); | ||
321 | print $Tpersonne." a un solde de ".$Tsolde{$Tpersonne}." EUR\n"; | ||
322 | } | ||
323 | my $pause = <STDIN>; | ||
324 | print "Y-a-t-il des remboursements plus aisés ?\n"; | ||
325 | my $ouinon; | ||
326 | while(1) { | ||
327 | my $i = 1; | ||
328 | my $var; | ||
329 | my @vart = ( "Oui", "Non" ); | ||
330 | foreach $var ( @vart ) { | ||
331 | print $i++.') '.$var."\n"; | ||
332 | } | ||
333 | $var = <STDIN>; | ||
334 | chop($var); | ||
335 | if(/\D/ || $var < 1 || $var > $i) { | ||
336 | print "Mauvaise entrée\n"; | ||
337 | next; | ||
338 | } | ||
339 | $ouinon = $vart[$var-1]; | ||
340 | last; | ||
341 | } | ||
342 | AISE: while($ouinon eq "Oui") { | ||
343 | print "Qui ?\n"; | ||
344 | my $personne; | ||
345 | while(1) { | ||
346 | my $i = 1; | ||
347 | my $var; | ||
348 | my @vart = ( keys(%participants), "Fini" ); | ||
349 | foreach $var ( @vart ) { | ||
350 | print $i++.') '.$var."\n"; | ||
351 | } | ||
352 | $var = <STDIN>; | ||
353 | chop($var); | ||
354 | if(/\D/ || $var < 1 || $var > $i) { | ||
355 | print "Mauvaise entrée\n"; | ||
356 | next; | ||
357 | } | ||
358 | $personne = $vart[$var-1]; | ||
359 | last; | ||
360 | } | ||
361 | if($personne eq "Fini") { last AISE; } | ||
362 | print "Avec qui ?\n"; | ||
363 | my $personneb; | ||
364 | while(1) { | ||
365 | my $i = 1; | ||
366 | my $var; | ||
367 | my @vart = ( keys(%participants), "Annuler" ); | ||
368 | foreach $var ( @vart ) { | ||
369 | print $i++.') '.$var."\n"; | ||
370 | } | ||
371 | $var = <STDIN>; | ||
372 | chop($var); | ||
373 | if(/\D/ || $var < 1 || $var > $i) { | ||
374 | print "Mauvaise entrée\n"; | ||
375 | next; | ||
376 | } | ||
377 | $personneb = $vart[$var-1]; | ||
378 | last; | ||
379 | } | ||
380 | if($personneb eq "Annuler") { next AISE; } | ||
381 | if($Tsolde{$personne}*$Tsolde{$personneb}<0) { | ||
382 | my $pers_inf = ($Tsolde{$personne}<0)?$personne:$personneb; | ||
383 | my $pers_sup = ($Tsolde{$personne}>0)?$personne:$personneb; | ||
384 | my $inf = (abs($Tsolde{$personne})<abs($Tsolde{$personneb}))?abs($Tsolde{$personne}):abs($Tsolde{$personneb}); | ||
385 | $remboursements .= $pers_inf." doit ".$inf." EUR à ".$pers_sup."\n"; | ||
386 | $Tsolde{$pers_inf} += $inf; | ||
387 | $Tsolde{$pers_sup} -= $inf; | ||
388 | } | ||
389 | } | ||
390 | # Une boucle pour détecter si on a des couples qui s'annulent mutuellement | ||
391 | COUPLE: foreach my $personne (keys(%participants)) { | ||
392 | if($Tsolde{$personne} == 0) { next; } | ||
393 | foreach my $personneb (keys(%participants)) { | ||
394 | if($Tsolde{$personneb} + $Tsolde{$personne} != 0) { next; } | ||
395 | my $pers_inf = ($Tsolde{$personne}<0)?$personne:$personneb; | ||
396 | my $pers_sup = ($Tsolde{$personne}>0)?$personne:$personneb; | ||
397 | my $val = abs($Tsolde{$personne}); | ||
398 | $remboursements .= $pers_inf." doit ".$val." EUR à ".$pers_sup."\n"; | ||
399 | $Tsolde{$pers_inf} += $val; | ||
400 | $Tsolde{$pers_sup} -= $val; | ||
401 | next COUPLE; | ||
402 | } | ||
403 | } | ||
404 | REMB: while(1) { | ||
405 | # On supprime les 0, et on fait deux hashs | ||
406 | my %Tneg = (); | ||
407 | my %Tpos = (); | ||
408 | foreach my $personne (keys(%Tsolde)) { | ||
409 | if($Tsolde{$personne} == 0) { delete $Tsolde{$personne}; } | ||
410 | elsif($Tsolde{$personne} < 0) { $Tneg{$personne} = $Tsolde{$personne}; } | ||
411 | elsif($Tsolde{$personne} > 0) { $Tpos{$personne} = $Tsolde{$personne}; } | ||
412 | } | ||
413 | if(keys(%Tneg) == 0) { | ||
414 | last REMB; | ||
415 | } | ||
416 | foreach my $neg (sort { $Tneg{$a} cmp $Tneg{$b} } keys %Tneg) { | ||
417 | my $max = 0; | ||
418 | my $positif = 0; | ||
419 | foreach my $pos (sort { $Tpos{$a} cmp $Tpos{$b} } keys %Tpos) { | ||
420 | if($Tpos{$pos} + $Tneg{$neg}>0) { | ||
421 | $positif = $pos; | ||
422 | last; | ||
423 | } | ||
424 | $max = $pos; | ||
425 | } | ||
426 | if(!($max eq 0)) { | ||
427 | $remboursements .= $neg." doit ".$Tsolde{$max}." EUR à ".$max."\n"; | ||
428 | $Tsolde{$neg} += $Tsolde{$max}; | ||
429 | delete $Tsolde{$max}; | ||
430 | } | ||
431 | else { | ||
432 | $remboursements .= $neg." doit ".-$Tsolde{$neg}." EUR à ".$positif."\n"; | ||
433 | $Tsolde{$positif} += $Tsolde{$neg}; | ||
434 | delete $Tsolde{$neg}; | ||
435 | } | ||
436 | next REMB; | ||
437 | } | ||
438 | } | ||
439 | print $remboursements; | ||
440 | my $pause = <STDIN>; | ||
441 | } | ||
442 | case "Sortir" { | ||
443 | last GLOBALE; | ||
444 | } | ||
445 | } | ||
446 | } | ||