Skip to main content

ArtinTech Solution

WordPress invoice plugin by ArtinTech Solution

De fleste små bureauer og freelancere fakturerer på en af to måder. Enten et regneark og en Word-skabelon, som nogen eksporterer til PDF i hånden, eller en hostet faktureringstjeneste, der faktureres pr. bruger, pr. måned, for altid. Den første bryder sammen, i det øjeblik to personer rører den. Den anden virker fint, indtil du tilføjer en kollega, en ekstra valuta eller en kunde, der har brug for noget, produktet aldrig var designet til.

Vi havde begge problemer, så vi byggede vores eget fakturaplugin til WordPress: ArtinTech Invoice Manager. Det kører som en app i fuld skærm på en WordPress-side. Det opretter professionelle fakturaer med PDF-eksport med ét klik, fører en kundebog med saldi, sporer betalinger i flere valutaer og har et admin-panel til at styre de personer, der bruger det. Det kører live på denne side, og det er det værktøj, vi nu fakturerer vores egne kunder med.

Denne artikel er den fulde byggelog. Den dækker, hvad pluginet gør, hvordan og hvorfor det er bygget, sikkerhedsmodellen, de fejl, vi fandt, før vores kunder gjorde, og hvad det krævede at gøre koden klar til pluginbiblioteket på WordPress.org. Hvis du overvejer, om du skal bygge et skræddersyet faktureringsværktøj eller bruge et eksisterende, er de sidste afsnit skrevet til dig.

Dashboard i fakturapluginet til WordPress med totaler for faktureret, modtaget, udestående og forfaldent
Fakturadashboardet: totaler pr. valuta, seneste fakturaer og den fulde liste. Alle skærmbilleder i artiklen bruger demodata, og kundenavnene er fiktive.

Hvorfor vi byggede vores eget fakturaplugin til WordPress

At bygge software, man kunne leje, er som regel en fejl, så det er værd at være præcis om, hvorfor det ikke var det her. De afgørende faktorer var praktiske, ikke ideologiske.

  • Data bør ligge hos virksomheden. Fakturaer, kundeadresser og betalingshistorik er en virksomheds finansielle registrering. At have dem i den samme WordPress-database, som vi allerede tager backup af og kontrollerer, er enklere end at stole på en tredjeparts eksportknap den dag, vi får brug for den.
  • Priser pr. bruger skalerer imod dig. Et hostet værktøj, der er billigt for én person, bliver en reel post på budgettet, når et lille team og et par samarbejdspartnere skal have hvert deres login. Et plugin koster det samme, uanset om én person bruger det eller tyve.
  • Flere uafhængige kontohavere, én installation. Vi havde brug for, at hver person havde deres egne fakturaer, kunder, logo, bankoplysninger og nummerering, helt adskilt fra alle andre, på én side.
  • Vores fakturaer er internationale. Vi fakturerer kunder i udlandet i mere end én valuta. Vi havde brug for totaler pr. valuta, aldrig omregnet i stilhed, og fakturaer, der viser bankoplysninger til overførsler på tværs af landegrænser.
  • Vi ville kunne ændre det. Når vi havde brug for en knap til “Markér som betalt” eller en kontakt til at skjule en kundes logo, ville vi have det samme eftermiddag, ikke på en leverandørs køreplan.

Intet af dette gør hostet faktureringssoftware dårlig. Det gør det til en anden afvejning, og det hjælper at se de to side om side.

Hostet faktureringstjenesteSelvhostet fakturaplugin til WordPress
Hvor data liggerLeverandørens servereDin egen WordPress-database
Pris, når teamet vokserStiger som regel pr. brugerFast, uanset antallet af brugere
OpsætningMinutterInstallér, aktivér, opret app-siden
TilpasningDet, indstillingsskærmen tilladerAlt, hvad koden kan
VedligeholdelseHåndteres af leverandørenDit ansvar, som med ethvert plugin
IntegrationerOfte et stort katalog af færdige forbindelserBygges efter behov mod din egen platform

Hvis kolonnen til højre læses som en liste over pligter, er et hostet værktøj sandsynligvis det bedste valg for dig. Hvis den læses som en liste over ting, du alligevel allerede gør for din hjemmeside, begynder et plugin at give mening.

Sådan virker det: fra installation til en betalt faktura

Før detaljerne er her hele forløbet fra start til slut: hvad en administrator gør én gang, og hvad en kontohaver gør, hver gang de fakturerer en kunde. Ni trin, hver vist på den rigtige brugerflade.

Trin 1: Installér pluginet, og opret app-siden

  1. Upload pluginet under Plugins → Add New → Upload Plugin og aktivér det.
  2. Åbn den nye menu Invoice Manager i wp-admin.
  3. Klik på Create app page.

Det udgiver en side på /invoice-manager/, og den side bliver selve applikationen. Intet andet på siden ændres. Administratorer kan bruge appen med det samme.

Trin 2: Log ind, eller lad folk tilmelde sig

App-siden viser sin egen login-skærm til alle, der ikke er logget ind. Folk logger ind med deres normale WordPress-brugernavn eller e-mail, og der er links til “Husk mig” og “Glemt adgangskode”.

Login-skærmen i Invoice Manager
Login-skærmen på frontend. Kontohavere behøver aldrig at se wp-admin.

Hvis du slår offentlig tilmelding til, vises et Create one -link under login-formularen, som åbner tilmeldingsskærmen. Med godkendelse af administrator slået til forbliver en ny konto afventende, indtil en administrator godkender den.

Tilmeldingsskærmen i Invoice Manager
Den valgfri tilmeldingsskærm med en note om, at nye konti gennemgås, før de kan bruges.

Trin 3: Angiv dine virksomhedsoplysninger én gang

Hver kontohaver starter i My settings:

  • Upload et logo, og vælg derefter person eller virksomhed.
  • Indtast din adresse, kontaktoplysninger og dit momsnummer.
  • Vælg en standardvaluta og betalingsbetingelser.
  • Indsæt dine bankoplysninger.
  • Angiv et fakturapræfiks og et startnummer, og tilføj dine egne momssatser.

Alt her udfyldes automatisk på nye fakturaer, så du skriver det kun én gang.

Kontoindstillinger med logo, virksomhedsadresse, valuta, bankoplysninger og fakturanummerering
My settings: branding, virksomhedsoplysninger, valuta, bankoplysninger og fakturanummerering.

Trin 4: Tilføj dine kunder

Under Clients → Add Client gemmer du hver kunde én gang: logo, firma- og kontaktnavne, e-mail, telefon, adresse og momsnummer. Kundebogen er søgbar, og hvert kort viser, hvor mange fakturaer en kunde har, og hvad de stadig skylder.

Kundebog med kunder, logoer og udestående saldi
Kundebogen med logoer og udestående saldi på ét blik.

Trin 5: Opret fakturaen

Klik på New invoice. Nummer, datoer, valuta, betingelser og dine oplysninger er allerede udfyldt.

  1. Vælg kunden.
  2. Tilføj varelinjer med antal, pris og moms.
  3. Giv en rabat, hvis det er nødvendigt, og tilføj egne felter, som et indkøbsordrenummer.
  4. Vælg, om dit logo og kundens logo skal vises på denne faktura.
  5. Klik på Save.

Totalerne genberegnes, mens du skriver.

Fakturaeditor med varelinjer, rabat, kundeoplysninger og kontakter til logoer
Fakturaeditoren: dokumentet til venstre, handlinger og kontakter til logoer til højre.

Trin 6: Forhåndsvis den, og download PDF’en

Preview viser fakturaen præcis, som kunden vil modtage den. Download PDF gemmer en A4-fil, du kan maile, uploade til en kundeportal eller printe.

Der findes tre skabeloner, som vælges pr. faktura i editorens skabelonmenu:

  • Blank: et rent, minimalistisk layout.
  • Modern: et farvet headerbånd.
  • Classic: en serif-skrift med streger.
Forhåndsvisning af PDF-faktura med afsenderens og kundens logoer, bankoplysninger og betingelser
PDF-forhåndsvisningen med begge logoer, rabatten, bankoplysninger og betalingsbetingelser.

Trin 7: Registrér betalingen

Når pengene kommer, så klik på Mark paid på fakturaens række, eller på $ -ikonet for at registrere en delbetaling med dato, metode og reference. Status ændrer sig af sig selv:

  • Partially paid efter en rate.
  • Paid når saldoen når nul.
  • Overdue hvis forfaldsdatoen passerer, før fakturaen er fuldt betalt.
Dialog til registrering af betaling med beløb, dato og betalingsmetode
Registrering af en betaling. Beløbet er udfyldt med den udestående saldo.

Trin 8: Følg, hvad der stadig skyldes

Totalerne på dashboardet opdateres med det samme. For en enkelt kunde åbner du deres side i kundebogen for at se:

  • Alt faktureret, modtaget og udestående pr. valuta.
  • Hver faktura, du har sendt dem.

Det er den skærm, du skal åbne før et opfølgende opkald.

Kundeside med totaler for faktureret, modtaget og udestående og fakturahistorik
En kundes side: saldi pr. valuta og fuld fakturahistorik.

Trin 9: Styr de personer, der bruger det

Administratorer og alle med rollen Invoice Manager Admin åbner Admin panel → Users. Derfra kan de:

  • Godkende afventende tilmeldinger, hvorefter brugeren automatisk får en mail.
  • Suspendere eller genaktivere konti.
  • Tilføje brugere direkte. Den nye bruger får en mail til at vælge sin adgangskode.
  • Ændre roller og slette konti.
Brugerstyring i admin-panelet med godkendelse, suspendering og roller
Brugerstyring: godkendelser, suspenderinger, roller og hver kontos antal fakturaer og kunder.

Hvad pluginet gør: en rundtur i funktionerne

Forløbet ovenfor viser hovedvejen. Denne rundtur dækker resten af, hvad pluginet kan. Alt kører på én side på hjemmesiden i en brugerflade, der er designet til at føles som en selvstændig applikation frem for en WordPress-skærm.

Fakturadashboardet

Startskærmen besvarer det spørgsmål, enhver virksomhedsejer åbner et faktureringsværktøj for at stille: hvem skylder os hvad? Fire tal står øverst: faktureret i alt, modtaget, udestående og forfaldent. Hvert tal beregnes separat for hver valuta, med en vælger, når en kontohaver fakturerer i mere end én. Under dem står de fire seneste fakturaer som kort og derefter den fulde fakturaliste.

Listen kan gennemsøges efter fakturanummer eller kundenavn. Du kan filtrere den efter kunde, status, dokumenttype og datointerval og sortere den efter enhver kolonne. Fra hver række kan du registrere en betaling, markere fakturaen som betalt, downloade dens PDF, kopiere den eller slette den uden at åbne den.

Fakturaeditoren

Editoren er opbygget som det færdige dokument, så det, du skriver, står der, hvor det vil blive vist. Panelet til højre indeholder handlingerne.

  • Fire dokumenttyper: Invoice (faktura), Quote (tilbud), Proforma og Credit Note (kreditnota).
  • Automatisk nummerering med et præfiks pr. bruger, som AT2623. Nummeret kan stadig redigeres, og dubletter afvises.
  • Udstedelses- og forfaldsdato. Forfaldsdatoen udfyldes ud fra hver persons standard betalingsbetingelser.
  • Varelinjer med antal, enhedspris, en beskrivelse og en momssats valgt fra brugerens egen liste.
  • En rabat på hele fakturaen, egne felter som et indkøbsordrenummer, ekstra virksomhedsoplysninger og en fri beskrivelse.
  • Kundeoplysninger, valgt fra kundebogen eller indtastet til en enkeltstående faktura, med mulighed for at gemme en ny kunde med det samme.
  • En valutavælger til hver faktura og en tekst med betingelser , der udfyldes på forhånd fra indstillingerne.

Totalerne opdateres, mens du skriver. Hvis du prøver at forlade siden med ændringer, der ikke er gemt, spørger appen, før de kasseres. Den lille detalje betyder mere i et faktureringsværktøj end næsten noget andet sted.

Betalinger, statusser og “Markér som betalt”

Ingen sætter en fakturas status i hånden. Den udledes af de betalinger, der er registreret på den, så den kan aldrig være uenig med pengene.

Registrerede betalingerVist status
IngenUnpaid
Mindre end totalenPartially paid
Lig med eller mere end totalenPaid
Ikke fuldt betalt, og forfaldsdatoen er passeretOverdue
Dokumenttypen er QuoteQuote (tælles aldrig som indtægt)

Hver betaling har en dato, et beløb, en metode og en valgfri note, så rater og manglende beløb på grund af bankgebyrer kan registreres korrekt. Til det mest almindelige tilfælde, hvor kunden bare har betalt, er der en knap, Mark as paid , med ét klik. Den registrerer en enkelt betaling for den resterende saldo, dateret i dag.

PDF-eksport og skabeloner

Hver faktura kan forhåndsvises og downloades som en A4-PDF i en af tre skabeloner: et rent Blank-layout, et Modern-layout med et farvet headerbånd og et Classic-layout med serif-skrift og streger.

PDF’en indeholder:

  • Afsenderens logo og kundens logo. Hver af dem kan slås fra på en enkelt faktura.
  • Begge adresser.
  • Varelinjer, rabat, moms og total.
  • Eventuelle modtagne betalinger, skyldigt beløb, bankoplysninger og betingelser.

Kundebogen

Kunder gemmes én gang og genbruges. Hver har logo, firma- og kontaktnavne, adresse, momsnummer og noter.

Kundelisten viser, hvad hver kunde stadig skylder, og en kundes egen side viser:

  • Totaler for faktureret, modtaget og udestående for hver valuta.
  • Deres fulde fakturahistorik.
  • En knap, der starter en ny faktura med kunden allerede udfyldt.

Personlige indstillinger for hver kontohaver

Hver bruger har sit eget:

  • Logo og et valg mellem identitet som person eller virksomhed.
  • Adresse og telefonnummer med international landekode.
  • Momsnummer og hjemmeside.
  • Standardvaluta og betalingsbetingelser i dage.
  • Bankoplysninger, præfiks for fakturanumre og næste nummer.
  • Standardtekst til betingelser og en liste over navngivne momssatser.

To personer på samme side kan derfor udstede fakturaer, der ser ud, som om de kommer fra to forskellige virksomheder, for det gør de.

Tilmeldinger, godkendelser og admin-panelet

Appen har sine egne skærme til login og tilmelding på frontend, så kontohavere aldrig behøver at se wp-admin. Offentlig tilmelding er valgfri. Når den er slået til, kan nye konti kræve godkendelse fra en administrator, før de kan bruges, og administratoren får en mail om hver tilmelding.

Inde i appen får administratorer et Admin panel med fire sektioner:

  • Overview: antal konti og fakturavolumen for alle brugere.
  • Users: godkend, suspendér, genaktivér, tilføj eller slet konti og skift roller.
  • Indstillinger for tilmelding.
  • Beskeder sendt fra formularen “Kontakt os” i appen.
Oversigt i admin-panelet med antal konti, indstillinger for tilmelding og volumen pr. valuta
Admin-oversigten: konti, der venter på godkendelse, indstillinger for tilmelding og fakturavolumen på tværs af alle konti.

Har du brug for et internt værktøj, der passer til den måde, din virksomhed faktisk arbejder på?

Fakturering, godkendelser, tilbud, kundeportaler. Fortæl os om arbejdsgangen, så siger vi ligeud, om et eksisterende plugin dækker det, eller om en skræddersyet løsning er berettiget.

Arkitektur: sådan bør et fakturaplugin til WordPress gemme sine data

Det meste af et plugins langsigtede kvalitet afgøres af datamodellen, fordi datamodellen er den ene del, du ikke nemt kan ændre, når der findes rigtige fakturaer. Vi traf fire beslutninger tidligt, og alle fire holdt.

Egne indholdstyper, ikke egne tabeller

Fakturaer, kunder og kontaktbeskeder er private egne indholdstyper. Hver post ejes af den WordPress-bruger, der oprettede den, og de strukturerede data gemmes i en enkelt post meta-værdi. Personlige indstillinger ligger i user meta, og indstillinger for hele pluginet bruger Options API.

Egne databasetabeller ville have været en anelse hurtigere ved meget store mængder. Til gengæld giver indholdstyper os meget gratis:

  • Almindelige WordPress-backups og -migreringer inkluderer automatisk data.
  • Eksportværktøjer forstår det allerede.
  • Objektcachen virker uden ekstra kode.
  • Sletning af en bruger kan tage deres poster med uden en eneste linje oprydningskode.

Et faktureringsværktøj til en virksomhed rummer sjældent mere end nogle få tusinde fakturaer pr. person. I den skala er den indbyggede tilgang den rigtige.

Indholdstyperne er registreret som fuldstændigt private: ikke offentlige, ikke forespørgbare, udelukket fra søgning og skjult for REST API og sitemaps. En faktura kan ikke ved et uheld sive ud i et temas søgeresultater eller et SEO-plugins sitemap.

Snapshots: hvorfor en faktura kopierer afsender og kunde

En faktura er en juridisk registrering af et øjeblik. Hvis du flytter kontor næste år, skal sidste års fakturaer stadig vise sidste års adresse. Så når en faktura oprettes, kopierer pluginet afsenderens oplysninger ind i den, og det samme gør det med kundens oplysninger.

At ændre dine indstillinger eller en kundes adresse omskriver aldrig historikken. Når du faktisk vil have en gammel kladde til at tage nye oplysninger, tilbyder editoren en bevidst handling, “Use my latest settings”, i stedet for at gøre det i stilhed.

Fakturaen beholder også et link til kundeposten, som styrer saldi pr. kunde. Når en kunde slettes, fjernes linket, men snapshottet bliver. Fakturaen læses stadig korrekt og holder bare op med at tælle med hos en kunde, der ikke længere findes.

Status beregnes, gemmes aldrig

“Forfalden” afhænger af dagens dato, så at gemme den ville gøre den forkert i morgen. Pluginet gemmer fakta: varer, rabat, betalinger og forfaldsdato. Det beregner status, hver gang en faktura læses. Et gemt statusfelt er en af de mest almindelige kilder til “dashboardet siger betalt, men banken siger noget andet” i forretningssoftware.

Pengeberegninger, som en revisor ville godkende

  • Rabat trækkes fra før moms. En rabat på 10 % mindsker både subtotalen og den moms, der beregnes af den, hvilket er, hvad de fleste momsregler forventer.
  • Moms beregnes pr. linje. Hver vare har sin egen sats, så én faktura kan blande momspligtigt og momsfrit arbejde.
  • Kreditnotaer tæller negativt i alle totaler, og tilbud tæller slet ikke.
  • Valutaer omregnes aldrig. Totaler holdes pr. valuta. At omregne i stilhed til en eller anden kurs ville give tal, der hverken passer med fakturaen eller banken.
  • Totaler genberegnes på serveren ud fra varelinjerne, når en faktura gemmes. Browserens udregninger er kun til visning, og en manipuleret forespørgsel kan ikke gemme en total, der ikke stemmer.

Et REST API med ejerskabstjek ved hver forespørgsel

Frontend taler med WordPress via et dedikeret REST-namespace. Hver route passerer det samme rettighedstjek. Forespørgslen skal komme fra en indlogget bruger med pluginets egen rettighed og en aktiv kontostatus, og den skal have en gyldig WordPress-nonce.

Oven i det tjekker hver forespørgsel, der nævner en faktura eller en kunde, at posten tilhører den aktuelle bruger. Hvis den ikke gør, svarer API’et ikke fundet i stedet for forbudt. Forskellen er bevidst: “forbudt” bekræfter, at en post med det ID findes, “ikke fundet” afslører intet. Vi tester det eksplicit ved at bede om én kontos faktura, mens vi er logget ind som en anden.

Hvert indkommende felt renses og længdebegrænses:

  • Datoer skal følge et strengt format.
  • Valutaer skal være tre bogstaver.
  • Dokumenttyper og skabeloner skal komme fra en fast liste.
  • Logoer accepteres kun som billeder, der allerede er uploadet til sidens eget mediebibliotek.

Uploadede billeder afkodes og kontrolleres for at være rigtige PNG-, JPEG-, GIF- eller WebP-filer, før de når mediebiblioteket. SVG afvises, fordi en SVG-fil kan indeholde script.

Én praktisk detalje sparede os for fremtidige supporthenvendelser. Nogle delte hosts og firewallregler blokerer HTTP PUT og DELETE -forespørgsler helt. Appen sender derfor hver skrivning som en POST med WordPress’ standardheader til method override, som REST API’et respekterer fra starten. Routerne forbliver RESTful, og forespørgslerne overlever restriktiv hosting.

Konti, roller og godkendelser

Pluginet tilføjer to roller og én rettighedsmodel og rører aldrig WordPress’ egne roller ud over at give administratorer adgang.

RolleKan bruge appenKan styre kontohavereKan styre fakturaadministratorer og roller
AdministratorJaJaJa
Invoice Manager AdminJaJaNej
Invoice Account HolderJaNejNej

Den mellemste rolle findes, så en kontorchef kan godkende og hjælpe brugere uden at få nøglerne til hele hjemmesiden. Administratorer kan aldrig suspenderes eller slettes inde fra appen, og ingen kan slette deres egen konto der. Det er netop de fejl, der låser folk ude af deres egen side.

Offentlig tilmelding er slået fra, indtil en administrator slår den til. Når den er slået til, er formularen beskyttet på fire måder:

  • En nonce.
  • Et skjult honeypot-felt, som bots udfylder, og mennesker ikke gør.
  • En grænse på fem tilmeldinger pr. netværksadresse i timen.
  • En minimumlængde på adgangskoden.

Med godkendelse slået til kan en ny konto logge ind, men ser kun en skærm med “afventer godkendelse”, indtil en administrator godkender den. Brugeren får en mail i det øjeblik. At suspendere en bruger logger dem straks ud på alle enheder ved at nedlægge deres WordPress-sessioner i stedet for at vente på, at en cookie udløber.

En app i fuld skærm, som temaet ikke kan ødelægge

En faktureringsapp skal se ens ud og opføre sig ens på hver side, den installeres på. Et temas knapstile, en sidebyggers nulstillinger eller et cache-plugins scriptoptimering kan alle ødelægge en brugerflade i applikationsstil på subtile måder. Derfor overtager pluginet visningen af sin egen side helt.

Når en besøgende åbner app-siden, serverer pluginet sin egen minimale skabelon i stedet for temaet. Skabelonen udskriver kun pluginets eget stylesheet og scripts via WordPress’ standardfunktioner til styles og scripts og intet fra temaet eller andre plugins. Siden fortæller også caches, at de ikke skal gemme den, og søgemaskiner, at de ikke skal indeksere den, da den er en applikation og ikke indhold.

Selve brugerfladen er skrevet i rene JavaScript-moduler uden framework og samlet i én læsbar fil. Navigationen bruger hash-baserede routes, så skift mellem fakturaer, kunder og indstillinger aldrig genindlæser siden, og browserens tilbage-knap stadig virker. Skrifttypen DM Sans følger med pluginet i stedet for at blive hentet fra en fonttjeneste, så appen laver ingen forespørgsler til tredjepartsservere.

Layoutet blev designet til telefoner fra starten. På små skærme:

  • Sidebaren bliver til en udtrækbar menu.
  • Datatabeller bliver til stablede kort med en etiket på hver værdi.
  • Fakturaeditoren omlægges til én kolonne.

Fakturaer bliver ofte tjekket fra en telefon, når en kunde siger, at de har betalt.

Fakturadashboard på en mobiltelefon
Dashboardet på en telefon.
Fakturaliste som stablede kort på en mobiltelefon
Fakturalisten bliver til stablede kort, og Mark paid er stadig kun ét tryk væk.

Generering af PDF-fakturaer i browseren

Generering af PDF på serveren i PHP betyder som regel tunge biblioteker, skrifttyper på serveren, hukommelsesgrænser og vidt forskelligt output på forskellige hosts. Vi genererer i stedet PDF’en i brugerens browser:

  1. Fakturaen vises som et HTML-dokument i A4-størrelse.
  2. Dokumentet rasteriseres til et billede.
  3. Billedet lægges i en PDF-fil med open source-biblioteket html2pdf.js.

Det giver tre fordele:

  • PDF’en ser præcis ud som forhåndsvisningen på skærmen, fordi den er forhåndsvisningen.
  • Det virker på enhver host.
  • Ingen fakturadata sendes nogen steder hen for at blive konverteret.

Ulempen er, at teksten i PDF’en er et billede og ikke tekst, der kan markeres. For fakturaer, der læses, printes og arkiveres, er det en acceptabel pris for ens output overalt.

De fejl, vi fandt, før vores kunder gjorde

Hver eneste af dem nåede en rigtig skærm. De er værd at beskrive, fordi hver af dem er en type fejl, der også dukker op i andre projekter.

Den tomme side to, forårsaget af en halv pixel

Fakturaer på én side blev downloadet som PDF’er på to sider, og side to var tom. Årsagen: dokumentet på skærmen havde en minimumshøjde på 1123 pixels, så forhåndsvisningen ligner et helt ark papir, men A4 ved 96 DPI er 1122,5 pixels højt. Det halve pixels overløb var nok til, at PDF-biblioteket startede en ny side.

Rettelsen fjerner minimumshøjden kun under eksporten, så forhåndsvisningen stadig ligner papir. Vi bekræftede det ved at tælle siderne i den genererede PDF: to før rettelsen, én efter. En faktura med 45 linjer flyder stadig korrekt over på en side to med indhold.

Et logout-link, der escapede sig selv

WordPress’ funktion til logout-URL’en returnerer en URL, der allerede er escaped til HTML, med &-tegnene skrevet som &. Det er korrekt i en HTML-attribut og forkert i JavaScript, hvor det escapede &-tegn ødelagde sikkerhedstokenet og dermed logout. Rettelsen afkoder URL’en én gang, før den gives til appen. Det er en lille fejl, men typisk for, hvad der sker i grænsen mellem PHP-skabeloner og JavaScript.

Kundelogoer, der aldrig nåede fakturaen

En kundes logo kunne uploades og blev gemt korrekt, men det dukkede aldrig op på fakturaer. Det snapshot, der kopieres ind i hver faktura, indeholdt det simpelthen ikke. Rettelsen havde to dele:

  • Nye fakturaer har nu logoet med i snapshottet.
  • Fakturaer, der er gemt tidligere, falder tilbage på den tilknyttede kundes aktuelle logo, når de læses, uden at de gemte data omskrives.

At lade gemte data være urørte, når man retter et visningsproblem, er en vane, der er værd at holde fast i.

Et dashboardkort, der var uenigt med tabellen

Efter at en faktura var markeret som betalt fra listen, blev rækken i tabellen grøn, men kortet med “seneste fakturaer” over den sagde stadig Unpaid, indtil siden blev genindlæst. To visninger af de samme data var kommet ud af takt. Nu genvises hele skærmen ud fra friske data efter enhver handling, der ændrer en faktura, så alle tal på siden altid stemmer.

Justering, efter et logo blev tilføjet

Med kundens logo placeret over deres adresse startede “Til”-blokken lavere end “Fra”-blokken, og fakturaen så ubalanceret ud. At flytte logoet til højre for adressen løste det: begge blokke starter på samme linje, og logoet flugter med fakturanummeret over det. Derefter gav vi kundekolonnen lidt mere bredde, så en typisk schweizisk gadeadresse bliver på én linje. Læren: test fakturalayouts med rigtige kundedata, for pladsholdernavne er altid bekvemt korte.

Klar til pluginbiblioteket på WordPress.org

Kode, der virker på din egen side, og kode, der klarer gennemgangen på WordPress.org, er ikke det samme. Biblioteket har bestemte regler, og vi ændrede en række ting for at opfylde dem, før vi indsendte.

  • Ingen kald til eksterne servere. Skrifttypen blev oprindeligt hentet fra en fonttjeneste, som sender hver besøgendes IP-adresse til en tredjepart. Den følger nu med pluginet under sin åbne fontlicens.
  • Scripts og styles går gennem WordPress’ egne funktioner. Hardcodede script- og link-tags blev erstattet med registrerede, versionerede filer. Konfiguration til kørselstid tilføjes via standardmekanismen for inline-scripts.
  • Læsbar kildekode. Biblioteket accepterer ikke minificeret kode uden kildekoden. App-bundtet leveres ikke-minificeret, de oprindelige moduler er inkluderet, og readme-filen forklarer, hvordan det bygges igen.
  • Tredjepartslicenser krediteret. PDF-biblioteket og skrifttypen er nævnt i readme med deres licenser og links til kilden, og deres licensfiler følger med pluginet.
  • Ingen kerne-hooks udløst af pluginet. En tidlig version udløste WordPress’ egen login-action efter tilmelding. Nu registrerer den login via sin egen kode i stedet.
  • Afinstallation kræver tilvalg. Sletning af pluginet fjerner intet, medmindre administratoren udtrykkeligt har bedt om at få data fjernet. Fakturaer er forretningsdokumenter, og at miste dem på grund af et klik ved et uheld er ikke acceptabelt.
  • En komplet readme med en kort beskrivelse, installationstrin, FAQ, et afsnit om privatliv og en ændringslog. Koden er struktureret, så det officielle værktøj Plugin Check kan gennemgå den uden anmærkninger.

Ingen af reglerne gjorde pluginet dårligere, og flere gjorde det bedre. At pakke skrifttypen med fjernede for eksempel et spørgsmål om privatliv helt.

Vil du have et WordPress-plugin bygget ordentligt, fra datamodellen og op?

Send os, hvad værktøjet skal kunne. Vi vender tilbage med et klart omfang, afvejningerne og en fast pris inden for én arbejdsdag.

Skal du bygge et skræddersyet fakturaplugin til WordPress eller bruge et eksisterende?

Ærligt talt bør de fleste virksomheder ikke bestille et skræddersyet faktureringsværktøj. Hvis én person sender en håndfuld fakturaer om måneden i én valuta, vil et eksisterende produkt tjene dem godt og koste mindre end nogen skræddersyet løsning. En skræddersyet løsning bliver det bedre valg, når flere af disse ting er sande:

  • Flere personer har brug for separat, adskilt fakturering i ét system, og pris pr. bruger begynder at gøre ondt.
  • Faktureringen skal forbindes med noget, der er specifikt for din forretning, som et bookingsystem, et projektværktøj, et ERP eller en kundeportal.
  • Du fakturerer i flere valutaer og har brug for totaler, der aldrig bliver omregnet bag din ryg.
  • Dine fakturaer kræver regler, som standardværktøjer ikke understøtter, som egne godkendelsestrin, dokumenttyper eller nummereringssystemer.
  • Du vil have, at de finansielle data bliver i infrastruktur, du allerede ejer, tager backup af og kontrollerer.

Hvis kun én af dem passer, så kig først grundigere på eksisterende produkter. Hvis tre eller flere passer, koster et fokuseret plugin som dette som regel mindre over to eller tre år end de abonnementer og nødløsninger, det erstatter. Og det gør præcis det, du har brug for.

Uanset hvilken vej du går, så bedøm ethvert faktureringsværktøj ud fra de ting, denne artikel har dvælet ved:

  • Gemmer det en fast registrering af hver faktura, så senere ændringer af dine eller en kundes oplysninger ikke omskriver gamle fakturaer?
  • Beregner det status ud fra betalinger i stedet for at gemme den?
  • Holder det valutaer adskilt?
  • Adskiller det brugerne fra hinanden?
  • Kan du få dine data ud?

Ofte stillede spørgsmål

Kan et fakturaplugin til WordPress håndtere mere end én bruger?

Ja, hvis det er designet til det. I ArtinTech Invoice Manager tilhører hver faktura og kunde den kontohaver, der oprettede dem, og API’et tjekker ejerskab ved hver forespørgsel. Hver bruger har sine egne indstillinger, logo, nummerering og bankoplysninger og kan ikke se andres data.

Sender det fakturadata til nogen tredjepartstjeneste?

Nej. Alt gemmes i sidens egen WordPress-database. PDF’er genereres i brugerens browser, og skrifttypen følger med pluginet. De eneste udgående beskeder er almindelige WordPress-mails, som beskeder om tilmelding og godkendelse.

Kan det fakturere i forskellige valutaer?

Ja. Hver faktura har sin egen valuta, og dashboardet og kundesiderne viser totaler separat for hver valuta. Intet omregnes, så tallene stemmer altid med de fakturaer, du faktisk har sendt.

Virker det med mit tema eller min sidebygger?

Ja. App-siden vises med pluginets egen skabelon og egne filer, så temaet, Elementor eller en anden bygger ikke kan ændre, hvordan den ser ud eller opfører sig. Resten af din side påvirkes slet ikke.

Findes pluginet på WordPress.org?

Vi har gjort det klar til pluginbiblioteket på WordPress.org, og det vil blive listet der, når det har bestået gennemgangen. Indtil da er du velkommen til at kontakte os, hvis du vil bruge det eller have en version tilpasset din arbejdsgang.

Kan I bygge en skræddersyet version til min virksomhed?

Ja. Egne fakturalayouts, ekstra dokumenttyper, integration med et booking- eller projektsystem, kundeportaler og godkendelsesflows er alle rimelige udvidelser af det samme fundament. Se vores ydelse inden for WordPress-pluginudvikling for, hvordan vi afgrænser det arbejde.

At bygge WordPress-værktøjer som dette er en central del af vores arbejde. Nogle er små rettelser, som den cache-relaterede 403-fejl , vi sporede til en nonces levetid. Andre er komplette applikationer som denne, leveret gennem vores arbejde med WordPress-udvikling og skræddersyet CMS og ERP . Hvis du overvejer et faktureringsværktøj eller et andet stykke software, som din virksomhed bliver ved med at arbejde uden om, så Lad os tale. Vi giver dig en ærlig vurdering, også når svaret er, at et eksisterende produkt kan klare det.

Del denne artikel

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *