W dniu 12 września 2011 17:17 użytkownik Robert cyberm@sarocom.net napisał:
może to pomoże: id: xxx, balance: -142.74, value: 47.5800, balance after: -95.16 value: 47.5800, balance after: -47.58 value: 47.5800, balance after: -1.4210854715202e-14 Wszystkie faktury klienta xxx pozostaja nierozliczone. UWAGA! Saldo klienta xxx jest nizsze niz wynika to z wystawionych faktur. Petla przerwana.
z lmsa wynika że: abonament=47,58 saldo=-142,74 wystawiono 3 faktury
Dzięki za testy. Faktycznie perl coś ma problem z liczeniem, u mnie to samo na tych danych. Dorzuciłem zaokrąglanie salda do drugiego miejsca po przecinku i poprawiłem wyświetlanie liczb. Do działania potrzeby moduł perla Math::Round. Pozdrawiam.
Łukasz Bujek
------ start ------- #!/usr/bin/perl use DBI; use Math::Round; $dsn = 'DBI:mysql:lms:localhost'; $db_user_name = 'lms'; $db_password = '123dupa12333'; $dbh = DBI->connect($dsn, $db_user_name, $db_password);
#rozliczanie wszystkich faktur i korekt $close_invoices = $dbh->prepare(qq{ update documents set closed = 1 where type = 1 or type = 3;} ); $close_invoices->execute();
#wybieranie klientów z ujemnym saldem $select_customerid = $dbh->prepare(qq{ select customerid from cash where customerid >0 group by customerid having sum(value) < 0;} ); $select_customerid->execute(); $count = $select_customerid->rows();
#przegladanie faktur klientów z ujemnym saldem for ($i = 1; $i <= $count; $i ++) {
#obliczanie salda klienta $customer_id = $select_customerid->fetchrow_array(); $get_customer_balance = $dbh->prepare(qq{ select sum(value) from cash where customerid = $customer_id;} ); $get_customer_balance->execute(); $customer_balance = $get_customer_balance->fetchrow_array();
printf "id: $customer_id, balance: %.2f, ",$customer_balance;
#wybranie wszystkich faktur danego klienta w kolejnosci od najmlodszej $get_invoices = $dbh->prepare(qq{ select id,type from documents where (type=3 or type=1) and customerid = $customer_id order by cdate desc;} ); $get_invoices->execute(); $invoice_count = $get_invoices->rows();
#przegladamy faktury, zaznaczajac jako nierozliczone te z wartoscia dodatnia, zaznaczamy tyle faktur az ich laczna wartosc pokryje ujemne saldo klienta while ($customer_balance < 0 && $invoice_count > 0) { @invoice_data = $get_invoices->fetchrow_array(); $invoice_id = $invoice_data[0]; $invoice_type = $invoice_data[1];
# jeśli faktura, wartosc liczymy jako suma (wartosc towaru * ilosc) if ($invoice_type == 1) { $get_invoice_value = $dbh->prepare(qq{ select sum(value*count) from invoicecontents where docid = $invoice_id;} ); $get_invoice_value->execute(); $invoice_value = $get_invoice_value->fetchrow_array(); } else # jesli korekta, wartosc liczymy jako suma wartosci towaru (w moich korektach czesto w polu count bylo 0) { $get_invoice_value = $dbh->prepare(qq{ select sum(value) from invoicecontents where docid = $invoice_id;} ); $get_invoice_value->execute(); $invoice_value = $get_invoice_value->fetchrow_array(); } printf "value: %.2f, ",$invoice_value;
if ($invoice_value > 0) { $customer_balance += $invoice_value; $open_invoice = $dbh->prepare(qq{ update documents set closed = 0 where id = $invoice_id;} ); $open_invoice->execute(); } $customer_balance = round($customer_balance*100)/100; printf "balance after: %.2f\n",$customer_balance;
$invoice_count--;
if ($invoice_count == 0) { print "Wszystkie faktury klienta $customer_id pozostaja nierozliczone.\n"; if ($customer_balance < 0) { print "UWAGA! Saldo klienta $customer_id jest nizsze niz wynika to z wystawionych faktur! Petla przerwana.\n"; } } } } ---------- koniec ---------