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
--------------------------------------