Як я робив свій облік фінансів під андроїд з блекджек, СМС і ФНС

  1. Вступ Все почалося в далекому 2011-му році, коли я купив свій перший андроїд смартфон і відкрив для...
  2. Бібліотеки та тулінг
  3. продуктивність
  4. Дизайн
  5. парсинг смс
  6. Завантаження касових чеків ФНС
  7. Автоматизація
  8. Синхронізація
  9. Просування і заробіток
  10. GitHub
  11. висновок

Вступ

Все почалося в далекому 2011-му році, коли я купив свій перший андроїд смартфон і відкрив для себе дивовижний світ андроїд маркету. Саме там я знайшов чудове додаток для обліку фінансів Financisto. Кілька років я трекал в ньому свої витрати і доходи, сильно звик, проте були і слабкі сторони:


  • необхідність вводити всі транзакції вручну. Притому, що частка безготівкових платежів неухильно росла, а банк на кожен чих шле вам смс.
  • немає глобального погляду на бюджет в тривалому часовому розрізі. Тобто хотілося бачити таблицю, припустимо, на рік, де для кожного місяця було б видно, скільки планувалося витратити і заробити і скільки вийшло за фактом, плюс разом по всіх рядках і стовпцях. Тут орієнтиром був YNAB.
  • немає синхронізації між пристроями. Так був Flowzr, але якось він мені не зайшов.

Якщо друга проблема вирішилася експортом в CSV і всемогутнім Ексель, то з іншими потрібно було щось робити. Очевидний варіант - змінити програму. Повивчавши пропозицію, прийшов до висновку, що всі програми діляться на мізерні по функціоналу і на дорогі :) Тим часом йшов 2015-й рік і мені все сильніше хотілося вивчити розробку під мобільні девайси. Що ж, зірки сходяться, прийнято рішення пиляти свій додаток!


Так як мій девелоперський бекграунд був пов'язаний з написанням вузькоспеціалізованих програм на дельфи, то, природно, першим поривом було спробувати мультиплатформенні розробку в самій дельфи. Але не будемо про те сумному досвіді, я швидко прийшов до висновку, що мені потрібно нативное додаток і нормальний тулінг. Так була завантажена андроїд студія і створений новий проект. Далі йде мій потік свідомості, який я постарався розділити за темами.




Про програму


Додаток має 2 основні сутності: рахунки і транзакції. Рахунок, це сховище коштів, транзакція - переміщення коштів. Транзакції бувають трьох видів:


  • прихід - поповнення рахунку третіми особами
  • витрата - виплата наших коштів третім особам
  • переклад - переклад коштів між своїми рахунками

Власне в цьому вся концепція програми. Далі опишу, що фактично було реалізовано. Деякі моменти опишу докладно нижче.


Отже, перше, що потрібно для спрощення життя, це парсинг смс від банків для автоматичного створення транзакцій. Потім був зроблений імпорт / експорт даних в CSV, причому предмет особливої ​​гордості - настроюється імпорт, що дозволяє завантажувати дані з файлів CSV довільної структури. Є сканер чеків ФНС РФ і завантаження інформації по ним з сервера. Для зручного обліку атрибути транзакцій зроблені багаторівневими. Наприклад, можна створити таке дерево категорій:


├ Витрати │ ├ Автомобіль` │ │ ├ Заправка │ │ └ Обслуговування │ ├ Їжа │ └ Розваги │ └ Доходи

Аналогічна структура можлива і у інших атрибутів, таких як Одержувачі (контрагенти), Проекти і т.д. Для зручної навігації по даним зроблена система фільтрів, за різними ознаками. Реалізовано управління боргами і бюджетування. Крім того є вагон і маленький візок дрібніших функцій, які я перераховувати тут не буду.


Бібліотеки та тулінг


З нестандартних використовуваних бібліотек можу виділити ButterKnife і EventBus. Хоча в 2018 році вони виглядають анахронізмом, на момент початку розробки вони виглядали багатообіцяюче. Зараз же я не готовий здійснити повномасштабний рефакторинг. Експериментував з RetroLambda і Rx, але випиляв їх як не відповідають завданню. В результаті зараз проект це чиста Java 7, хоча велике бажання піддатися хайп і спробувати Kotlin.


Дуже корисною виявилася бібліотека io.requery: sqlite-android, що дозволяє мати завжди актуальну версію SQLite. У додатку реалізовані дерева сутностей (наприклад, вкладені категорії) без обмеження по глибині і для вибірки таких даних дуже ефективно використовувати рекурсивні запити. На жаль, вони з'явилися в досить свіжих версіях SQLite і не доступні на старих версіях андроїда. Requery вирішує цю задачу.


На даний момент в коді 39 зовнішніх залежностей. Так, це багато, і я проводжу планомірну роботу по їх зменшенню. Але, тим не менше, вважаю, що використання сторонніх бібліотек ефективно при швидкому нарощуванні функціонала.


Дуже хочеться впровадити нормальний DI, але знову ж таки поки немає на це часу.


Кілька слів про тулінге. Якщо в 2014-2015 ще можна було почути про те, що розробляти потрібно в Eclipse, а Genymotion був musthave для розробника під андроїд, то сьогодні Гугл всіх затьмарив. Android Studio дуже швидка і зручна, втім як і вбудований емулятор.


Так само хотілося б сказати спасибі kaftanati за його інструмент . Він дозволяє вести гугл-таблицю із строковими ресурсами на різних мовах і перетворювати її в xml-файли. Дуже спрощує процес локалізації. До слова на даний момент додаток доступний на 2-х мовах: EN і RU.


В процесі розробки непогано освоїв Git, виявилася незамінна річ.


продуктивність


Оптимізації продуктивності було приділено чимало часу. Виділити такі моменти, що зробили значний вплив:


  • Глибина вкладеності лейаута. Чим менше тим краще. Проблема практично зникла після впровадження constraint layout.
  • Оптимізація БД. Індекси наше все.
  • Профайлинг. TraceView це дуже корисний інструмент для розуміння того, що проісходт в надрах додатка.

В цілому зараз я задоволений продуктивністю. Моя особиста база, яка є одночасно тестової, містить архів транзакцій за 5 років (> 7000 транзакцій) і при цьому нітрохи не гальмує на не самих швидких телефонах.


Дизайн


Особисто у мене з дизайном все погано. Напевно тому перша версія вийшла такою вирвіглазной. Однак при цьому вона більш-менш відповідала нормам матеріального дизайну). Така версія проіснувала близько двох років, коли нарешті я зрозумів, що треба щось міняти. Так як досвід показував, що сам я не впораюся, то був кинутий клич серед фрілансерів. Такий досить швидко знайшовся і за розумні гроші перемалював мені все екрани. Результат я отримав в psd, але так як я був уже чув про таку чудову інструменті як Zeplin, то сам швиденько все в нього експортував і переробив дизайн. Нинішній мені подобається набагато більше, крім того в процесі переробки сформувалися якісь внутрішні гайлайни, так що тепер створення нового екрану не викликає ускладнень.


Було і стало:



Перша версія матеріального дизайну полягала, по-суті, з одних гайдайнов, з якими розробник залишався один на один. По-цьому розплодилося безліч бібліотек, які пропонували реалізацію UI. Не оминула ця проблема і мене, в бажанні реалізувати якомога ближче до ідеалу було імпортовано багато бібліотек. Але Гугл виправляється і рухається в бік однаковості і спрощення в процесі розробки. Сучасна версія support'а дозволяє обійтися практично без сторонніх компонентів.


парсинг смс


Більшість додатків практикує парсинг смс по встановленим форматам. Тобто розробник бере смс конкретного банку, пише правила як його розбирати на частини і вшивається в код. Буває такі правила можна правити користувачам, але це досить мудрі процес. Переваги та недоліки такого підходу очевидні: якщо розробник впровадив підтримку твого банку, то все відмінно і швидко працює. Однак, якщо банк раптом вирішить поміняти формат або ваш банк не відомий розробнику, то все різко перестає працювати. Я вирішив, що додаток нічого не повинно знати про формат смс і покласти все на користувача, постаравшись максимально полегшити йому завдання.


Отже загальна концепція така: вам приходить смс, наприклад, такого змісту: "VISA1234 01.01.18 12:00 покупка 106.40р SUPERMARKET Баланс: 6623.34р" (Сбербанк). Очевидно, що тут можна витягти наступну інформацію: номер карти (рахунок), дата і час, одержувач коштів, сума транзакції і залишок коштів на карті. Завдання користувача правильно розставити ключові слова (маркери): виділити "VISA1234" і поставити маркер рахунок, на "SUPERMARKET" поставити маркер Одержувач і т.д.


Виглядає це приблизно так:

Виглядає це приблизно так:


Додаток запам'ятовує всі маркери і таким чином навчається. Досвід показує, що після тижня-двох навчання, 90% транзакцій створюються автоматично без участі користувача. Так, потрібно затратити деякі зусилля, але незалежність від сторонніх осіб на мою думку варто того.


Користувачам теж подобається, надходить дуже багато "хотелок", так, наприклад були реалізовані: імпорт раніше прийшли смс, парсинг смс з буфера обміну і т.д.


Завантаження касових чеків ФНС


У минулому році ФНС РФ піднесла всім продавцям подарунок зобов'язавши відправляти все касові чеки в електронному вигляді на свої сервера. Простим людям теж трохи перепало у вигляді офіційного мобільного застосування, в якому можна перевірити чек на справжність і, що найбільш важливо, завантажити його собі в форматах pdf або json. Не раз уже ця тема тут обговорювалася, однак, коротко: офіційного апі для отримання чека немає. Воно може бути у деяких з ОФД (оператори фіскальних даних, через яких чеки потрапляють з кас в ФНС), але так, що б взяти і отримати будь-який чек в одному місці - немає. АЛЕ, є офіційне мобільний додаток, що працює через http, зі звичайною http-авторизацією, ніж давно скористалися добрі люди, послухати трафік і виклали його апі на загальний огляд. Там все просто. Можна створити нового користувача, отримавши пароль по смс, можна скачати вміст чека за його даними, і можна завантажити все чеки за певний період, раніше завантажені даними користувачем. Для полегшення завдання на кожному чеку друкується QR-код, що містить всі необхідні для отримання чека дані.


Далі все просто qrcodereaderview + retrofit і вміст чека у нас в руках. У зв'язку з можливістю завантажувати список товарів в чеку, була реалізована можливість ці товари прикріплювати до транзакції. Тобто тепер у вас транзакція може бути не просто сумою, а складовою сумою, наприклад, товар1 х к-ть х вартість + товар2 х к-ть х вартість + ... Причому кожному товару можна призначити окрему категорію і проект, що буває дуже корисно при покупках в супермаркетах, коли за один раз береться багато різнорідного товару.


Автоматизація


Одним з цікавих запитів користувачів виявилося бажання автоматизувати створення транзакцій за допомогою ІНТЕНТ, що власне і було зроблено. Можна в будь-якому додатку створити Интент з сумою, і атрибутами транзакції і послати його в моє додаток, після чого така транзакція буде автоматично створена. Сам, чесно кажучи, такий метод не застосовую, але є люди, які Парс emailи в Таскер, а потім створюють на їх основі транзакції. Або ще варіант - створення транзакцій голосом через Дусю.


На жаль, поки є проблеми на 8-му андроїд, так як там заборонили фонове виконання ІНТЕНТ. Планую в найближчих версіях зробити запуск foreground-процесу тим користувачам, які хочуть такий функціонал.


Синхронізація


Синхронізація, як багато в цьому слові ... Ведення загальної бази було одним з основних завдань створення проекту. На жаль, вона до цих пір не реалізована. Причина - занадто комплексне завдання для пет-прожекту одну людину. Спроба була. І навіть була робоча версія. Зробив я її на Firebase. На перший погляд це виглядало не складно. Є гігантський json, в якому лежать загальні бази. Вся аутентифікація робиться 10-ю рядками в правилах безпеки в консолі. Апі дуже просте і зручне. Алгоритм був приблизно такий:


  1. Користувач логинится в Realtime Database за допомогою учеткі Гугла.
  2. Йому заводиться нода, в яку вивантажується вся його база.
  3. Потім він дає дозвіл на модифікацію своєї бази іншим користувачам, так само по gmail'у.
  4. Інші користувачі, при підключенні, вказують, що хочуть працювати з чужої базою і вводять адресу першого користувача, потім підключаються до його ноді і можуть видаляти інформацію.

Потім почалися проблеми: як зробити розмежування прав доступу ?; на великих базах були проблеми з продуктивністю; синхронізацію передбачалося пропонувати у вигляді підписки, для цього потрібна верифікація на сервері, тобто знову ж таки потрібен бекенда. Звичайно всі ці проблеми були пов'язані з недоліком мого досвіду і відсутністю часу на повномасштабне вивчення питання, але кулею в голову даного підходу стала заява Гугла про те, що relatime database, це тепер стрьомно, робіть ка все на Firestore. Загалом поки ця затія поставлена ​​на паузу, продовжую вивчати шляхи вирішення. На даний момент мені бачаться наступні варіанти реалізації:


  • Спробувати все-таки Firestore, там ввели колекції, спростилася робота зі складними структурами даних.
  • Плюнути на все і зробити свій бекенд. Поки що непоганим кандидатом виглядає Postgres + Postgrest. Мінімум розробки, більше контролю, але знову ж таки є незрозумілі моменти.
  • Екзотичний варіант - xmpp сервер. Взагалі не зберігати дані на сервері, а лише пересилати їх між користувачами. Так може проявитися, на мій погляд, втратою консітентності, але є і плюси (хоча як подивитися) у вигляді повної відсутності бекенд.

Загалом, мені був би цікавий ваш досвід вирішення даного завдання, може хто наставить на шлях істинний.


Просування і заробіток


Напевно найслабша сторона мого проекту. На превеликий мій жаль, розробляти мені набагато цікавіше ніж продавати. Трафік виключно органічний. Проект представлений на 4PDA, там же сформувалася база лояльних користувачів. Значно збільшила кількість установок публікація, знову ж на 4PDA, в рамках програми підтримки розробників. Можу сказати, що кошти витрачені на неї окупилися, але не більше.


Спочатку програма була задумана як навчальний проект, тому про заробіток на ній не йшлося. Однак, in-app purchases теж треба вивчити, тому була додана концепція Pro-функцій, тобто платних фич. Фича така поки одна єдина - це можливість будувати графічні звіти. Планував зробити підписку на синхронізацію, але через брак фичи, так і немає підписки.


GitHub


Тривалий час я не міг зважитися відкрити вихідні. Ну знаєте, хакнуть покупки, будуть сміятися над кодом і т.д. Але потім прийшло розуміння, що відкритий вихідний код буде благом, тому він доступний за засланні .


висновок


Основна мета, яку я ставив перед собою починаючи цей проект, виконана - я навчився андроиду. І, можна сказати, навіть досяг успіху в цьому. Для повноцінного звання success story, звичайно, не вистачає комерційного успіху, але, тим не менше, я радий, що мені вдалося розвинути проект і довести його до пуття. Гріє думка і про те, що справа роблю корисну для людей.

Потім почалися проблеми: як зробити розмежування прав доступу ?