Generare numar unical crescator de Invoice

Trebuie să generez un numar de Invoice (string) unic crescator dupa data ultimului numar adaugat. Numărul facturii nu are un format implicit, utilizatorul este liber să înregistreze orice string dorit. Exemple: 00001, abc, EP-2018 / 00005…etc.

Ok, cum trebuie să funcționeze?
Dacă utilizatorul înregistrează un string 0001 ca număr de factură, atunci pe pagina „Adăugați o nouă factură”, trebuie să fie afișat următorul număr crescător, în acest caz va fi 0002. Dacă utilizatorul înregistrează o factură cu șir abc ca număr de factură, atunci pe pagina " Adăugați factură nouă ", trebuie să afișați abd.
Deci, după cum vedeți, depinde de ultima dată a numărului adăugat, deoarece al doilea numar de invoice a fost abc, acum vedem pe pagina „Adăugare factură nouă” abd este următorul număr unic.

Un alt exemplu, și aici treaba devine foarte complicată:
Dacă în db avem deja factură cu numărul “abd” și aceasta este foarte veche, atunci trebuie să obținem numărul următor de invoice, iar acesta este “abe”.

Database table invoices:

  • id (auto increment)
  • number (string)
  • updated_at (timestamp)

Exemplu 1:


id | number | updated_at

1 abc 2020-03-14 11:50:09
2 abd 2020-03-14 11:39:03

Deci, ultimul număr actualizat / adăugat este „abc”, următorul număr crescator trebuie să fie „abe”

Exemplu 2:

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

Deci, ultimul număr actualizat / adăugat este „00001”, următorul număr trebuie să fie „00002”

Am incercat asta:

    $latestByUpdatedDate = Invoice::latest('updated_at')->first();

    $latestByNumber = Invoice::latest('number')->first();


    if($latestByUpdatedDate > $latestByNumber){
        return ++$latestByUpdatedDate->number;
    }

    return ++$latestByNumber->number;

Funcționează bine dacă *latestByUpdatedDate și *latestByNumber sunt numai caractere sau numai cifre.Insă dacă încercați să comparați 00001 cu abc, rezultatul va fi greșit.

Ce idei mai pot fi pentru a primi ceea ce am nevoie?

1 Like

N-am citit toata postarea, dar ideea e asa: salvezi numarul ca atare, 1, 2, 3 etc. si apoi la afisare il prefixezi cu cati de 0 ai nevoie.

Multumesc, dar nu este ceea ce pare. Vreau sa fac ceva custom. Citeste te rog toata postarea daca ai timp.

Orice factura are o serie si un numar. Seria o salvezi separat, numarul de asemenea separat.
Incrementarea o faci doar pentru numar.

Poate ai nevoie de un comparator custom. Nu cred ca php stie logica ta de sortare.

Si nu cred ca poti sa faci operatii ce implica cifre si litere

Ai citit postarea? In cazul meu nu cesista de separat numar sau serie. La mine este un string si el trebuie incrementat.

Adica sa-l compar daca ambele sunct caractere a-Z? sau daca doar 0-9? Si in depdenta de caz sa mai compar ceva?

Eu am incercat sa fac asta inainte sa-mi dau seama ca variables pot fi de diferite forme. Dar poate solutia mea nu este buna. Dar as vrea sa aflu daca mai sunt si alte solutii.

Ce faci in situatia in care ultima factura e de forma “abz”? Ce ar trebui sa-i generezi utilizatorului? Cumva “aca”?

Daca e o aplicatie pe care o dezvolti de la 0 si ai posibilitatea de a schimba modul in care este salvata informatia iti recomand sa mergi pe varianta serie + numar cu incrementare asa cum am scris mai devreme.

Daca nu poti interveni asupra modului de salvare, cred ca situatia e destul de complicata din cauza exemplului dat mai devreme.

Da.

Este o aplicatie de la 0.

Nu pot sa merg pe aceasta varianta, sarcina este alta.

Multumesc, eu asta am facut. In cazul meu, problema este alta.

Arunca un ochi pe CAST() sau CONVERT() in MySQL.

Nu înțeleg de ce ce este luat în considerare, în codul dvs., latestByNumber, având în vedere fraza de mai sus („după data ultimului număr adăugat”).

Am mai adaugat latestByNumber, din cauza ca mai exista un asa caz:

id | number | updated_at

1 abc 2020-03-14 11:50:09
2 abd 2020-03-14 11:39:03

Dacă în db avem deja factură cu numărul “abd” și aceasta este foarte veche, atunci trebuie să obținem numărul următor de invoice, iar acesta este “abe”.

In general, ideea este ca sa scot din db ultimul numar dupa data creata + desc number, ca ulterior la acest numar sa-i pot face ++$latest->number;

1 Like

Acum înțeleg. Eu văd lucrurile în felul următor…

Dacă latestbyNumber și latestByUpdatedDate au ca număr de invoice un string de același format, atunci:

  • dacă numerele de invoice coincid, înseamnă că ultima dată deține și cel mai mare număr, deci următorul număr de invoice va fi ++&(lastestByNumber sau latestByUpdatedDate)->number
  • dacă numerele de invoice nu coincid, înseamnă că cel mai mare număr nu aparține ultimei date, deci următorul număr de invoice va fi ++&latestByNumber->number

Problema intervine când cele două numere de invoice au un format diferit. Nu există termen de comparație între „0001” și „abcd” (poate doar prin comparație caracter cu caracter, pe baza ASCII, dar nu de comparația lexicografică vorbim aici, presupun). Eventual, prin convenție, în această situație, următorul număr de invoice va fi ++&latestbyUpdatedDate->number.

Deci problema finală constă în determinarea egalității formatelor celor două numere de invoice. Acum depinde de toate formele pe care le poate avea numărul de invoce. De exemplu, dacă ar lua doar forme de tipul „abc”, „123” atunci aș lua câte un caracter la întâmplare din fiecare și aș testa dacă ambele caractere sunt între ‘a’ și ‘z’ sau între ‘0’ și ‘9’ și pe baza rezultatelor aș putea trage o concluzie. Dar nu știu cum stă treaba în cazul dvs.

2 Likes

Sau puteți încerca cu REGEX?

1 Like

Multumesc pentru raspuns. Ai inteles foarte bine problema.

Aici m-am si blocat

omg…eu cu regex stiu doar sa fac copy/paste, nu le pricep (

În mod specific, care sunt posibilele forme pe care le poate avea numărul de invoice?

Totul in afara de caractere speciale !?.,{}`~, adica dupa urmatorul regex /^[a-zA-Z0-9-_]+$/

Variante pot fi de tot felul: INV-0001, INV-1578M, avc,abc,ade,abcdefg…etc.