Предисловие

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

Дисклеймер: автор статьи имеет посредственные скиллы разработки, так что некоторые технические решения могут оскорбить чувства middle и senior developer-ов. 

К пониманию необходимости учета финансов я пришел в 2016 году, когда съехался со своей будущей женой. Цели учета были вполне банальные: понимать кто и сколько расходует на какие товары, выявить возможности для оптимизации расходов, а так же убедиться, что соотношение семейных расходов соразмерно соотношению размеров зарплат членов семьи. (Спойлер: разумеется, сэкономить в итоге ни на чем не получилось)

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

Я считаю такой подход более разумным. Разумеется, мы не делим расходы абсолютно в каждом чеке из продуктового. В основном, дележке подвергаются крупные чеки из гипермаркетов на тысячи рублей. Также мы совместо финансируем коммунальные платежи, аренду и другие крупные жилищно-инфраструктурные проекты.

Версия 0

Как правило, первые попытки ведения семейного бюджета люди начинают в Excel или иных аналогах, типа Google Sheets. И мы не стали исключением.

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

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

Версия 1

Но поиск быстро зашел в тупик. Бесплатные варианты не умели делить один чек между несколькими пользователями. Да даже многопользовательский режим был далеко не везде. Платные же программы помимо факта своей платности зачастую предлагали поделиться данными о своих расходах с разработчиками. Ни платить ни делиться данными мне не хотелось.

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

Так как на заочном отделении в моем ВУЗе меня обучили только шлепать формы на C#, выбор стека для собственного приложения был очевиден. В качестве СУБД был выбран MSSQL Express, который хостился на домашнем сервере. Примерно за месяц был написан MVP, после чего с 1 сентября 2016 года процесс учета расходов был перенесен в свеженаписанную программу.

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

Основная сущность в программе - чек, который содержит позиции. У чека есть дата и место совершения покупки.

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

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

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

Вокруг основного функционала и данных я начал реализовывать разные полезные фичи, такие как например:

  • Отчетность. Были реализованы различные отчеты, как например статистика трат по категориям товаров или статистика трат в разрезе магазинов.

  • Отслеживание текущего баланса. Всегда хотел видеть количество денег, как у игрового персонажа :)

  • Шаблоны чеков. Ввод однотипных расходов, как например такси, кофе, проезд в метро, был значительно упрощен таким путем. При выборе шаблона автоматически подставлялись все данные из соответствующего старого чека. Оставалось только поменять сумму и сохранить новый чек.

В какой-то момент появилось и устоявшееся название, которое сохранилось и по сей день – Домашняя бухгалтерия.

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

Главное окно программы
Главное окно программы
Форма добавления чеков
Форма добавления чеков
Отчет по структуре расходов
Отчет по структуре расходов

После этого дальнейшее развитие программы сильно замедлилось. 2019-2020 годы прошли без каких-либо значимых изменений. Лишь изредка приходилось править баги. Все новые идеи откладывались в долгий ящик, мотивации кодить не было, и скоро поясню почему.

Небольшое лирическое отступление

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

Виделось два очевидных вектора автоматизации учета:

  • парсинг SMS уведомлений о списаниях с банковской карты

  • получение содержимого чека по QR-коду.

Но такие глобальные доработки упирались в один очень неприятный факт:

Программирование в гуманитарном ВУЗе, да еще и на заочном отделении преподают весьма посредственно. Поэтому весь код представлял из себя мешанину из if/else, непонятных переменных и sql-запросов, объединенных с переменными. ООП? MVC? MVVM? Паттерны проектирования? Да хотя бы банально писать комментарии? Не, не слышали. После многократных переделок код стал похож на эдакого Франкенштейна. Надо ли говорить, что ориентироваться в нем было крайне сложно?

И вот под конец бесполезно потраченных новогодних выходных 2021 года я снова взялся за Visual Studio.

Версия 2 - текущая

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

Опыта в мобильной разработке у меня было ровно ноль. Тратить месяцы на изучение Java или Kotlin не хотелось. И поэтому, я опять же пошел по легкому пути – Xamarin. В интернете нашел учебный шаблон приложения с вкладками и принялся его погонять под свои нужды, в процессе активно используя Google и Stackoverflow. Как только стало понятно, что мои планы на мобильное приложение реализуемы, параллельно начал разработку серверной части. Тут опять же был выбран C# и .Net Core. Мы же в 2021 живем как-никак, нужно уметь в кроссплатформенность.

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

Мобильное приложение - CostsExporter

Мобильное приложение-компаньон умеет делать три вещи:

  • сканировать и отправлять на сервер QR-код с чека.

  • проверять inbox на предмет новых SMS от банка и так же отправлять их на сервер.

  • отправлять на сервер введенный расход в виде сумма:описание.

Для сканирования QR-кодов с чека я использую библиотеку ZXing.Net.Mobile. Примерно в 90% случаев QR-код удается отсканировать. Но если QR-код нечеткий или чек непропечатался/истерся, то тут все печально. Встроенное приложение камеры, как и официально приложение ФНС России, вполне справляются даже в таких случаях. Специально для этого пришлось добавить вариант с ручным ввводом содержимого QR-кода. Если кто может посоветовать вариант лучше, я был бы очень благодарен.

Для чтения SMS в памяти телефона постоянно висит Foreground Service, который дергает метод проверки входящих SMS каждые 3 минуты. После продолжительного штудирования интернетов я сделал вывод, что только таким путем можно обеспечить приемлемую работоспособность этого процесса, ибо своевольный Android может выгружать любые активности, когда ему вздумается.

Все SMS/QR-коды/ручные записи перед отправкой складываются в локальную базу SQLite, где так же хранится дата создания и статус отправки на сервер. При повторном сканировании SMS/QR-кода дубли будут отброшены.

Все сообщения отправляются в json-формате. JSON выглядит примерно так:

{
  "TypeId": "2",
  "Payload": "02.03.2021 9:54:33;Raiffeisen;Karta *****. Pokupka 137.00 RUB. CITYMOBIL.. Balans 4842.16 RUB. 02.03.2021"0Э
  "User": "Pavel",
  "Secret": "SomeSecret"
}

Далее немного скринов приложения:

Серверная часть - CostsReceiver

CostsReceiver представляет из себя Web-сервер на Asp.Net Core запущеный в Docker-контейнере на домашнем сервере. Наружу он опубликован через KeenDNS (сервис для владельцев роутеров Keenetic), который позаботился и о доменном имени и SSL сертификате.

CostsReceiver парсит прилетающие к нему json-ы и складывает результат в таблицу пакетов для обработки.

Каждые 3 минуты в отдельном потоке запускается воркер, который пытается обработать все необработанные входящие пакеты. Параметр TypeID подсказывает серверу, как обрабатывать полученный пакет. Если TypeID равен единице, то это QR-код, если 2 – это SMS, если 3 – то это расход, введенный вручную.

С SMS все просто – текст прогоняется через регулярное выражение. Из него вычленяются название торговой точки, время и сумма покупки. Непрошедшие регулярку сообщения удаляются.

С QR-кодом все интереснее. После непродолжительного поиска я нашел статью Николая Валиотти о реализации парсера чеков на Python. Переписать код на C# было несложно.

Сперва происходит аутентификация и запрос токена. Затем с этим токеном и содержимым QR кода воркер постоянно стучится на сервер ФНС, пока сервер не выдаст ему в ответ содержимое чека в json формате. Как быстро чек появляется на сервере ФНС, судя по всему, зависит от типа кассы. Это может занять от пары минут до пары дней. Из полученного json-а также выдергивается название торговой точки, время покупки и все позиции чека.

Возможно, кому-то этот код будет полезен
public class CheckRequesterByQR
    {

        private Envelope _envelope = new Envelope();
        public CheckRequesterByQR(Envelope envelope)
        {
            _envelope = envelope;

        }


        public async Task<string> GetCheckByQR()
        {
            string sessionId;
            if (Variables.sessionID == null)
            {
                JObject responseSessId = JObject.Parse(await GetSessionID());
                sessionId = (string)responseSessId["sessionId"];
                Variables.sessionID = sessionId;
            }
            else sessionId = Variables.sessionID;

            try
            {
                JObject responseTicketId = JObject.Parse(await GetTicketID(sessionId, _envelope.Payload));
                var ticketId = (string)responseTicketId["id"];
                if (ticketId != null)
                {
                    JObject responseCheck = JObject.Parse(await GetCheck(sessionId, ticketId));
                    var check = responseCheck.ToString();
                    return check;
                }
                else return null;
            }
            catch (Exception ex)
            {
                if (ex.Message == "HTTP ERROR: Unauthorized" && Variables.sessionID != null)
                {
                    Variables.sessionID = null;
                    throw new Exception("HTTP ERROR: Unauthorized. Will try to renew session token next time.");
                }
                else
                {
                    throw ex;
                }
                
            }        
           
        }

        private HttpClient GetClient()
        {
            HttpClient client = new HttpClient();
            client.DefaultRequestHeaders.Add("Accept", "application/json");
            client.DefaultRequestHeaders.Add("Host", "irkkt-mobile.nalog.ru:8888");
            client.DefaultRequestHeaders.Add("Accept", "*/*");
            client.DefaultRequestHeaders.Add("Device-OS", "iOS");
            client.DefaultRequestHeaders.Add("Device-Id", "7C82010F-16CC-446B-8F66-FC4080C66521");
            client.DefaultRequestHeaders.Add("clientVersion", "2.9.0");
            client.DefaultRequestHeaders.Add("Accept-Language", "ru-RU;q=1, en-US;q=0.9");
            client.DefaultRequestHeaders.Add("User-Agent", "billchecker/2.9.0 (iPhone; iOS 13.6; Scale/2.00)");
            client.Timeout = TimeSpan.FromSeconds(7);
            return client;
        }

        private async Task<string> GetSessionID()
        {
            HttpClient client = GetClient();

            var env_inn = Environment.GetEnvironmentVariable("INN");
            var env_pass = Environment.GetEnvironmentVariable("PASSWD");

            var payload = new
            {
                inn = env_inn,
                client_secret = "IyvrAbKt9h/8p6a7QPh8gpkXYQ4=",
                password = env_pass
            };

            try
            {
                var response = await client.PostAsync("https://irkkt-mobile.nalog.ru:8888/v2/mobile/users/lkfl/auth",
                new StringContent(
                    JsonConvert.SerializeObject(payload),
                    Encoding.UTF8, "application/json"));

                if (response.IsSuccessStatusCode)
                {
                    return await response.Content.ReadAsStringAsync();
                }
                else
                {
                    throw new Exception("HTTP ERROR: " + response.StatusCode);
                }

            }
            catch (Exception ex) when (ex is TaskCanceledException || ex is OperationCanceledException)
            {
                return null;
            }
        }

        private async Task<string> GetTicketID(string sessionId, string qrcode)
        {
            HttpClient client = GetClient();
            client.DefaultRequestHeaders.Add("sessionId", sessionId);

            var payload = new
            {
                qr = qrcode
            };

            try
            {
                var response = await client.PostAsync("https://irkkt-mobile.nalog.ru:8888/v2/ticket",
                new StringContent(
                    JsonConvert.SerializeObject(payload),
                    Encoding.UTF8, "application/json"));

                if (response.IsSuccessStatusCode)
                {
                    return await response.Content.ReadAsStringAsync();
                }
                else
                {
                    throw new Exception("HTTP ERROR: " + response.StatusCode);
                }

            }
            catch (Exception ex) when (ex is TaskCanceledException || ex is OperationCanceledException)
            {
                return null;
            }

        }

        private async Task<string> GetCheck(string sessionId, string ticket)
        {
            HttpClient client = GetClient();
            client.DefaultRequestHeaders.Add("sessionId", sessionId);

            try
            {
                var response = await client.GetAsync("https://irkkt-mobile.nalog.ru:8888/v2/tickets/" + ticket);

                if (response.IsSuccessStatusCode)
                {
                    return await response.Content.ReadAsStringAsync();
                }
                else
                {
                    throw new Exception("HTTP ERROR: " + response.StatusCode);
                }

            }
            catch (Exception ex) when (ex is TaskCanceledException || ex is OperationCanceledException)
            {
                return null;
            }
        }

    }

Результатом работы CostsReceiver являются черновики чеков. Они уже содержат в себе дату чека, место покупки, сумму и, если это был QR-код, то и позиции в чеке. К ним можно получить доступ из основного приложения. Черновик чека - это еще не полноценный чек. Для каждой позиции в черновике нужно указать категорию. Если не удалось определить магазин, его также нужно указать вручную. Но это все равно гораздо быстрее, чем вводить данные с нуля.

Нормализация данных

Попутно пришлось решить пару проблем по данной части.

Во-первых - это преобразование названий многочисленных ООО-шек в уже предопределенные названия магазинов. При обработке пакета воркер производит замену названия типа ОБЩЕСТВО С ОГРАНИЧЕННОЙ ОТВЕТСТВЕННОСТЬЮ "АЛЬФА ПЕНЗА" на хорошо известное название "Красное и Белое".

Аналогичным путем решается вопрос нормализации названий позиций в чеке. Думаю, каждый не раз задавался вопросом, что такое, например, *KON.Печ-сэн.СУП.КОН.mars.сл288г или *Р.ФР.Бат.КР.тв/как/вз.кар.180г. Когда я расшифровываю эту позицию в чеке, она записывается в базу, и в следующий раз CostsReceiver автоматом заменит белиберду на понятное название и подставит категорию товара.

Так же CostsReceiver автоматически пытается подобрать соответствующий шаблон для черновика чека на основании заранее предопределенных правил. Если таковой находится, то добавить чек можно нажатием одной кнопки. Правила для шаблона нужно задать самому.

Три из пяти расходов можно одобрить нажанием одной кнопки
Три из пяти расходов можно одобрить нажанием одной кнопки

Домашняя бухгалтерия v2

Но все это было бы невозможно без переписывания десктопной версии "Домашней бухгалтерии". К марту руки дошли и до нее.

В этот раз было решено отказаться от безнадежно устаревшего WinForms и выбрать что-то посовременнее. Выбор пал на WPF. Было очень непривычно формошлепить в xaml, но после пары форм дело пошло быстрее. Еще через месяц активного кодинга большая часть старого кода была переписан с нуля с сохранением логики.

К написанию второй версии я подошел уже с некоторым багажом знаний и опыта в программировании. Теперь в нем стало немного больше ООП. Появились классы, отражающие сущности из БД, методы доступа к данным были отделены от логики форм. Попутно была реализована интеграция с CostsReceiver и разнообразные мелкие улучшения.

Снова скриншотики:

Новое главное окно программы
Новое главное окно программы
Ввод нового чека
Ввод нового чека
Красивый график текущего баланса
Красивый график текущего баланса
И визуализация распределения расходов по категориям
И визуализация распределения расходов по категориям

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

Из глобальных доработок в планах осталось:

  • добавление мультивалютности

  • упрощение заполнение чеков в туристических поездках, чтобы не пересчитывать вручную цену каждой позиции на курс

  • возможно, прикрутить хранение сканов гарантиек и чеков на разную технику

  • допилить учет кредитов/ипотек. Тут пока нет четкого понимания ввиду сложности рассчетов ежемесячных платежей и остатка долга

  • в перспективе добавить учет ИИС и активов в валюте (когда они появятся)

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

Выводы

Сложно однозначно ответить на вопрос, как именно нам помогло как-то детальное знание структуры семейных и личных расходов. В экономическом плане скорее всего никак. Больше экономить на основании полученных данных мы конечно же не стали.

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

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


  1. anonymous
    00.00.0000 00:00


    1. pawellrus Автор
      07.10.2021 08:40

      Была попытка сравнить существующие решения?

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

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

      А времени требует много.

      Отсюда и желание ускорить процесс.


      1. zlt
        08.10.2021 16:22
        +2

        zenmoney.ru? Сканирование чеков, автозамена названий магазинов, категории, статистика, бюджет, плановые операции, напоминание в телеграмм.

        Единственная особенность — это облачный сервис. Видимо это был серьёзный блокер.


    1. Srgun
      07.10.2021 12:45
      +1

      Ну и про вечное — надо зарабатывать столько чтобы не считать расходы

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

      Контроль же, грубо, может быть относительный и неявный (типа нафига я буду тратить деньги на эту ненужную ерунду), абсолютный и неявный (так, на карточке денег почти не осталось, купить что-то ещё в этом месяце уже не получится), и абсолютный и явный (обычно я трачу в месяц X денег на то-то и то-то, зарабатываю 2*X, соот-но могу потратить ещё примерно X на то, что хочется/надо сверх обычного). Для ценителей 3 подхода и нужен учёт.

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


  1. Fortisa
    07.10.2021 00:46
    +4

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


    1. pawellrus Автор
      07.10.2021 08:34
      +2

      Распространенное мнение, но тем не менее способа лучше мы не придумали.


    1. DDroll
      07.10.2021 10:10
      +9

      Это не по девчачьи, это по-детски. Рано или поздно вы задумаетесь, почему, зарабатывая так много, вы можете себе позволить так мало. А так же, когда начнет маячить конец молодости, зададите себе вопрос, хотите ли вы зависеть от государства (особенно, постсоветского) в старости. И придете к табличкам)


      1. Fortisa
        07.10.2021 12:43

        Я зарабатываю для своего региона like a boss (и не для своего тоже), у меня трёшка в центре (купила сама за нал в 2019), у папы машина (я купила), сама помешана на обучении, книгах и дорогой косметике, дома свои тренажёры, родителей обеспечиваю с ног до головы, немного балуюсь на бирже (да, именно балуюсь, каюсь, но моя профессия по диплому как раз связана с ценными бумагами и брокерской деятельностью — мне тупо интересно). Да, транжирю много лишнего. Но я ни перед кем никогда не буду ни за это отчитываться. И знаете, до этого поста я немного переживала, что одна (мне 37), а сейчас что-то так спокойно стало, что такие вот мимо проходят.


        1. codecity
          07.10.2021 13:07

          Я зарабатываю для своего региона like a boss (и не для своего тоже), у меня трёшка в центре (купила сама за нал в 2019), у папы машина (я купила), сама помешана на обучении, книгах и дорогой косметике, дома свои тренажёры, родителей обеспечиваю с ног до головы, немного балуюсь на бирже (да, именно балуюсь, каюсь, но моя профессия по диплому как раз связана с ценными бумагами и брокерской деятельностью — мне тупо интересно).

          Понимаете ли каких потенциальных мужей вы завлекаете сейчас как пчел на мед? Которые с превеликой радостью ничего считать и/или вести отчетов не будут — а просто тупо сядут вам на шею и будут жить за ваш счет, постоянно находя отмазки почему нет работы и подкупая подарочками/фишками на ваши деньги.


          1. urvanov
            07.10.2021 14:20
            +1

            Может, такие и нужны :)


          1. Fortisa
            08.10.2021 00:27
            +1

            Ути-пути. Нет, в 36 женщины уже знают себе цену и стоимость мужчин. Впрочем, это уже глубокий оффтоп. И да, что-то в личку писем не поступало — взрослые ж люди, ну.


            1. codecity
              08.10.2021 03:39

              в 36 женщины уже знают себе цену и стоимость мужчин

              Возраст при нулевом опыте ничего не даст.

              Из жизни история, ничего не придумываю. Женщина, состоявшийся юрист, всем обеспечена — впервые вышла замуж ближе к 50 за психа, которого потом ненавидела и реально боялась (и не без оснований). От него у нее дочь. Но это же не технарь а юрист, постоянно с людьми работает — как могла позволить себя одурачить — совершенно не ясно.

              И да, что-то в личку писем не поступало — взрослые ж люди, ну.

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


        1. Levitskyi
          07.10.2021 15:14
          +1

          У каждого своя история успеха. Павел поделился своей.

          С радостью почитал бы и о вашей.


    1. Kanut
      07.10.2021 11:14

      Ну у нас всё равно кучу вещей имеет смысл документировать для налоговой. Чтобы потом возвраты делать. Плюс часто чеки надо хранить для всяких гарантий/возвратов.


      И если всё равно таким уже занимаешься, то нет особых пробел документировать всё. Особенно учитывая что сейчас уже и дигитальные чеки есть и просто приложения для скана/распознавания чеков.


      И как бонус замечаешь когда какие-то расходы начинают ползти вверх или даже если какие-то вещи дорожают.


    1. codecity
      07.10.2021 11:16

      но как же страшно встретить человека, который будет вести домашнюю бухгалтерию

      У них, похоже, раздельный бюджет. Вернее частично раздельный.

      С одной стороны жлобство. С другой стороны именно это диктуют законы государства, а других рычагов у нас нет. По законам — два человека равноправные и свободные личности — каждый имеет право в любой момент прекратить союз в одностороннем порядке. Причем не важно есть дети или нет. То есть когда все выстраивается с учетом возможного прекращения — то такой союз как раз дольше продержится. Многим женщинам это не понравится, т.к. выгоднее создать иллюзию что все это навсегда, чтобы мужик вкладывался больше — а потом выиграть за счет развода.


      1. Fortisa
        07.10.2021 12:46

        Вот неслучайно я выбрала не начинать отношения, чем потом жить в этом всём…


  1. codecity
    07.10.2021 04:45
    +3

    Для меня было открытие — разделить расходы на значимые и необходимые. Значимые можно внести, их можно контролировать. Необходимые — вносить смысла нет, т.к. сократить их тоже не возможно — просто выделять под них фикс. сумму на неделю. Еда, гигиена, моющие — это необходимые, которые ужать не получится. Смысл дробить на яблоки/печенья? Покупка нового телефона — это уже можно внести.


  1. opckSheff
    07.10.2021 06:49
    +7

    Кто-то из нас двоих в оплачивал в магазине большой чек. Далее содержимое чека вносилось в экселевский файлик, а затем суммировались ячейки с товарами, купленными на семейные нужды. Так мы понимали, кто кому сколько должен перевести денег.

    Я, конечно, прекрасно понимаю, что мы тут собрались не для того, чтобы обсуждать чужую семейную жизнь... Но имхо ЭТО с таким подходом к совместной жизни и финансам сложно назвать семьёй. Какое-то юрлицо, товарищество на вере.

    А в остальном статья интересная, спасибо.


    1. melt
      07.10.2021 08:51

      Ну ладно вам, автор же пишет, что с «будущей женой». А с девушками не такой и тяжкий грех. Кто знает, может они договорились снимать квартиру получше, но делить расходы пополам? Не нам судить :)

      И статья про код и хобби вообще-то. Идея отличная! Даже вин формс выглядит симпатично :) Не понимаю, почему не перейти полностью в разработку при наличии успехов и выполненных проектов? Планируете ли подключать туда как пользователей друзей/соседей/родственников? Open source? Какие дальше планы вообще? Только для себя или какое-то развитие продукта? В любом случае, автор - молодец и успехов!


      1. pawellrus Автор
        07.10.2021 10:26

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

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

        По поводу Open source не уверен, стоит ли начинать. Мне думается, что это потребует гораздо больше времени на поддержку и устранение багов, чем я готов тратить. А так, планирую и дальше вести разработку по настроению.


    1. codecity
      07.10.2021 12:34

      с таким подходом к совместной жизни и финансам сложно назвать семьёй

      Государство хочет именно такие семьи. Патриархат, когда мужик брал на себя всю ответственность и обеспечивал семью всем — канул в Лету.


      1. tommyangelo27
        07.10.2021 14:59

        Но ведь может быть не только модель патриархата. Например, деньги скидываются в общую кучу, откуда каждый берет по мере надобности, расходы свыше Х обсуждаются.


        1. codecity
          07.10.2021 15:39

          Тут не понятно. Если куча это 10х, взять можно <x только 1 раз? Или можно взять 10 раз по 0.9x?


          1. tommyangelo27
            07.10.2021 16:30

            Ну это уже у кого как.

            Я могу рассказать про собственный опыт, и надеюсь, что это просто вопрос-подколка, а не непонимание всерьез.

            У нас в семье никаких строгих правил нет. Просто и я, и жена, и ребенок когда надо потратиться на что-то достаточно крупное задаёмся вопросом (и обсуждаем друг с другом) — есть ли сейчас такая возможность? Также принимается во внимание сумма, уже потраченная в данном месяце + остатки на счетах.


  1. Armitage1986
    07.10.2021 09:25
    +3

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


  1. mkvmaks
    07.10.2021 12:35
    +1

    Пытался так вести бухгалетрию - хватило не на долго (((. Вот как у людей получается простой и красивый дизайн??? Сколько не пытаюсь - все равно дизайн у меня г***о.


    1. pawellrus Автор
      07.10.2021 12:47

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


  1. x2v0
    07.10.2021 13:19

    github?


    1. pawellrus Автор
      07.10.2021 14:23

      Увы, но только gitlab, и то мой локальный.


  1. drno-reg
    07.10.2021 14:35

    вспомнил хакатон 2017 года в октябре и команда с этой идеей обошла нашу) автору респект за подробное описание зачем о это делал и как проходили этапы жизненного цикла MVP и описание выбор инструментов разработки а организации архитектуры - после такого ты становишься full stack разработчиком) не буду оригинальным - предложение поделиться кодом в github и как вариант может появятся контрибьюторы чего и желаю чтобы проект и жил дальше


  1. Levitskyi
    07.10.2021 14:48

    Безумно интересно было почитать о чужом опыте. Я думал только я такой сумасшедший и люблю видеть цифры. Мы в свое время выбрали более простое решение: у каждого на телефоне стояло бесплатное приложение, куда просто вносилась сумма и условная категория, например "бытовуха" "транспорт" "развлечения" "подарки" и тд. Потом девушке даже это надоело и она забила, а я уже больше 5 лет до сих пор заношу суммы в приложение, не могу без этого. Как мне это помогает? Да просто интересно. Например, понимаю сколько в месяц заработал и сколько осталось в итоге. Иногда можно понаблюдать и другую картину: "осталось -8900р"))) В не лучшие времена это помогает немного затянуть пояс когда видишь что уже почти всё потратил, в лучшие - порадоваться либо позволить себе что-то для души, например кинуть донейты любимому бесплатному бесплатному софту, авторам ценных для меня технических ютуб каналов и тд.


  1. D1abloRUS
    08.10.2021 08:24

    Для кэша удобно, цифровую структуру расходов многие банки уже запили.. и не только банки.. офд там все эти. Если тут цифры реальные, то как то все прискорбно на графике


    1. pawellrus Автор
      08.10.2021 09:20

      К банку привязываться не хочется, тем более у каждого свое видение аналитики расходов.

      Скриншоты из тестовой базы. Насколько цифры близки к реальности и близки ли вообще - пусть останется тайной.


  1. Iliya_karin
    08.10.2021 10:28

    Хорошая статья, прям глобально.

    По прочтении остался только 1 вопрос, удалось ли с эникея на разработчика перепрофилироваться?


    1. pawellrus Автор
      08.10.2021 12:06

      Спасибо.

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


  1. Gallemar
    08.10.2021 17:25
    +1

    Отличная статья!

    Автору уважение и удачи в своих новых начинаниях!


  1. Guul
    08.10.2021 19:55
    +1

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