Generare numar unical crescator de Invoice

Din câte observ, rezolvarea nu constă în REGEX, având în vedere că formatul este flexibil, necesită o abordare brute-force.
Ca să înțeleg mai bine, care sunt următoarele numere dacă ultimul este:

  • INV - 999
  • INV - 999Z
  • zzz
  • ZZ-ZZ-99

Daca sa ne conducem dupa aceasta lista, se primeste ca zzz este ultimul. Si urmatorul trebuie sa fie aaaa

Asta e o cerinta de la client sau ceva de compatibiltiate cu unul sau mai multe sisteme existente? :thinking:

Este o cerinta de la client.

Se pare că este o problemă de algoritmică. Să ușurăm problema. Se dau două șiruri de caractere A și B. Să se determine dacă cele două șiruri au același format.

Exemplu 1:

  • abde_3030-ppp
  • d_1-p
  • răspuns: au același format

Exemplu 2:

  • 00_01
  • 00b_01
  • răspuns: nu au același format

Problema determinării egalității formatului se poate rezolva prin simplificarea stringurilor inițiale. Codificăm o subsecvență de numere/litere continuă astfel:

  • subsecvența este alcătuită din numere, o transformăm în 0

  • subsecvența este alcătuită din litere, o transformăm în ‘a’

De exemplu, dacă avem stringul “345-kap_qq_01” atunci codificat ar fi “0-a-a-0”.
Tot ce rămâne este să verificăm dacă stringurile A și B au aceeași codificare.

În exemplul 1, avem A = ”abde_3030-ppp” = “a_0-a” și B = ”d_1-p” = “a_0-a” => A are același format cu B

În exemplul 2, avem A = “00_01” = “0_1” și B = “00b-01” = “0a-1” => A și B nu au același format

1 Like

tldr; Nu sunt un expert dar facturile au o serie si un numar iar acesta este bine sa fie chiar un numar. Nu stiu ce faceti voi acolo cu incrementare de caractere dar mi se pare profund gresit.

4 Likes

Eu am spus asta de la bun inceput :smiley:

De acord, mi se pare o aberație această cerință. Nu înțeleg de ce trebuie complicat atât de mult un concept atât de simplu.

Pare ca bazaie cam ce vrei tu

$serie = "abc";
$serie = ++$serie;
echo $serie . PHP_EOL;

$serie1 = "abc-123";
$serie1 = ++$serie1;
echo  "serie noue:" . $serie1 . PHP_EOL;

$serie2 = "EP-2018 / 00005";
$serie2 = ++$serie2;
echo "serie 2 noua" . $serie2;

abd
serie noue:abc-124
serie 2 nouaEP-2018 / 00006
Process finished with exit code 0


Fa niste teste fara baza de date si vezi ce iti iese. Dar cum zice @geosoft1, te complici f mult.

Daca te intereseaza un anumit format de serie, cred ca o poti cauta in baza de date.

id | number | updated_at

1 abe 2020-03-14 11:49:09
2 abc 2020-03-14 11:50:09
3 abd 2020-03-14 11:49:09
4 00001 2020-03-15 10:45:52
5 abf 2020-03-15 10:42:50

select number for factura where number like '0001%' si in cazul de fata o sa iti dea inregistrarea cu id-ul 4. Si apoi ii incremenzi valoarea. Vezi poate te ajuta cu ceva.

Sigur, nu este cea mai buna idee, dar este cea care mi-a venit pe moment.

Si eu sunt de acord. As zice sa incerci sa discuti cu clientul despre nevoia unei standardizari clare in numerotarea facturilor cu argumentul ca lipsa acesteia va duce cu siguranta la probleme de mentenanta precum si dificultate pentru utlizatorii aplicatiei care vor trebui probabil sa fie invatati (sau mai rau sa descifreze singuri) sistemul de numerotare. In plus, cineva imi spunea ca numerotarea gresita a facturilor ar putea sa iti dea si probleme legale, nu stiu daca e adevarat sau nu dar daca este cu atat mai mult nu vrei sa ai un sistem de numerotare asa confuz.

Daca o tine pe a lui atunci va trebui sa implementezi cum crezi tu si sa incerci sa acoperi cazurile care iti vin in cap dar sa fii pregatit pentru greseli si probleme in viitor deci obligatoriu sa scrii si teste pentru toate cazurile din sistemul asta de numerotare / ordonare ca sa poti reveni si sa il modifici fara sa strici ce era inainte.

Multumesc pentru idee. Am sa incerc sa le compar cu acest algoritm.

  1. Eu asta am facut. Problema mea nu este in incrementing atunci cand am un string. Problema mea este sa scot ultimul numar corect din baza de date.

  2. ++$serie nu este totul. Trebuie ceva mai complex, un exemplu: ZZ-ZZ-99, daca ii dai ++, primesti ZZ-ZZ-00, si acuma daca faci asta de 1000 de ori

foreach (range(0, 1000) as $index){
        echo ++$string.'<br>';
 }

O sa gasesti dublari, ceea ce este foarte rau. In acest caz trebuie de parcus fiecare secventa dupa cratima(-), si de dat ++$string doar la secventele care nu sunt numerice, apoi primesti un nou string AAA-AAA-00, apoi daca faci asta de 1000 ori, nu vor fi dublari(dar aici mai trebuie de facut teste).

Daca este un CRM intern care il foloseste doar o companie, atunci sunt deacord cu voi, dar in cazul meu, este vorba despre un produs SAAS, aici trebuie sa fie cat mai flexibil pentru fiecare abonat.
De exemplu: Eu m-am inregistrat in acest sistem si incep sa fac un invoice nou. Din start acolo imi este propus varianta 00001. Eu am posibilitate sa modific numarul cum doresc eu, sau sa-l las pe acela propus de sistem. Daca am salvat primul invoice, atunci la urmatorul invoice o sa am propunerea 00002.
Deci este foarte super, din cauza ca eu din start pot sa-mi setez un format chiar din invoice, de exemplu, 2020/0001, si daca salvez un invoice cu acest numar, atunci urmatoarele vor fi cu incrementing pornind de la acest format, adica urmatoarele vor fi: 2020/0002, 2020/0003…etc.

1 Like

Atunci poate ai putea salva si formatele numarului facturii pentru fiecare abonat per factura. Asa ai sti mai usor ce regula sa aplici la incrementare.

Am intuit ca e vorba de un produs SAAS, dar chiar si asa poti da abonatului optiunea de a-si defini modul de numerotare. Iti dau un exemplu, la SmartBill, atunci cand iti faci cont, printre setari trebuie sa definesti seria facturii si numarul de inceput. De exemplu XYZ-00001. Stiind acest lucru, poti face mult mai usor sortarea pentru ca ai din start modalitatea de numerotare a abonatului.

Eu nu am o problema cu incrementarea. Eu am o problema cu gasirea ultimului numar dupa care sa fac incrementing.

Pe de alta parte nu stiu daca din punct de vedere contabil, legal, etc poti scrie chiar ce vrei tu pe acolo pentru ca se declara la ANAF.

vezi pag.41,42

de la @Cosmin_Popescu https://factureaza.ro/ajutor/ce-este-o-serie-de-facturi/

Daca era asa de simplu, demult o faceam. Dar aici trebuie ceva mai complicat din punct de vedere tehnic si mai simplu din punct de vedere user experience.

1 Like

Abordarea urmatoare nu te ajuta?

  1. $latestNumber = select number from invoices order by updated_at limit 1
  2. $latestNumber++;
  3. $greaterNumber = select count(id) from invoices where number = $latestNumber
  4. if $greaterNumber !== 0 { $latestNumber++; goto 3; }
  5. insert into invoices ($latestNumber)

Pai din moment ce ai salvat si formatul numarului de factura, iei ultima factura dupa data, iei maximul pentru acel format de numar si il incrementezi. Sau nu inteleg eu bine problema? :thinking:

Am avut gandul sa incerc asa, doar ca in cazul cand $greaterNumber exista, eu trebuie sa mai caut odata, defapt aici necesita un ciclu pana ajungi sa nu mai ai variante in baza de date. Acest ciclu nu-l pot controla, pe viitor poate sa devina foarte mare si astfel pot sa am un timeout execution sau ceva de genul.