Fintech / lično alatkanje
Sopstveni alat za fakturisanje
Mali Symfony alat za komandnu liniju koji generiše moje frilenserske fakture kao PDF i šalje ih mejlom — napravljen da izbriše mesečnu obavezu, sa osobenostima srpskog fakturisanja ugrađenim u njega.
Pregled
Svaki frilenser ima ponavljajuću administrativnu obavezu koju tiho prezire. Moja je bila fakturisanje — isti obrasci ukucani u isti šablon svakog meseca, gde je jedino što se menja par brojeva, a jedina nagrada za ručno rađenje je šansa da napraviš grešku. Zato sam napravio mali alat da to radi umesto mene. Nije glamurozan, i to je otprilike i poenta.
Problem
Ručno fakturisanje je repetitivno, a repetitivno-ali-mora-da-bude-tačno je najgora kombinacija koja postoji. Dovoljno je dosadno da pažnja popusti i dovoljno važno da popuštanje ima posledice. Povrh toga, fakture ovde dolaze sa lokalnim pravilima — iznos mora da se pojavi ispisan slovima, uputstva za banku moraju da budu ispravna — pa generički generator faktura ne bi valjao. Hteo sam nešto što zna baš za moje fakture.
Rešenje
Alat za komandnu liniju: bin/console invoice:send 3 gradi PDF za fakturu i
šalje je mejlom, u jednom koraku. Model podataka je tačno onoliko mali koliko
treba da bude — organizacije i ljudi u njima, bankovni računi, fakture i njihove
stavke — i ništa više. Renderuje fakturu iz šablona u PDF i šalje je, sa
srpski-specifičnim detaljima (poput ispisivanja ukupnog iznosa slovima) rešenim
kao prvorazredne funkcionalnosti, a ne kao naknadne misli.
Arhitektura
Symfony 6.4 na PHP-u 8.2, sa Doctrine ORM-om nad MariaDB. Fakture su modelirane
kao pravi entiteti — Organization, Person, BankAccount, Invoice,
InvoiceItem — sa value objektima za stvari koje zaslužuju svoj tip umesto
labavog stringa ili inta. Generisanje PDF-a ide kroz mPDF iz Twig šablona,
isporuka kroz Symfony mailer, a Google API klijent rukuje skladištenjem. Sve to
radi u Dockeru (PHP-FPM, nginx, MariaDB, hvatač mejlova za lokalna pokretanja)
tako da se ponaša isto na mojoj mašini kao i bilo gde drugde.
Namerni izbor ovde bio je da to bude CLI alat, a ne veb aplikacija. Nema korisnika osim mene i nema razloga da bude sajt; konzolna komanda je najmanji pošten interfejs za ovaj posao, i sklapa se sa svim ostalim na komandnoj liniji.
Tehnički izazovi
Zanimljivi ćoškovi su lokalni. Pretvaranje numeričkog ukupnog iznosa u gramatički ispravne srpske reči („iznos slovima”) jeste mali, samostalan jezički problem — vrsta stvari koja je jednolinijaš u glavi, a pravi mali servis u kodu kada obradiš sve slučajeve. Držati alat dosadno pouzdanim — tako da „pokreni ga i prava PDF faktura sleti u pravo sanduče” nikada ne bude pod znakom pitanja — vredelo je više od bilo koje funkcionalnosti. Neke ideje su još na listi (povlačenje kursa sa Narodne banke, automatsko prepoznavanje banke iz broja računa), i to je u redu; lični alat zaslužuje svoje funkcionalnosti kada se pojavi stvarna potreba.
Naučene lekcije
Pravi male alate za sebe. Najbolji način da razumeš šta softver čini prijatnim za korišćenje jeste da budeš onaj koji mora da ga koristi svakog meseca — svaku grubu ivicu osetiš lično, i popraviš one koje zaista znače umesto onih koje dobro izgledaju na spisku funkcionalnosti. Ovaj alat nikada nikoga neće impresionirati, a tiho mi je uštedeo isti taj sat, iznova i iznova, godinama. To je dobra trampa.