Привет!
Сегодня созвездия сошлись в очень удачное положения для первых шагов в MVP. Появились первые наметки для структуры программы. Для начала я расскажу в целом о своём подходе к управлению данными, а затем опишу философию и структуру соответствующей таблицы.
Сегодня что-то на финансово-программистском.
Доходы я делю на три вида:
- Регулярные. Те, что поступают стабильно и предсказуемо - как правило, ежемесячно/еженедельно и т.п. Это зарплаты в найме, пенсии, постоянные контракты с регулярными усреднённо-фиксированными выплатами (например, у фрилансеров), стипендии, пособия, доходы от аренды недвижимости.
- Дополнительные. Возникают периодически и могут зависеть от множества факторов. Это проценты по банковским депозитам, разовая подработка, партнёрские программы и рефералы, вывод средств или дивидендов с биржевых счетов и т.п.
- Экстра. Непредсказуемые и нерегулярные. Зачастую зависят от внешних обстоятельств. Это могут быть денежные подарки, единоразовые премии (помимо тех, что внутри регулярной зарплаты), выигрыши в лотереях и конкурсах, возврат налогов, наследство, компенсации и т.п.
Сегодня речь именно о регулярных доходах. Как заниматься их прогнозированием и учётом в горизонте одного и более лет.
Для чернового прогноза используется либо пользовательская информация (для фиксированных выплат типа пенсии или пособий, либо контрактов), либо (только для зарплат) - прогрессивная шкала налогообложения.
Первичное заполнение таблицы для каждого пользователя происходит единоразово на 5 лет вперёд при создании типа дохода (добавлении его в учётку пользователя).
Учитывая, что программа достаточно сложная, я предлагаю для пользователей использовать визард, где на первом шаге человек выберет все варианты своих фактических регулярных доходов, а потом заполнит данные по каждому из них последовательно. При этом визард в любой момент должно быть можно прервать и продолжить с шага, на котором остановился.
На первом шаге предлагается выбрать варианты регулярных доходов, применимые к конкретному человеку. Я, например, получаю зарплату, кто-то - зарплату и пенсию, кто-то - контракты от фриланса + пособие + стипендию. Разные ситуации бывают. А кто-то вообще на двух работах в найме на зарплате сидит. И это должно быть учтено. Потому оптимальным здесь будет инструмент чекбоксов (можно выбрать сразу несколько). Кроме того, для каждого варианта можно указать число таких источников дохода. Например - две зарплаты, или три контракта, или одна пенсия, или две стипендии... Каждый сам себе определит сколько чего надо.
- Зарплата. Прогноз по прогрессивной шкале, но ежемесячно корректируется вводом фактических данных о средствах, полученных на руки. Учитывается аванс, зарплата и отпускные. При этом не следует нагружать пользователя требованием указать оклад или процент аванса. Человек может их не знать (например, когда в месяц получает фиксированную премию). Здесь логичнее попросить его ввести приблизительную цифру дохода в месяц - от этого источника (зарплата + аванс суммарно), а также среднее значение аванса, сколько он имеет на руки. На основании этого программа сама считает округленный процент и вычисляет по прогрессивной шкале прогноз, заполняя таблицу сразу на длительный период. Фактические значения пользователь потом по ходу внесёт сам, по мере поступления денег. Кроме того, для удобства можно указать даты получения аванса и зарплаты. Тогда программа сможет "радовать" пользователя подсказками в духе "послезавтра зп!", учитывая выходные и праздничные дни.
- Пенсии. Здесь достаточно указать дату получения пенсии, а также её сумму. Ни аванса, ни отпускных тут нет, а период не ограничен. Потому прогноз заполняется фиксированным значением сразу на весь период вперёд.
- Стипендии, контракты, пособия, аренда недвижимости. Логика аналогично пенсии, но есть возможность указать дату окончания. Тогда расчет будет делаться не на 5 лет, а до даты включительно. Удобно для выплат, которые идут регулярно, но ограниченный период. В остальном логика как у пенсий.
Под каждый вид такого дохода будет создаваться своя уникальная цепочка. И в соответствии с тем, какие чекбоксы пользователь отметил и какое количество такого дохода указал, надо будет заполнить поля для каждого из вида доходов. В режиме "далее-далее-далее".
Какая философия у таких данных?
Историческая информация здесь не интересна. Программа не ставит себе целью анализировать, как отличается прогнозный расчет от фактических средств за период сколько-то-времени-тому-назад. Нужны только актуальные данные. Потому при поступлении денег, пользователь вносит их в программу и прогнозная цифра перетирается фактической.
Цель - дать возможность пользователю прогнозировать доходы и расходы. А для этого актуальная информация важна, а исторические данные - нет.
Достаточная точность. Для учёта и отображения используется дробное значение до 4 знаков после запятой. При этом в базе данных хранятся только преобразованные целочисленные значения, т.к. хранение Double/Float приводит к погрешностям, которые в финансах допускать категорически нельзя.
Максимальная анонимность. Не хранить данные, о которых говорится в федеральном законе 152-ФЗ. Это распространяется не только на то, что нам не нужна информация о пользователях, которая может быть скомпрометирована, но так же не рекомендуется хранить настоящие данные о счетах - номера карт и прочее. Анонимно безопаснее для всех, тем более, что речь идёт о деньгах.
Отсюда получаем вот какие поля (предварительно, так как при финальном проектировании я наверняка что-то ещё вспомню и додумаю).
- RegularIncomeID. Тип данных UUID. Уникальный идентификатор цепочки - вида регулярного платежа. По этому идентификатору можно будет собирать цепочки конкретного пользователя и использовать их в аналитике, прогнозировании или просто корректировках данных.
- UID. Идентификатор пользователя внутри сайта. Нужно для связки со многими сущностями как моей базы данных, так и служб самого сайта.
- Year. Год, за который делается аналитика или вносятся прогнозные и фактические данные. Обычное 4-значное Decimal значение.
- Month. Аналогично, только месяц. Decimal-значения от 1 до 12 (или вообще hex для экономии памяти). Можно было бы объединить с годом, но мне хочется прозрачности не только для пользователей, но и при написании выборок из базы - то есть удобства для себя лично. Так-то, это поле можно было бы вполне объединить с предыдущим.
- AdvancePayment. Авансовый платёж. Поле используется только у зарплатных типов дохода. По умолчанию на весь период заполняется по прогрессивной шкале, но потом, по мере получения денег, пользователь затирает прогнозные значения и сохраняет там фактически полученные на руки. Значение строго Decimal.
- Salary. Зарплата. Логика аналогична, но поле универсальное - как для зарплатных типов, так и для пенсий, стипендий и т.п. Фиксированные платежи хранятся в базе как Salary.
- VacationPay. Отпускные. Аналогично авансу, только отпускные. В типах кроме зарплат - не используется за ненадобностью.
- IncomeType. Здесь указывается тип дохода. Скорее всего, я вынесу его в отдельную таблицу, чтоб от месяца к месяцу не писать одни и те же данные. Но суть в том, что здесь пишется именно разновидность дохода, что это: зарплата (0), пенсия (1), контракт (2), аренда (3) или что-то другое (4).
- Status. Состояние конкретно этой записи. По умолчанию все записи прогнозные, то есть имеют значение "000". По мере заполнения данных в поля аванса (10), зарплаты (1) и отпускных (100) меняется и запись. Возможные варианты: 100 (только отпускные, без ЗП и аванса), 010 (аванс дали и больше ничего), 001 (только зарплата и больше ничего), 011 (аванс + зарплата уже выплачены), 111 (выплачены все три показателя - аванс, зп и отпускные). Так программа сможет отличать чисто программно-прогнозные данные от фиксированных пользователем.
- Comment. Комментарий пользователя, по которому он сможет однозначно идентифицировать, о каком счёте идёт речь. Также можно вынести в отдельную таблицу и связать по RegularIncomeId.
- Weight. Вес в списке. Также для отдельной таблицы. Исключительно с целью дать возможность отображать виды доходов в том порядке, как удобно пользователю, а не "просто по алфавиту" или ещё каким-то критериям.
- PeriodEnd. Дата окончания срока действия дохода. Нужно для ограниченных по времени выплат. По умолчанию тут пусто, но если значение есть, то и аналитика по датам за пределами сохранённой вычисляться не будет.
Кроме того неплохо иметь данные, которые пользователь вводит базово - в среднем размер суммарного дохода по источнику и в среднем размер аванса. Тогда из них можно будет делать расчеты.
Кроме того, если в процессе у человека, например, вырастет зарплата или изменится размер аванса, можно в любой момент поправить эти данные и программа сделает пересчет всего периода на 5 лет вперёд от даты, с которой действует изменение. Это благотворно скажется на прогнозировании.
Вот такие мысли. Пожалуй, это уже в MVP можно будет включать. Осталось добраться до кодинга, а не всё о брендировании рассуждать.