Cubus Arts Blog

 
Gabriel Târnovan

factureaza.ro - lansare API

Gabriel Târnovan

La cererea mai multor clienţi şi deoarece considerăm că momentul este oportun, am lansat accesul API la serviciul factureaza.ro.

Pe scurt, aceasta înseamnă că orice alt sistem informatic poate fi integrat cu factureaza.ro. Facturarea devine astfel un modul care nu mai trebuie implementat pentru fiecare aplicaţie în parte. Mai mult, din moment ce toate datele de facturare pot fi păstrate în acelaşi loc, diversele aplicaţii conectate vor împărţi aceleaşi date; integrarea e mai strânsă şi duplicarea informaţiei dispare.

Exemple de utilizare:

  • aplicaţii de e-commerce (dorim să lansăm în curând module de facturare pentru magento şi spreecommerce )
  • SaaS sau alte forme de aplicaţii online pe bază de abonament; noi am integrat de exemplu pe travelbox.ro
  • CRM
  • aplicaţii de project management şi time tracking
  • … orice aplicaţie unde e nevoie de facturare

Detalii tehnice pentru integrarea API-ului factureaza.ro în aplicația voastră gasiți aici: factureaza.ro/documentatie/api.

Pentru implementare am folosit gem-urile serialize_with_options și inherited_resources. Factureaza.ro fiind construit pe Ruby on Rails, implementarea a fost destul de simplă. Mai multe detalii într-un post viitor.

Exemplu concret – integrare travelbox.ro

Pentru travelbox.ro, al doilea SaaS oferit de firma noastră am făcut prima integrare pe baza APIului factureaza.ro după cum urmează:

  • în momentul în care un client nou se înregistrează pe travelbox.ro, se creează automat prin API o înregistrare pentru acest client pe factureaza.ro
  • clientul este înregistrat în funcţia de facturi recurente (abonamente); periodic aceasta va emite facturile aferente
  • de fiecare dată când un utilizator se autentifică pe travelbox.ro, se verifică prin API dacă nu există facturi emise acestul client scadente de mai mult de o lună. Accesul nu este permis dacă acesta este cazul.

În curând travelbox.ro va permite generarea de facturi către turişti, desigur prin intermediul APIului factureaza.ro

În concluzie

Detaliile pentru integrarea APIului găsiţi aici: factureaza.ro/documentatie/api Aşteptăm cu interes să vedem în ce fel îl veţi folosi.

Vă invităm să aruncaţi o privire şi peste openapi.ro – un set de servicii web utile dezvoltatorilor români (date de pe mfinante.ro, geolocare IP, diverse validări, etc) – în uz şi la factureaza.ro

Gabriel Târnovan

factureaza.ro - scurt istoric

Gabriel Târnovan

Înainte de 2007 întocmeam clienţilor noştri din Germania şi Austria facturi cu ajutorul omniprezentului Excel, pentru că facturile în regim special de atunci nu erau acceptate de clienţi. Aceasta creea o situaţie comică: făceam o factură in Euro care era trimisă clienţilor, şi una in Lei care intra în contabilitate. Cum majoritatea clienţilor noştri la acea vreme erau externi, am decis să înlocuim Excelul, directoarele anuale și subdirectoarele lor lunare cu o aplicaţie web-based, pentru că la asta ne pricepem şi pentru că vroiam să emitem facturi de oriunde; inclusiv de la sediul clienţilor din Austria.

Ne-am scris deci cândva în 2005 prima aplicaţie de facturare în PHP care exporta LaTeX din care generam PDF. Am folosit sistemul respectiv fără probleme. Din păcate nu scăpaserăm de redactarea periodică a facturilor pentru clienţii noştri de hosting, majoritatea locali.

În 2007 situaţia s-a schimbat complet. Nu doar că fiecare furnizor işi putea emite facturile în orice formă, dar chiar semnarea şi ştampilarea facturilor nu mai erau obligatorii. Ne-am pus pe treabă şi in aprilie 2007 factureaza.ro era online cu 200 de conturi înregistrate. Aplicaţie Ruby on Rails, Prototype JS, MySQL cluster. Acel moment a reprezentat pentru firma noastră şi trecerea completă pe dezvoltare bazată pe Ruby on Rails, și nu ne-a părut rău niciodată.

După boom-ul iniţial – în prima parte a lui 2007 toată lumea căuta înlocuitor pentru vechile tipizate – evoluţia s-a stabilizat într-o creştere constantă a cererii pentru acest tip de servicii.

În ultimii patru ani am încercat să ţinem pasul cu cerinţele clienţilor noştri prin îmbunătăţirea serviciului, adăugarea de funcţii noi şi oferind un suport cât mai bun. Cele mai recente completări includ:

  • API-ul factureaza.ro prin care oferim posibilitatea clienţilor noştri să integreze sistemul de facturare în propriile sisteme (eCommerce, CRM, etc).
  • integrare cu openapi.ro
  • un sistem de drepturi prin care se poate partaja accesul angajaților la facturile firmei
  • ajutor live prin chat direct de pe site (prin integrarea serviciilor olark.com)

De la câteva sute de utilizatori la sfârșitul lui 2007 am ajuns acum la peste 4200 și un total de peste 150.000 facturi emise. Valoarea totală a facturilor emise se apropie de jumătate de miliard de RON. Dar despre asta într-un alt post.

Mihai Târnovan

Profilul utilizatorului factureaza.ro

Mihai Târnovan

Spre surpriderea mea, nu cunosc nici un SaaS românesc în afara concurenței factureaza.ro. Miopia mea e ușor de înțeles, dar în acest articol mă voi concentra nu pe piața românească de soluții de facturare online, ci pe o analiză a profilului utilizatorului român de soluții SaaS, așa cum reiese el din statisticile adunate de factureaza.ro din 2007 până în prezent. Ca atare, nu este cazul să extrapolăm aceste date la toată piața română de SaaS-uri, dar putem cel puțin să ne formăm o idee mai bună despre utilizatorii români de internet care au înțeles utilitatea acestui mod de utilizare a software-ului (deși pe piețe mai mature SaaS-urile au penetrat deja piața destul de consistent, la noi acești utilizatori pot fi considerați încă pionieri / early adopters). Datele la nivel național au fost preluate de pe statcounter.com.

Date tehnice

Browser

  Firefox IE Chrome Safari Opera
România 43.32 34.45 14.08 0.79 7.1
Factureaza.ro 45.58 26.32 20.16 5.36 2.58

Utilizatorii factureaza.ro folosesc browserul Firefox aproximativ în aceeași proporție ca la nivel național, în schimb mai puțin Internet Explorer și Opera, preferând în detrimentul acestora cele două browsere bazate pe WebKit.

Fără să mai intrăm în detalii legate de versiunile specifice de browser folosite, este totuși de menționat (și de lăudat) declinul constant al infamului browser Internet Explorer 6 printre utilizatorii factureaza.ro, de la 42% în aprilie 2007 la doar 3% în aprilie 2011.

Ponderea mult mai ridicată a browserului Safari sugerează și că mai mulți dintre utilizatorii factureaza.ro sunt utilizatori de Mac-uri.

Sistem de operare

  Windows MacOS Linux
România 98.5 0.8 0.6
Factureaza.ro 83 10 5

O pondere mult mai mare a sistemelor de operare non-Windows susține ipoteza că utilizatorii factureaza.ro sunt mai experimentați din punct de vedere tehnic decât media națională.

Apare o schimbare şi la preferinţele de limbă (detectate în browser) ale vizitatorilor: engleza scade de la 82% la 70%, româna creşte de la 6% la 20%. Trendul este bun, de aliniere lentă la o situație normală în care developerii pot să se bazeze pe limba detectată în browser.

Plăți online

Introdusă la începutul lui 2009 pe factureaza.ro, plata cu cardul ar trebui să fie teoretic modalitatea cea mai potrivită pentru utilizatorii noştri. Plata se face imediat, se evită întocmirea de OPuri, comisioanele sunt suportate de noi etc. Cu toate aceste avantaje, adopția acestei modalități de plată este încă relativ modestă (comparativ cu alte piețe, unde – pentru SaaS-uri – plata online cu cardul este practic singura modalitate acceptată):

Procentul de plăți la factureaza.ro efectuate prin card
2009 6.25%
2010 11.5%

Clienții factureaza.ro după activitate (cod CAEN)

După cum era de așteptat, cei mai mulți dintre cei care folosesc serviciu nostru de facturare online activează în domeniul tehnologiei informației și al comerțului.

Clienții factureaza.ro după activitate (cod CAEN)
Activitati de servicii in tehnologia informatiei 15.14%
Comert cu ridicata cu excepta comertului cu autovehicule si motociclete 9.56%
Comert cu amanuntul, cu exceptia autovehiculelor si motocicletelor 8.76%
Activitati ale directiilor (centralelor), birourilor administrative centralizate 7.57%
Transporturi terestre si transporturi prin conducte 6.77%
Lucrari speciale de constructii 4.78%
Publicitate si activitati de studiere a pietei 4.38%
Telecomunicatii 3.59%
Activitati ale agentiilor turistice si tur-operatorilor 2.79%
Constructii de cladiri 2.79%
Altele 33.86%

Remarci și concluzii

Utilizatorul factureaza.ro folosește Mac-uri și Linux considerabil mai mult decât media la nivel național și activează cel mai probabil în IT, comerț sau administrație. Plățile online și-au dublat ponderea în 2009 față de 2010. Internet Explorer 6 a scăzut la o cotă de piață insignifiantă, care nu mai poate justifica eforturile de dezvoltare necesare pentru păstrarea compatibilității cu acesta.

Unde procentele nu se însumează la 100%, s-au eliminat categorii cu procente irelevant de mici. Datele preluate de pe statcounter.com au fost pentru data de 10. aprilie, cele preluate de la factureaza.ro sunt furnizate de Google Analytics pentru intervalul aprilie – mai 2011 (pentru a dispune de un eșantion mai relevant).

Andreas Philippi

Truncate typo3 indexed search tables

Andreas Philippi

Huge table index_rel never stops growing

On one of our webservers we have a lot of typo3-based sites. Some of them make use of the indexedsearch extension, which uses some database tables to store the indexed data. These tables can grow really huge .

Bad performance for search queries

The table index_rel grows very fast, having over 6.000.000 entries for some typo3 installations. Even a simple search takes over 30 seconds to complete. I searched for an elegant solution with very little success.

Our current solution: periodical brute force

Here is a brute force solution: a ruby-script that finds all databases that have a index_rel-table and truncates all indexed search tables if they reach a given size. The tables will be automatically refilled every time a page is accessed.

The script truncates the “cache tables” also, the “indexed search tables” will not be rebuild by public requests if only the cache for a given page is returned by a request.

If you want to refill the search instantly index can write a script the crawls the site using wget —spider or something similar.

The script

We call this via cron once a week – every friday night

Gabriel Târnovan

Simple Audit for Rails Apps

Gabriel Târnovan

simple_audit is a lightweight auditing solution for Rails apps. Instead of auditing all attributes of your models, simple_audit allows you to specify what data is relevant for auditing. This simple idea makes auditing complex model aggregations (through has_many, has_one, habtm associations) trivial.

Audit in 2 minutes:

Result will look like this:
Screenshot of helper result

Why ?

simple_audit is intended as a straightforward auditing solution for complex model associations. In a normalized data structure (which is usually the case when using SQL), a core business model will aggregate data from several associated entities. More often than not in such cases, only the core model is of interest from an auditing point of view (the parent in the has_xxx relations).

One approach would be to audit all aggregated entities sepparately. The downside of this is the high complexity of retracing all changes triggered on each save. Another minus is the increased database workload.

simple_audit takes a simpler approach: you decide for each audited model what data needs to be audited by specifying a serializable representation of all relevant information – including the any relevant aggregated entities (e.g. the housing_unit_bookings in the above example) This data will be serialized on every save. The available helper methods will render a clear audit trail (see above).

Limitations

This is not a solution for versioning. Changed data can not be restored. Use acts_as_audited or acts_as_versioned for that.

Dependencies

The current user is assumed to be available by calling User.current You can use sentient_user or roll your own solution.

More information

Read more on the github page. Contributions are welcome!

Andreas Philippi

Typo3 TMENU_LAYERS generates endless recursion loop

Andreas Philippi

What happens?

You have a typo3-template which uses TMENU_LAYERS. You may notice that you’ll get “too much recursion” javascript-errors on all browsers.

microtime is not enough :)

This errors happens because of a unique-ID-generating-function uses microtime. On some machines the microtime-based function does not provide unique IDs.

Under certain conditions, when using TMENU_LAYERS the layers containing the navigation items get non-unique IDs.

We noticed this error after migrating several sites in a virtualized environment on a very fast machine.

our solution

To correct this error we used the php-function uniqid to give us unique ids.

We proceeded this way:

  • locate the file /typo3/sysext/cms/tslib/media/scripts/tmenu_layers.php
  • search for the string: substr(md5(microtime()),0,6);
  • replace the string using: str_replace(‘.’,‘’,uniqid(‘’,true));

We also filed a bug

Mihai Târnovan

Installing mysql gem with Percona XtraDB

Mihai Târnovan

After installing the mysql gem, we were seeing uninitialized constant MysqlCompat::MysqlRes errors all over the place, although the gem installed fine.

This was on FreeBSD 8.1. Turns out Percona XtraDB binary doesn’t include the mysql client libs, so you need to install those as well. On FreeBSD just do

pkg_add -r mysql51-client

Then reinstall the gem:

env ARCHFLAGS="-arch x86_64" gem i mysql -- --with-mysql-config=/usr/local/percona-xtradb/bin/mysql_config

Mihai Târnovan

Ruby Eval stacktrace position information

Mihai Târnovan

We’ve been often annoyed by warnings or exceptions like this: (eval):231: some error or warning. They make it very difficult to pinpoint the exact location of the problem.

The problem is usually cause by module_eval being called without file and line information. There’s an interesting write-up about eval and position information on Ola Bini’s blog. One of his readers observed that when using module_eval like this you’ll get the incorrect line number:

However, I noticed that if you write the heredoc inline you’ll get the correct line in the backtrace:

__LINE__ + 1 accounts for the line with the module_eval itself. I tested this with Ruby 1.8.6 and Ruby 1.9.1 and it applies for both, tough 1.9 at least puts more lines in the backtrace with the position of the module_eval call.

Passing __FILE__ and __LINE__ is better than skipping them, but can lead to false line numbers unless you use the 2nd form with the inlined heredoc.

Mihai Târnovan

Dear typographers

Mihai Târnovan

The romanian language has some specific diacritics which can radically change the meaning of a word.

The problem

For example țânc vs. tanc, tata vs. țâța vs. țața (kid vs. tank, father vs. breast vs. aunt). The problem with this characters and their implementation in keyboard layouts, charsets and fonts, is well known and has been explained in almost academic detail and extremely well documented manner by Cristian Secară.

Microsoft’s “solution” and its consequences

When Microsoft implemented the first romanian keyboard layout, they mapped the keys which should have produced these characters to similar turkish characters instead. They could have fixed this as early as Windows 2000 (around then the romanian standard SR 13411:1999 was already in place). Instead, they did nothing until 2007.

By then, their core fonts were already the de facto standard for web typography and everyone had fonts installed on their computer which lacked characters for lowercase and uppercase ș and ț (Unicode code points U+0218, U+0219, U+021A and U+021B).

Fixing the problem and causing new ones

It took Microsoft until 2006 to get it right. They released a patch which added the missing characters to Times New Roman, Arial and Verdana. When they released Windows Vista, they still didn’t get it right for all fonts – Verdana was only fixed by a later patch.

Ok, so Microsoft release a patch for XP and did the right thing with Vista. So everything’s fine, right ? Well, not quite. If you use the Romanian keyboard layout on Vista or MacOS, you will write text containing the proper Unicode characters. But a vast majority of romanian users don’t have these characters in their fonts, because they didn’t apply the font patch. So for them, a ș written with the proper romanian character appears as a square.

Possible solutions

  1. Use fonts that never had this problem in the first place.
    • Palatino Linotype
    • Tahoma

    This is of course too limiting for practical purposes, especially in web design.

  2. Use old keyboard layout.

    I still haven’t figured out how to do this for MacOS without custom keyboard layouts, but it should be fairly easy to do this for Vista and Linux (use Romanian legacy or a similar keyboard layout). You’ll write text with turkish diacritics, but at least all your visitors will be able to display them correctly.

  3. Serve two versions of content, one for Windows XP (and older) users with turkish characters, and one for all the others.

    Due to the complexity of this solution, I’m not sure this is a good idea. (we do this for travelbox with a Rack filter — but that was implemented more to learn about Rack than as a long term solution for this problem)