Witam, W nawiązaniu do ostatniego wątku o rozliczaniu faktur w LMSie na podstawie kwoty wpłaty, przyszedł mi do głowy taki pomysł, żeby zabrać się za to od drugiej strony. Tzn, zamiast rozliczać faktury na podstawie wpłaty, wymyśliłem, że już po zaksięgowaniu wpłat można przejrzeć saldo klientów i na podstawie aktualnego salda zaznaczyć odpowiednią ilość najmłodszych faktur jako nierozliczone. Poniżej skrypt w perlu, który to właśnie robi. Może się komuś przyda.
Skrypt najpierw rozlicza *WSZYSTKIE* faktury niezależnie od salda a następnie przegląda każdego klienta z ujemnym saldem i zaznacza faktury jako nierozliczone, zaczynając od najnowszej. Nierozliczone pozostają faktury na łączną wartość przynajmniej równą saldu (co do wartości bezwzględnej). Jeśli faktura ma wartość <= 0 (korekty) pozostaje rozliczona. W efekcie rozliczone są faktury najstarsze, zerowe i ujemne. Saldo klienta nawet -0,01 zł skutkuje nierozliczoną fakturą.
Skrypt ma kilka wad: - pętla while ($customer_balance < 0) nie zatrzyma się jeśli saldo klienta jest mniejsze od sumy wartości wszystkich wystawionych faktur i korekt - u mnie się to nie zdarzyło, - nie bierze pod uwagę not obciążeniowych - na razie nie miałem takiej potrzeby, - nie bierze pod uwagę tego co jest na dowodach wpłat, czyli jeśli rozliczyliśmy *nie najstarszą* fakturę dowodem wpłaty, a klient ma nadal saldo ujemne, to ta faktura rozliczona dowodem wpłaty może zostać zaznaczona przez skrypt jako nierozliczona. Wystawienie dowodu wpłaty na *nie najstarszą* fakturę jest złamaniem założenia, że rozliczamy najpierw najstarsze należności.
Proponuję popatrzeć sobie na środowisku testowym lub zrobić backup danych przed zabawą. Pozdrawiam.
Łukasz Bujek
----------------------------------------- start -------------------------------------- #!/usr/bin/perl use DBI; $dsn = 'DBI:mysql:lms:localhost'; $db_user_name = 'lms'; $db_password = 'xxxxx'; $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();
print "id: $customer_id, balance: $customer_balance, ";
#wybranie wszystkich faktur (i korekt) 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();
#przegladamy faktury, zaznaczajac jako nierozliczone te z wartoscia dodatnia, zaznaczamy tyle faktur az ich laczna wartosc pokryje uj emne saldo klienta while ($customer_balance < 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, stad oddzielny przypadek) { $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(); } print "value: $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(); }
print "balance after: $customer_balance \n"; } } ----------------------------------------- koniec --------------------------------------