Всем привет. Это первая статья из цикла «Как я делаю свой проект». Здесь пойдет речь не о самом сервисе, а о том, как он реализовывается.

Кратко об архитектуре всего сервиса:
  1. Слой данных и бизнес-логики: СУБД PostgreSQL 9.4
  2. Средний слой: Node.js (Express) + Redis. Реализация REST API, шардинг (горизонтальное масштабирование)
  3. Клиенты:
    • web-приложение
    • мобильное приложение

Сразу скажу, что API сервиса полностью открыты как и исходный код Web-приложения (в будущем и исходники мобильного приложения будут выкладываться на github)

В данной статье будет рассматриваться Web-приложение.

Итак, я использую:
  • CoffeeScript. Так получилось, то я изучал Marionette.js по скринкастам от Brian Mann, а он использовал Ruby On Rails и CoffeeScript. Позже я отказался от Ruby On Rails, а вот CoffeeScript прижился.
  • Marionette.js — MVC фреймворк (для знакомства можно почить здесь)
  • Gulp — сборка проекта
  • Bower — пакетный менеджер

Что из себя представляет это web-приложение? Это несколько маленьких статических страниц (регистрация, подтверждение регистрации, сброс пароля, подробное описание сервиса) и одна главная страница-приложение (Single-Page Application).

Файловая структура проекта

  • _ — главная страница сайта
  • _<page_name> — страница первого уровня
  • _<page_name>__<sub_page_name> — страница второго уровня
  • bower_components
  • lib — общие библиотеки для всех страниц
  • node_modules
  • public — собранный проект

Файловая структура страницы

Файловая структура страницы

Файл app/assets/javascripts/app.coffee> — это «точка входа» для страницы.

Папка app/assets/javascripts/backbone нужна только для SPA.
  • apps — содержит модули-приложения. Своего рода это «кирпичики», из которых строится web-приложение. Они полностью независимые друг от друга и общение между ними идет только через шину сообщений.
  • entities — описание моделей и коллекции
  • lib — вспомогательные библиотеки

Шаблон для index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <link href="/_<page_name>[/<sub_page_name>]/assets/app.css" media="screen" rel="stylesheet"/>
</head>
<body>


<script src="/_<page_name>[/<sub_page_name>]/assets/app.js"></script>
</body>
</html>

Данные приложения

Все глобальные коллекции и модели хранятся в объекте App.entities. Доступ в приложении к сущностям может быть как прямой (App.entities.projects), так и через глобальную шину сообщений: App.request('project:entities')

Стандартно для каждой сущности есть две функции:
  • App.request('project:entities') — возвращается коллекция сущностей
  • App.request('project:new:entity') — возвращается новая сущность

Запуск приложения

  • Пользователь со страницы входа отправляет запрос на аутентификацию. Если все в порядке, то запрос возвращает токен авторизации, который нужно передавать со всеми будущими запросами к серверу. Этот токен сохраняется в sessionStorage браузера и делается редирект на страницу /i. Это и есть SPA.
  • Отрабатывается функция входа на страницу /i, где проверяется наличие токена авторизации в sessionStorage. Если все в порядке, то запускается приложение (см. Marionette.Application).
  • Делается один запрос на получения справочников и другой необходимой информации.
  • Запускаются модули-приложения бокового меню и шапки.

Модули-приложения

Все остальные модули-приложения работает только с основной частью страницы — главным регионом. Запускаются они через смену адресной строки (см. Marionette.AppRouter)

Для примера рассмотрим модуль «Проекты» (backbone/apps/references_projects).

Файловая структура модуля

Описание модели и коллекции проектов (файл backbone/entities/project.coffee)
@CashFlow.module 'Entities', (Entities, App, Backbone, Marionette, $, _) ->
  class Entities.Project extends Entities.Model
    idAttribute: 'idProject'
    urlRoot: App.getServer() + '/projects'

    defaults:
      idUser: null
      idProject: null
      name: ''
      writers: []
      note: ''

    parse: (response, options)->
      if not _.isUndefined response.project
        response = response.project
      response

  # --------------------------------------------------------------------------------

  class Entities.Projects extends Entities.Collection
    model: Entities.Project
    url: 'projects'

    parse: (response, options)->
      response.projects

    initialize: ->
      @on 'change:name', =>
        @sort()

    comparator: (project) ->
      project.get('name')

  API =
    newProjectEntity: ->
      new Entities.Project

    getProjectEntities: (options = {})->
      _.defaults options,
        force: false
      {force} = options

      if !App.entities.projects
        App.entities.projects = new Entities.Projects
        force = true

      projects = App.entities.projects

      if force
        projects.fetch
          reset: true

      projects

  # --------------------------------------------------------------------------------

  App.reqres.setHandler 'project:new:entity', ->
    API.newProjectEntity()

  App.reqres.setHandler 'project:entities', (options)->
    API.getProjectEntities(options)
    

Модуль состоит из:
  • Основной файл. Здесь описываются роутеры и обработчики вызовов через общую шину сообщений (внешний интерфейс модуля, через который другие модули могут с ним взаимодействовать)
    references_projects_app.coffee
    @CashFlow.module 'ReferencesProjectsApp', (ReferencesProjectsApp, App, Backbone, Marionette, $, _) ->
      class ReferencesProjectsApp.Router extends Marionette.AppRouter
        appRoutes:
          'references/projects': 'list'
    
      API =
        list: ->
          ReferencesProjectsApp.list()
    
      App.addInitializer ->
        new ReferencesProjectsApp.Router
          controller: API
    
      @list = (project) ->
        new ReferencesProjectsApp.List.Controller
          project: project
    
      @edit = (project, region) ->
        new ReferencesProjectsApp.Edit.Controller
          project: project
          region: region
    
      # --------------------------------------------------------------------------------
    
      App.reqres.setHandler 'project:edit', (project, region = App.request 'dialog:region') ->
        isNew = project.isNew()
        editController = ReferencesProjectsApp.edit project, region
    
        editController.on 'form:after:save', (model) ->
          if isNew
            projects = App.request 'project:entities'
            projects.add model
          editController.form.formLayout.trigger 'dialog:close'
    
        editController
                
  • Подмодули. Подмодуль — это реализация одного конкретного действия: показ списка (list), редактирование (edit), копирование(copy) и т.д.

Подмодуль состоит из:
  • controller.coffee — создает и показывает основной layout модуля
    controller.coffee
    @CashFlow.module 'ReferencesProjectsApp.List', (List, App, Backbone, Marionette, $, _) ->
      class List.Controller extends App.Controllers.Application
        initialize: (options = {})->
    
          projects = App.request 'project:entities'
    
          @layout = @getLayoutView projects
    
          # после показа layout показываем панель и список проектов
          @listenTo @layout, 'show', =>
            @showPanel projects
            @showList projects
    
          # показываем layout в главном регионе приложения
          # при смене layout (когда другой модуль начнет работать)
          # все зависимые представления будут автоматически закрыты
          @show @layout
    
        getLayoutView: (projects) ->
          new List.Layout
            collection: projects
    
        showPanel: (projects) ->
          panelView = @getPanelView projects
          @show panelView,
            region: @layout.panelRegion
    
        getPanelView: (projects) ->
          new List.Panel
            collection: projects
    
        showList: (projects) ->
          listView = @getListView projects
          @show listView,
            region: @layout.listRegion
    
        getListView: (projects) ->
          new List.Projects
            collection: projects
    
                
  • view.coffee — описывает представления
    view.coffee
    @CashFlow.module 'ReferencesProjectsApp.List', (List, App, Backbone, Marionette, $, _) ->
      class List.Layout extends App.Views.Layout
        template: 'references_projects/list/layout'
    
        # определяем два региона для панели с кнопками и для таблицы
        regions:
          panelRegion: '[name=panel-region]'
          listRegion: '[name=list-region]'
    
      # --------------------------------------------------------------------------------
    
      class List.Panel extends App.Views.ItemView
        template: 'references_projects/list/_panel'
    
        ui:
          btnAdd: '.btn[name=btnAdd]'
          btnDel: '.btn[name=btnDel]'
          btnRefresh: '.btn[name=btnRefresh]'
    
        events:
          'click @ui.btnAdd': 'add'
          'click @ui.btnDel': 'del'
          'click @ui.btnRefresh': 'refresh'
    
        collectionEvents:
          'sync': 'render'
    
        add: ->
          model = App.request 'project:new:entity'
          App.request 'project:edit', model
    
        del: ->
          model = @collection.getFirstChosen()
          if confirm('Вы уверены, что хотите удалить данный проект?')
            model.destroy()
    
        refresh: ->
          App.request 'project:entities',
            force: true
    
      # --------------------------------------------------------------------------------
      # View для строки таблицы
      class List.Project extends App.Views.ItemView
        template: 'references_projects/list/_project'
        tagName: 'tr'
    
        modelEvents:
          'change': 'render'
    
        events:
          'click a': ->
            @model.choose()
            App.request 'project:edit', @model
    
    
      # --------------------------------------------------------------------------------
    
      # View, который будет показан, если нет проектов
      class List.Empty extends App.Views.ItemView
        template: 'references_projects/list/_empty'
        tagName: 'tr'
    
      #-----------------------------------------------------------------------
    
      # CompositeView для таблицы проектов
      class List.Projects extends App.Views.CompositeView
        template: 'references_projects/list/_projects'
        childView: List.Project
        emptyView: List.Empty
        childViewContainer: 'tbody'
    
        collectionEvents:
          'sync': 'render'
    
                
  • Папка templates — шаблоны, используемые при формировании представлений
    • layout.eco — определяем регионы, где будут отображатся представления и их расположение
      layout.eco
      <div name="panel-region" id="ribbon">
      </div>
      
      <div name="list-region">
      </div>
                          
    • _panel.eco — панель инструментов
      _panel.eco
      <div class="row">
          <div class="col-sm-9">
              <h3 class="page-title">
                  Справочники <span>> Проекты</span>
              </h3>
          </div>
      </div>
      <div class="btn-toolbar" role="toolbar">
          <div class="btn-group">
              <button type="button" name="btnAdd" class="btn btn-default">
                  <i class="fa fa-plus"></i>
                  Добавить
              </button>
              <button type="button" name="btnDel" class="btn btn-default">
                  <i class="fa fa-trash-o"></i>
                  Удалить
              </button>
          </div>
      
          <div class="btn-group">
              <button type="button" name="btnRefresh" class="btn btn-default">
                  <i class="fa fa-refresh"></i>
                  Обновить
              </button>
          </div>
      
          <div class="btn-group">
              <button type="button" name="btnCopy" class="btn btn-default">
                  <i class="fa fa-copy"></i>
                  Копировать
              </button>
              <button type="button" name="btnMerge" class="btn btn-default">
                  <i class="fa fa-code-fork fa-rotate-270 "></i>
                  Объединить
              </button>
          </div>
      </div>
                          
    • _projects.eco — таблица без содержимого
      _projects.eco
      <div class="row">
          <div class="col-xs-12 col-sm-11 col-md-10 col-lg-9">
              <table class="table table-hover table-condensed ">
                  <thead>
                  <tr>
                      <th>Название</th>
                      <th>Владелец</th>
                      <th>Доступ</th>
                      <th>Примечание</th>
                  </tr>
                  </thead>
                  <tbody>
                  </tbody>
              </table>
          </div>
      </div>
                          
    • _project.eco — строка таблицы
      _project.eco
      <td>
          <a href="#">
              <%= @name %>
          </a>
      </td>
      <td>
          <%= CashFlow.entities.users.get(@idUser).get('name') %>
      </td>
      <td>
          <% for idUser in @writers: %>
          <span class="tag">
          <%= CashFlow.entities.users.get(idUser).get('name') %>
          </span>
          <% end %>
      </td>
      <td>
          <%= @note %>
      </td>                    
                          
    • _empty.eco — сообщение, что нет данных
      _empty.eco
      <td colspan="4">
          <div class="well well-sm text-center">
              Нет данных
          </div>
      </td>
                          

Сборка проекта

На первом этапе разработки я использовал Ruby On Rails. Мне очень понравилась идея файлопровода (asset pipeline). Но использовать целый фреймворк только ради файлопровода — не лучшая идея. Поэтому, используя Gulp, написал свой велосипед свою реализацию файлопровода.

Итак, есть два режима сборки проекта: development и production. В production mode происходит сжатие стилей и скриптов. При этом к имени asset-файла добавляется хеш-сумма от содержимого файла (app.js > app-4f2474f8.js).

Еще одна особенность сборки заключается в том, что gulp-задачи генерируются автоматически на основе описания для каждой страницы проекта. Таким образом, что бы добавить сборку новой страницы, достаточно добавить описание что и как собирать.

Есть следующие задачи:
  • scripts:<page_name> — сборка app.js для страницы (проверка CoffeeLint, компиляция CoffeeScript, сжатие)
  • styles:<page_name> — сборка стилей app.css (импорт css-файлов, компиляция SASS, минификация)
  • html:<page_name> — генерация html-страницы (изменение версии сборки, добавление счетчиков, замена имени файлов для app.css и app.js)
  • fonts:<page_name> — копирование шрифтов
  • cp:<page_name> — копирование файлов
  • build:<page_name> — сборка указанной страницы
  • build — сборка проекта
  • watch — наблюдение за файлами и перезапуск соответствующей задачи при изменении файла

Примечание. Не все задачи являются обязательными для каждой страницы.

Пример описания задач для главной страницы
  {
    name: '',
    tasks: {
      scripts: {
        src: [
          'bower_components/jquery1x/dist/jquery.js',
          'bower_components/bootstrap-sass/assets/javascripts/bootstrap/transition.js',
          'bower_components/bootstrap-sass/assets/javascripts/bootstrap/collapse.js',
          'bower_components/social-likes/social-likes.min.js',
          'lib/assets/javascripts/**/*.+(coffee|js)',
          '_/app/assets/javascripts/**/*.+(coffee|js)'
        ],
        dest: 'public/assets'
      },
      styles: {
        src: ['_/app/assets/stylesheets/app.scss'],
        dest: 'public/assets'
      },
      html: {
        src: ['_/app/index.html'],
        dest: 'public'
      },
      fonts: {
        src: ['bower_components/font-awesome/fonts/fontawesome-webfont.*'],
        dest: 'public/assets'
      },
      cp: {
        src: ['_/cp/*'],
        dest: 'public'
      }
    },
    build: ['scripts:', 'styles:', ['html:', 'fonts:', 'cp:']]
  }
    

Примечание: также задается порядок и синхронность выполнения задач при сборки конкретной страницы.
Например, для главной страницы задано следующее правило: ['scripts:', 'styles:', ['html:', 'fonts:', 'cp:']]. Это значит, что сначала выполнится задача 'scripts:', потом 'styles:', а уже затем параллельно выполнятся задачи 'html:', 'fonts:' и 'cp:'

Файл gulpfile.js целиком на github.

Ссылки:

Комментарии (28)


  1. ptitca_zu
    10.05.2015 11:03
    +1

    Немного обратной связи по самому сервису. Я примерно год назад хотел сделать приложение для домашнего бюджета. Дальше прототипа на бумаге не ушло, но зато я поговорил с некоторым количеством потенциальных пользователей (50-70 человек).
    Так вот все в один голос назвали 2 проблемы ведения домашнего бюджета.

    1. Удобство ведения

    Подавляющее большинство забросило это дело, потому рос «снежный ком» неучтенных транзакций, потерянных чеков etc.
    Для всех оказалось важным либо максимальное удобное занесение расходов/доходов, либо — что на мой взгляд даже лучше — автоматизация этого дела: скан смс, фото чеков, регулярные транзакции и т.д

    2. Информативность

    Многие говорили, что не знают, что делать с этими цифрами. При этом, данных много, и на них вполне можно делать какие-то прогнозы и давать простейшие советы.

    Не знаю функционала Вашего сервиса — я просто посмотрел демо — но подумал, что эта информация могла бы помочь.


    1. hudson
      10.05.2015 12:08

      Удобство ведения — это наверное вопрос мотивации прежде всего. Я несколько раз начинал вести учет и только последние года три регулярно заношу все операции. Дорос или может быть очень сильно захотел.

      А вот мобильного приложения сейчас очень не хватает. Но анализа и прогнозирования не хватает еще больше, так как учет сам по себе это только половина решения домашних финансовых неурядиц…


      1. ptitca_zu
        10.05.2015 12:19

        Согласен, я тоже вполне себе несколько лет вел учет, дисциплинированно занося туда все расходы и доходы.
        Но перестал как раз потому, что мне эти цифры ничего не говорили. То есть этап, когда бюджет дисциплинирует тебя прошел и его ведение превратилось просто в привычку.
        Поэтому и хотел сделать для себя какой-то простой анализ, но один не осилил, а увлечь кого-то не удалось :)


        1. amiksam Автор
          10.05.2015 15:29

          Если цель — самоорганизовать себя и приучить контролировать свои расходы, то ведение домашней бухгалтерии в течение одного года будет вполне достаточно. Сейчас я не планирую месячные расходы, т.к. у меня они практически не изменяются (хотя в семье двое маленьких детей). Но если вы активно используете несколько счетов, работаете с долгами, то без программы учета будет очень сложно.


    1. amiksam Автор
      10.05.2015 15:18

      Спасибо большое. Обратная связь для меня сейчас самое ценное.

      Конечно, бывают «потерянные» деньги. В этом ничего страшного нет. Можно раз в неделю (месяц) сделать сверку реальных остатков в кошелке и в программе и разницу списать на категорию «Выравнивание баланса».

      Распознавание чеков — это очень сложная задача. Да и не уверен, что она сильно поможет в введении бухгалтерии. Сейчас на внесение чека в 10 строк я трачу не более минуты, а вот импорт банковских выписок обязательно будет.

      Прикрепить фото чеков (как и любые картинки) можно будет позже.


  1. TDz
    10.05.2015 13:42
    +1

    А как вы развивали идею? Вот от мысли «замутить бы что-то» через идентификацию проблем, анализ рынка, составление требований «пользовтелям нужна такая-то форма, потому что...» итд итп


    1. amiksam Автор
      10.05.2015 16:02

      Я веду домашнюю бухгалтерию с 2003 года. Фактически это первая моя программа, купленная официально. Но мне реально не хватало некоторых функций, особенно планирования и группировки затрат в группу (чек). И для планирования приходилось использовал Excel. Было несколько попыток реализовать идею, но все время что-то мешало… Периодически смотрел, что есть на рынке, но все было не то.

      Год назад твердо решил, что сделаю и практически полностью погрузился в этот проект. Основные user-story писал с себя. Мой пользователь был человек, который уже ввел домашнюю бухгалтерию и которому не хватало того, что предлагали другие сервисы.

      В данный момент доступен не весь функционал, который задумывался. Это всего лишь MVP. По большому счету, я делаю ставку на комьюнити вокруг этого проекта:

      • не хватает какого-то отчета: опиши его. Если не я, то кто-нибудь другой заинтересованный реализует его.
      • не нравится сайт или мобильное приложение — возьми за основу готовое и доработай под себя. Выложи для других пользователей и даже заработай на этом


      Но уже сейчас вижу, что придется менять профиль моего пользователя, т.к.:
      • большинство зарегистрированных пользователей — девушки
      • импортов из других бухгалтерий единицы


      1. ptitca_zu
        10.05.2015 21:48

        Интересный профиль пользователя получился. Еще интересней будет посмотреть на его жизненный цикл.
        Подумайте все же в сторону анализа данных — тут может быть бомба :) Единственные, кто пытается это сейчас делать — EasyFinance. Но у них как-то убого получается.

        Кстати, если о монетизации думали (думали, кстати?), то тут тоже интересные модели вырисовываются.


      1. Hungry_Hunter
        11.05.2015 00:31

        Есть замечательный сервис Дребеденьги называется. Можете позаимствовать у них много идей.
        Я в него просто влюбился в свое время, очень удобно пользоваться.


        1. amiksam Автор
          11.05.2015 10:31

          конечно я знаю лидера рынка :) Надеюсь, что FINEX тоже будет вызывать такие чувства :)
          Но по правде, я не вижу, что можно вот так взять и скопировать.


  1. dj_raphael
    10.05.2015 14:08
    +2

    Пробовал пользоваться домашними бухгалтериями, надоедает быстро всё это писать вручную. Надо сделать распознование чеков с веб-камеры или с телефона. С раскладываем покупок по категориям и по целям(Членам семьи). У вас этого нет, но мне помогло выявить неожиданные перерасходы за телефон из-за поднятия цены. Порывался сам написать такую систему, но отказался от идеи из-за сложности реализации и неплатежеспособности целевой аудитории. Сам пока веду в экселе. Могу поделится пустым документом если интересно.


    1. ptitca_zu
      10.05.2015 14:22

      Поделитесь, интересно.


    1. amiksam Автор
      11.05.2015 10:37

      Надо сделать распознование чеков с веб-камеры или с телефона. С раскладываем покупок по категориям и по целям(Членам семьи). У вас этого нет...

      Я не встречал ни одного сервиса с возможностью распознаванием чеков с камеры. Это уже из области ИИ. Когда это будет возможно, не думаю, что у людей будет необходимость вести домашнюю бухгалтерию :)

      Если есть какой-то интересный анализ в экселе, то конечно хотелось бы посмотреть.


      1. dj_raphael
        11.05.2015 12:07

        вот файл
        На графиках слева по месяцам справа по кварталам, сверху расходы по категориям, снизу разница расходов доходов.

        Такие внутри графики


        1. amiksam Автор
          11.05.2015 12:34

          Если честно, то без данных очень сложно оценить ваш подход. Оставили хотя бы несколько десятков записей (суммы можно было бы и изменить). Это сильно отличается от сводной таблицы в FINEX (Отчеты -> Динамика — вид «Таблица»)? Там тоже динамика по месяцам и по категориям. Так же график может показывать динамику по месяцам и по категориям.

          рисунки




          1. dj_raphael
            11.05.2015 14:57

            Ну да, функционалом не сравниться, но там то, что нужно было именно мне, чтобы оптимизировать расходы. сейчас вспоминаю зачем я это вел, целей было несколько, Основная: накопить на первый взнос ипотеки и далее по убывающей, отпуска и бытовая техника.
            Просто вывод был из этого когда я сам задумался сделать бухгалтерию — готов ли я был за ней платить когда она мне нежна была?
            Нет — Денег не хватает, да и сам программист напишу как нибудь.
            Дребеденьги — основное с чем сравнивал — неудобно заполнять по сравнению с экселем. У вас кстати тоже, постоянное переключение между мышкой и клавиатурой — большой минус.

            А насчёт распознования, когда я обсуждал это с коллегой, который уже занимался распознованием с документов, распознать геометрию и выровнять документ проблем не составляет, написать сценарий шаблон для одного типа чеков(для одного магазина) — тоже. но написать универсальный конструктор шаблонов для чеков — очень сложно.


            1. amiksam Автор
              11.05.2015 15:08

              У вас кстати тоже, постоянное переключение между мышкой и клавиатурой — большой минус.

              при потоковом вводе операций мышка не нужна. Как только вызвали форму создания операции, то вторую и последующие операции можно вводить только с клавиатуры: выбрали категорию (введя несколько символом), «Таб», указали сумму, «Ввод» и так далее повторить нужное количество раз.


  1. jarosluv
    10.05.2015 21:28
    +1

    Сам некоторое время назад жил с мыслью сделать простенькое веб-приложение для занесения расходов/доходов и планирования бюджета. Главная мысль, к которой пришёл — необходимо, чтобы приложение на основе собранных данных давало советы, где можно сэкономить, как отложить побольше денег на свои финансовые цели.

    Эталоном приложений для учёта и самоорганизации для меня является приложение Lifesum. Я считаю, что успешное приложение для ведения личного бюжета должно двигаться как раз в эту сторону, но с большим уклоном к анализу данных, чтобы давать релевантные индивидуальные советы.

    А по поводу сканирования чеков — кто-то в прошлом году во время выступления, на котором я присутствовал, рассказывал о неуспешности приложения, основанного на сканировании чеков. Людям просто было лень/неудобно каждый раз сохранять чеки и сканировать их, хотя казалось бы…


  1. Vinchi
    11.05.2015 08:30

    Импорт вы делаете, но что насчет экспорта информации? Есть ли это в API, будет ли реализовано? Я к чему — вот накопится много информации, а проект закроется и данные никак не вытащить. Или просто сервис упал, или интернета под рукой нет, но если есть возможность выгрузки в архив — то можно в него залезть и посмотреть.


    1. amiksam Автор
      11.05.2015 10:17

      Импорт данных обязательно будет. Все введенные данные — это данные пользователя. В любой момент он может их забрать.
      Просто еще не дошла очередь до реализации этой задачи: нужно еще разработать простой и понятный формат выгрузки данных.
      На днях выложу в публик «дорожную карту» развития сервиса.

      Работа с офф-лайн базой будет реализовано в мобильной версии. Основная функция которой — оперативный ввод данных без необходимости подключения к сервису с последующей синхронизацией.


  1. Vinchi
    11.05.2015 08:41

    И еще вопрос. У вас написано:
    Предложение действительно для пользователей, зарегистрированных до выпуска версии 1.0 при условии использования данного сервиса не менее 5 раз в месяц

    5 раз использования — это что конкретно значит? Залогинился, сделал запись где угодно, создал отчет?


    1. amiksam Автор
      11.05.2015 10:24

      5 раз использования = 5 входов. Сначала хотел как-то оценивать активность, но сейчас решил, что буду смотреть только на факт входа.
      Более того уже поменялась сама концепция монетизации: будет бесплатная версия и платная.


  1. saaivs
    11.05.2015 13:50
    +1

    Еще одну вещь которую очень бы хотелось бы видеть в приложениях подобного класса — Планирование.
    Я, как и многие, давно пользуюсь подобными money-трекерами и цель в их существовании вижу только одну — знание о том сколько и на что я тратил дает мне возможность скорректировать будущие траты.

    В связи с этим очень не хватает удобного инструмента для планирования с хорошей детализацией(не встречал еще удобных реализаций). Условный Excel, конечно, в простых случаях помогает, но когда нужно контролировать множество различных центров затрат (небольшой бизнес, инвестирование, семейный бюджет, кредиты, долги и т.п.) очень важным становится вопрос: а каковы будут остатки на счетах в произвольную дату при заданной структуре доходов и расходов.

    ВХОД:
    1) Условные центры затрат сгруппированные по категориям, т.е. счета в различных валютах (кредитный или дебетовый счет).
    2.1) Доходы, сгруппированные по категория, т.е. пополнения счетов.
    2.2) Расходы, сгруппированные по категориям, т.е. списания со счетов.
    2.3) Переводы, сгруппированные по категориям, т.е. переводы средств со счета на счет. (в случае мультивалютных переводов было бы удобно прогнозировать и курсы валют)

    Время событий (доходов, расходов, переводов) задавать в гибком формате (каждый месяц в определенное число, раз в год, раз в неделю по понедельникам и т.п.) с указанием срока действия правила.

    ВЫХОД:
    Вносим текущие остатки по счетам, выбираем период планирования, и на основе входных данных, на каждый день на заданный период видим остатки по счетам. т.е. если собираетесь взять кредит, накопить некоторую сумму к некоторой дате, или просто понять какое будет ваше финансовое состояние через 5 или 10 лет, если все будет так как вы планируете — вы сразу получаете простой ответ.

    За такой инструмент я бы с удовольствием заплатил. Если кто знает, буду признателен за ссылку.

    А money-трекеры здесь были бы очень полезны, чтобы максимально достоверно сформировать персональную структуру правил движения средств и на ее основе уже автоматически строить прогноз. Вот вам и конкурентное преимущество:)

    С т.з. программирования построение прогноза на основе правил задача весьма простая(я делал для себя прототип на java и результат был очень полезный в свое время). Гораздо сложнее сделать этот процесс эргономичным и простым для массового потребителя, но, думаю, оно того стоит, т.к. базовая идея должна быть простой и понятной: ЧТО Я БУДУ ИМЕТЬ ЗАВТРА С ТЕМ, ЧТО У МЕНЯ ЕСТЬ СЕГОДНЯ.


    1. amiksam Автор
      11.05.2015 14:32

      интересный запрос. Фактически уже сейчас, нечто похожее можно делать, используя «неподтвержденные операции». И остатки можно посмотреть на любую дату, и на графике увидеть прогноз. Единственно, что все эти операции нужно завести, т.е. нет правил.
      Лично я так и делаю, только не делю затраты на подкатегории и с какой-то долей вероятности могу сказать, что будет с деньгами через некоторое время.
      В любом случае я зафиксирую эту идею на форуме и обязательно к ней вернусь. Спасибо!


  1. kellas
    12.05.2015 15:29

    Сколько у меня будет денег в октябре если всё будет идти так как сейчас? Ой в августе кассовый разрыв, компенсируем с резервного вклада в и теряем %… тогда в банк не будем пару месяцев откладывать 10% дохода, а отложим в конвертик чтобы закрыть дыру, или выгодней тупо занять у Аньки и процент покроет на треть будующий долг?

    Планирование и бюджетирование это то ради чего имеет смысл вести учёт. Перебрал кучу сервисов, все концентрируются на трекинге расходов, как будто в налоговую эти отчёты нести нужно…


    1. amiksam Автор
      12.05.2015 15:46

      Трекинг расходов — это первичная задача учета. Цель — понять, на что тратятся деньги и где можно экономить.
      То, что вы описали — это конечно круто, особенно по выбору способа покрытия кассового разрыва. Реализовать такой выбор в программе не обещаю :), но вот узнать «Сколько у меня будет денег в октябре» и увидеть кассовые разрывы можно будет. Сейчас как раз над этим работаю.


      1. kellas
        12.05.2015 16:25

        Всё таки первично «нужно ли экономить», ну т.е. что мне будет за то что я не куплю себе сейчас «квадракоптер»? Или какая злая кара настигнет меня в будующем благодая этой покупке?
        Что касается трекинга, кто вообще придумал записывать необратимые расходы? Гораздо эффективнее вносить расход ДО покупки. Мы же сначала смотрим сколько у нас денег в кошельке и потом платим, вот и расход нужно сначала вписать в план(внести в программу) и потом уже реально платить если это окажется возможным. Поэтому сканирование чеков, смсок, функция сомнительная. Вот реально тупо содрали с налоговой отчётности. А как почти все работают? — Пишут красивый такой план(ТЗ) и потом всеми силами его придерживаются, так хорошо всё равно не получается, но получается лучше чем без плана, просто отчитываясь о сделанной непонятно зачем работе.

        Тем не менее я не критикую ваш сервис, просто это принципиально разные подходы, возможно ещё от людей зависит, может кому-то и достаточно логгировать расходы и потом анализировать.


        1. amiksam Автор
          12.05.2015 16:57

          Что бы планировать, нужно иметь хотя бы элементарную финансовую грамотность. К сожалению, с этим у людей большие проблемы. Сегодня ресторан, а завтра занимаем деньги до следующей зарплаты. И не дай бог, если кто-то серьезно заболеет.