Чистый код

Поступила интересная задача по автоматическому заведению пользователя сразу в несколько баз 1С Бухгалтерия 3.0 с помощью Обновлятора-1С.
При создании пользователя должны прописываться следующие параметры:
1. Имя пользователя.
2. Полное Имя.
3. Вход в программу разрешен = истина
4. Аутентификация 1С Предприятие = истина
5. Пароль для пользователя.
6. Потребовать смену пароля при входе = истина
7. Пользователю запрещено менять пароль = ложь
8. Пользователю запрещено восстанавливать пароль = ложь
9. Показывать в списке выбора = ложь
10. Электронная почта.
Права доступа:
1. Администратор
2. Главный бухгалтер
3. Открытие внешних отчетов.
4. Синхронизация с другими программами.
Решение есть и даже в нескольких вариантах, но все же пришлось повозиться со скриптом из-за электронной почты (она не мигрирует автоматически из пользователя конфигуратора в пользователя 1С БСП и просит закончить миграцию самостоятельно) и прав доступа через профили групп доступа.
В итоге родился следующий код:
#use "updater1c"
// ****************************************************************************
// Переменные модуля
// ****************************************************************************
Перем errors; // Признак того, что при выполнении скрипта были ошибки.
Перем updater; // Обновлятор, через который мы получаем информацию о базе,
// а также вызываем различные функции обновлятора.
Перем connector; // Коннектор для подключения к базе.
Перем v8; // Само подключение к базе через коннектор.
// ****************************************************************************
// Ваш код для выполнения обновлятором
// ****************************************************************************
Процедура Главная()
ИмяПользователя = "Тест";
ПолноеИмяПользователя = "Тестов Тест";
Пароль = "123";
ЭлПочта = "test@mail.ru";
// создаём пользователя ИБ
ПользовательИБ = v8.ПользователиИнформационнойБазы.СоздатьПользователя();
ПользовательИБ.Имя = ИмяПользователя;
ПользовательИБ.ПолноеИмя = ПолноеИмяПользователя;
ПользовательИБ.Пароль = Пароль;
ПользовательИБ.ПоказыватьВСпискеВыбора = Ложь;
ПользовательИБ.АутентификацияОС = Истина;
ПользовательИБ.АутентификацияСтандартная = Истина;
ПользовательИБ.ЗапрещеноИзменятьПароль = Ложь;
ПользовательИБ.ЗапрещеноВосстанавливатьПароль = Ложь;
ПользовательИБ.АдресЭлектроннойПочты = ЭлПочта;
Если v8.ПользователиИнформационнойБазы.НайтиПоИмени(ПользовательИБ.Имя) = Неопределено Тогда
ПользовательИБ.Записать();
Сообщить("Новый пользователь создан.");
Иначе
Сообщить("Пользователь с таким именем уже есть в базе!");
Возврат;
КонецЕсли;
// создаём пользователя в справочнике Пользователи
Пользователь = v8.Справочники.Пользователи.СоздатьЭлемент();
Пользователь.Наименование = ПользовательИБ.ПолноеИмя;
Пользователь.Недействителен = Ложь;
ОписаниеПользователяИБ = v8.NewObject("Структура");
ОписаниеПользователяИБ.Вставить("Действие", "Записать");
ОписаниеПользователяИБ.Вставить("УникальныйИдентификатор", ПользовательИБ.УникальныйИдентификатор);
ОписаниеПользователяИБ.Вставить("Имя", ИмяПользователя);
ОписаниеПользователяИБ.Вставить("ПолноеИмя", ПолноеИмяПользователя);
ОписаниеПользователяИБ.Вставить("АутентификацияСтандартная", Истина);
ОписаниеПользователяИБ.Вставить("АутентификацияОС", Истина);
ОписаниеПользователяИБ.Вставить("Пароль", Пароль);
ОписаниеПользователяИБ.Вставить("Почта", ЭлПочта);
ОписаниеПользователяИБ.Вставить("АдресЭлектроннойПочты", ЭлПочта);
ОписаниеПользователяИБ.Вставить("ПоказыватьВСпискеВыбора", Ложь);
ОписаниеПользователяИБ.Вставить("ЗапрещеноИзменятьПароль", Ложь);
ОписаниеПользователяИБ.Вставить("ЗапрещеноВосстанавливатьПароль", Ложь);
ОписаниеПользователяИБ.Вставить("РежимЗапуска", "Авто");
ОписаниеПользователяИБ.Вставить("ВходВПрограммуРазрешен", Истина);
ОписаниеПользователяИБ.Вставить("ПотребоватьСменуПароляПриВходе", Истина);
Пользователь.ДополнительныеСвойства.Вставить("ОписаниеПользователяИБ", ОписаниеПользователяИБ);
Пользователь.Записать();
//e-mail добавим через контактуню информацию
ВидКонтактнойИнформации = v8.Справочники.ВидыКонтактнойИнформации.EmailПользователя;
ТипКонтактнойИнформации = ВидКонтактнойИнформации.Тип;
ЗначенияПолей = v8.УправлениеКонтактнойИнформацией.КонтактнаяИнформацияПоПредставлению(ЭлПочта, ВидКонтактнойИнформации);
v8.УправлениеКонтактнойИнформацией.ЗаписатьКонтактнуюИнформацию(Пользователь, ЗначенияПолей, ВидКонтактнойИнформации, ТипКонтактнойИнформации);
Пользователь.Записать();
ТекПользователь = Пользователь.Ссылка;
// назначаем права пользователю ИБ
ТекПрофиль = v8.Справочники.ПрофилиГруппДоступа.НайтиПоНаименованию("Администратор");
v8.УправлениеДоступом.ВключитьПрофильПользователю(ТекПользователь, ТекПрофиль);
ТекПрофиль = v8.Справочники.ПрофилиГруппДоступа.НайтиПоНаименованию("Главный бухгалтер");
v8.УправлениеДоступом.ВключитьПрофильПользователю(ТекПользователь, ТекПрофиль);
ТекПрофиль = v8.Справочники.ПрофилиГруппДоступа.НайтиПоНаименованию("Открытие внешних отчетов и обработок");
v8.УправлениеДоступом.ВключитьПрофильПользователю(ТекПользователь, ТекПрофиль);
ТекПрофиль = v8.Справочники.ПрофилиГруппДоступа.НайтиПоНаименованию("Синхронизация данных с другими программами");
v8.УправлениеДоступом.ВключитьПрофильПользователю(ТекПользователь, ТекПрофиль);
КонецПроцедуры
// ****************************************************************************
// Служебные процедуры
// ****************************************************************************
Процедура ПриНачалеРаботы()
errors = Ложь;
updater = Новый Updater1C;
connector = updater.CreateConnector();
v8 = updater.BaseConnectNew(connector);
КонецПроцедуры
Процедура ПриОкончанииРаботы()
Если v8 <> Неопределено Тогда
Попытка
ОсвободитьОбъект(v8);
v8 = Неопределено;
Исключение
КонецПопытки;
КонецЕсли;
Если connector <> Неопределено Тогда
Попытка
ОсвободитьОбъект(connector);
connector = Неопределено;
Исключение
КонецПопытки;
КонецЕсли;
Если updater <> Неопределено Тогда
Попытка
ОсвободитьОбъект(updater);
updater = Неопределено;
Исключение
КонецПопытки;
КонецЕсли;
Приостановить(1000);
Если errors Тогда
ЗавершитьРаботу(1);
КонецЕсли;
КонецПроцедуры
// ****************************************************************************
// Инициализация и запуск скрипта
// ****************************************************************************
ПриНачалеРаботы();
Попытка
Главная();
updater.КодПользователяВыполнился();
Исключение
errors = Истина;
Сообщить("<span class='red'><b>" + ОписаниеОшибки() + "</b></span>");
КонецПопытки;
ПриОкончанииРаботы();
Принцип двойной записи можно кратко cформулировать так: когда в одном месте средства убывают, в другом они прибывают. Например, если после посещения магазина в кошельке убавились деньги, значит сумма в одном из активов уменьшилась, а сумма на счете «расходы» увеличилась. Принцип двойной записи — это основополагающий принцип в бухгалтерии.
Согласно этому принципу в каждой записи обычно не менее двух счетов, но указывать сумму для одного из них необязательно, понятно, что изменение будет равно сумме всех других, но с противоположенным знаком:
2014-09-21 Проезд на метро во время Московского марафона
актив:наличные ; понятно, что здесь должно быть -35
расходы:проезд 35
В 2003 году John Wiegley представил Ledger: текстовый формат данных и утилиту командной строки для эффективного бухучета в системе двойной записи. Эта идея прижилась среди разработчиков и технарей, поэтому сейчас существует более 5 активных проектов, таких как hledger и Beancount, с более чем 40 расширений и утилит и активное сообщество. На этом сайте вы найдете описание утилит, документацию и лучшие практики этой системы учета.
Финансовые данные очень важны для нас и мы хотим всегда иметь полный доступ к ним — даже без программного обеспечения. Мы хотим отслеживать все изменения и хранить их в системе контроля версий. Мы хотим искать в них, манипулировать ими эффективно. Поэтому мы храним их в человеко-читаемом виде в простом тексте.
Вместо дебета-кредита мы используем знак числа — "плюс" для поступлений на счет, "минус" для списаний со счета.
Мы задаем произвольную иерархию счетов, которая полностью отвечает нашим потребностям и с легкостью работает как в простых, так и в сложных вариантах учета.
Кто этим пользуется ?
Пока, в основном, технари и опытные пользователи, хотя авторы и делают всё возможное для снижения порога вхождения.
Почитайте Кто использует Ledger (на англ.), там много интересных историй пользователей системы.
Мне придется писать всякие непонятные команды ?
Нет, конечно!
"Бухучет на текстовых файлах" это просто название, относящееся, в основном, к формату хранения данных.
Мы не имеем ничего против дополнительных средств с GUI, и их немало.
Какие еще есть программы для учета ?
Свободные утилиты типа GNUCash, Grisbi, KMyMoney.
Проприетарные типа Quicken/Quickbooks, You Need A Budget.
Онлайновые: Xero, FreeAgent.
Вообще есть хорошее сравнение.
Кто-то ведет учет в таблицах.
Также можно вести учет денег на бумаге. Или нанять бухгалтера.
Почему это лучше чем, к примеру, QuickBooks ?
Ваши данные всегда доступны (даже когда нет интернета).
Никаких ежегодных платежей, все абсолютно бесплатно.
Вы можете доработать ПО при желании.
Кроссплатформенно.
Расширяемо.
Эффективно.
А как с бюджетированием ?
Смотрите раздел бюджетирование ниже. Можно эмулировать бюджетирование в стиле YNAB (третья ссылка).
Но учет денег отнимает столько времени…
Прочитайте книгу "Миллионер по соседству", она откроет глаза на важность вопросов финансового контроля и планирования. “Планирование и контроль потребления – ключевые факторы в вопросе накопления богатства… Отсутствие четкого бюджета в вашей семье сравнимо с отсутствием бизнес-плана на предприятии или каких-либо производственных целей”.
Вы правда вводите каждую мельчайшую транзакцию ?
Да! И многие из нас так делают. Кто-то начал детальный учет давно и все еще продолжает, потому что это не напряжно и весело. Но это не обязательно. Вы можете выработать свой подход к внесению транзакций. Но учтите, что этот способ позволяет легко найти ошибки в учете и с легкостью исправить их.
Как это возможно ?
Практика и процесс/инструмент, которые подходят вам. Некоторые просто импортируют большинство данных из банка (в формате CSV), поэтому им требуется лишь небольшая работа руками. Кто-то предпочитает вручную вводить каждую операцию, чтобы не упустить мелочей. "Ручной" ввод данных обычно не нужен благодаря интерактивным консольным утилитам (hledger add и подобные), web-утилитам (hledger-web и подобные), утилитам с GUI (ledgerhelpers), умным редакторам (типа emacs & ledger-mode, vim, sublime-text с плагином), сценариям повторяющихся транзакций. Если использовать импорт банковских CSV и ввод небольшого количества операций в вашем любимом редакторе, это в среднем будет занимать минут 15 в день, и это не плохая инвестиция.
Как я могу использовать данные из моего банка или мобильного приложения ?
Если вы можете выгрузить их в формат CSV, то вы без проблем загрузите их в формат Ledger. Также ниже перечислено несколько утилит для конвертации из форматов OFX, QIF и т.п.
Где можно увидеть сравнение hledger, Ledger, beancount и остальных ?
Здесь в таблице, а также в разделе сравнение. У hledger в разделе частых вопросов также расписаны отличия от других систем.
Как я могу организовать файлы журнала ? Мне нужно их делить на периоды ?
Все в одном файле (или один файл на каждый год), отсортированном по дате — проще всего.
Вот здесь описан один из способов организации:
How do you manage multiple accounts in ledger/hledger?
byu/floriplum inplaintextaccounting
Насколько большой файл журнала у вас ?
Для личной бухгалтерии что-то около 500-1500 транзакций и 100-400 Kb за один год.
How big is your ledger/journal file
byu/threesevenths inplaintextaccounting
Приложения для ведения бухгалтерии на текстовых файлах:
Плагины для популярных редакторов.
Atom language-ledger, ledger
Emacs beancount-mode, hledger-mode, ledger-mode (с поддержкой hledger, beancount и т.д.)
VIM vim-ledger (ledger & hledger), vim-beancount, hledger-vim
Sublime sublime-ledger-syntax
TextMate Ledger.tmbundle
VS Code hledger-vscode, ledger, vscode-beancount
Jetbrains (IntelliJ) Ledger Plugin
2009, 2013, 2014, 2014, 2015, 2016, 2016, 2016
@LedgerTips, #plaintextaccounting, #ledgercli, #hledger, #beancount
на русском:
на англ.:
на англ.:
на англ.:
на англ.:
на русском:
на англ.:
2021
2020
2019
Более старые:
на англ.:
на англ.:
C-c C-a
добавить транзакцию,
C-c C-b
калькулятор,
C-c C-c
/C-c C-e
toggle clearedОтчет с командой ledger —budget:
Автоматические транзакции:
С org-mode:
С обычными субсчетами:
Поддержка Python 3 в Ledger Python
ledgerhelpers Python
hledger-lib, hledger, пример Haskell
hledger-api, примеры JSON
node-hledger JavaScript
This list powered by: Plain Tex Accounting
Ранее учет с ledger (на русском) был описан в статьях Планирование финансов через командную стоку в ledger, Финансовый учёт с ledger и Ledger — бухучёт в командной строке. Для общего развития рекомендую ознакомиться с ними.
Счетом мы называем любой вид Дохода/Расхода, а также любое “место”, откуда/куда приходят деньги. Кто-то называет их категориями, но суть от этого не меняется.
Обычно заводят такие счета как “Продукты”, “Авто”, “Подарки”, “Зарплата”, “Наличные”, “Ипотека” и т.п.
В системе двойной записи деньги переходят с одного счета на другой. И при этом отображаются в обоих строках транзакции с разными знаками. К примеру, покупка книги за 500 рублей переводит деньги со счета “Наличные” на счет “Книги”. Получение зарплаты отражается как перевод денег со счета “Зарплата” на счет “Наличные” (ну или “Банковская карта”). Главное — помнить, что при перемещении денег в итоге должен быть обязательно ноль, иначе ничего не получится.
Итак, мы выяснили, что счета могут быть самые разные, но многие пользователи добавляют такие счета верхнего уровня:
• Расходы (Expenses)
• Доходы (Income)
• Активы (Assets)
• Обязательства (Liabilities)
для того, чтобы в дальнейшем построить удобную структуру доходов/расходов. Иерархия счета таким образом может выглядеть так: “Расходы” -> “Авто” -> “Бензин”. И записываются такие счета в транзакциях через двоеточие: “Расходы:Авто:Бензин” (хотя вы можете использовать другой разделитель, об этом будет написано ниже).
Я опишу здесь свой опыт реального использования утилиты hledger. Если у вас появятся вопросы, с радостью отвечу на них в комментариях или чате 🙂
Прежде всего, почему hledger, а не ledger-cli? На самом деле между ними нет большой разницы, используйте любую утилиту, благо формат журнала у них очень похожий. Мне нравятся функциональные языки программирования, а hledger написан на Haskell. При этом я пользуюсь MS Windows, а ledger-cli в этой ОС работает не очень хорошо. У hledger есть hledger-api для написания своих программ поверх hledger и я планирую заняться этим в ближайшее время, но и у ledger есть python api, который тоже очень удобен. В общем, решать вам, что использовать, я для себя пока выбрал hledger и он мне нравится 🙂
В этом учебнике мы создадим удобное дерево счетов, настроим программу на работу с несколькими валютами, покажем типовые сценарии использования различных финансовых инструментов и настроим удобный ввод транзакций.
Также построим надежную и гибкую структуру файлов журнала с выгрузкой изменений в систему хранения версий BitBucket (в приватном бесплатном репозитории).
Создайте пустой файл в блокноте и сохраните файл под любым именем, например “ledger.txt”.
В дальнейшем нужно будет запускать hledger так:
hledger -f ledger.txt <команда>
Но для hledger можно назвать файл “.hledger.journal” и поместить его в директорию пользователя ( /home для *nix систем или “C:\Users\<Имя пользователя>\” в Windows ) и тогда при вызове hledger вам не нужно будет каждый раз указывать имя файла. Например, так:
hledger <команда>
Предположим, вы так и сделали и у вас теперь есть файл журнала в домашней директории.
У hledger есть удобная команда интерактивного ввода add, здесь вы можете ее увидеть в действии. Вы можете попробовать ввести с ее помощью транзакцию и затем посмотреть что записалось в файл журнала.
Откройте журнал любимым редактором ( я рекомендую SublimeText3 с плагином подсветки/дополнения или Vim/Emacs ) и добавьте следующую операцию (или замените транзакцию, созданную при помощи команды add):
2016/09/01 * Зарплата
Кошелек:Наличные 10000 руб
Доходы:Зарплата
Вкратце поясню что мы написали, но рекомендую все же ознакомиться с форматом записи ledger. У нас описана операция получения зарплаты в размере 10000 руб от 1 сентября 2016 г. В ней мы зачисляем 10000 руб на счет “Кошелек:Наличные” со счета “Доходы:Зарплата”.
Вы можете указать сумму с минусом в строке “Доходы:Зарплата”, но это не обязательно и важно только в транзакциях с тремя и более строками. Hledger автоматически понимает, что с другой стороны проводки нужная нам сумма.
При этом, в нашей транзакции указан флаг *, который говорит нам о том, что транзакция выверенная (флаг может быть ! и *, а можно его вообще не указывать). К примеру, вы вводите транзакции, а в конце недели сверяете с банковской выпиской, отмечая при этом сверенные транзакции флажком *. Знаком ! отмечают незаконченные транзакции (в статусе ожидания), но вам это, возможно, пригодится позже.
Свой разделитель счетов. Если вам не нравится знак двоеточие между счетами, вы можете указать свой разделитель. Для этого в начале журнала добавьте псевдоним для двоеточия и программа его обработает как разделитель, к примеру, укажем точку:
# alias /РЕГУЛЯРНОЕ ВЫРАЖЕНИЕ/=ЗАМЕНА
alias /\./=:
2016/10/01 зарплата
Кошелек.Расчетный счет 1000 руб
Доход.Зарплата
Еще момент — необходимо указать минимум два пробела между счетом и суммой, иначе программа будет считать сумму частью названия счета и выдаст ошибку!
Теперь запустим отчет Баланс (команда balance или bal):
hledger balance
-10000 руб Доходы:Зарплата
10000 руб Кошелек:Наличные
--------------------
0
Ноль под чертой очень важен и показывает, что у нас все транзакции записаны правильно с точки зрения двойной записи. А остаток в кошельке у нас 10 000 руб.
Теперь вы видите насколько просто вести учет денег с ledger?
Вы спросите, почему Доходы показаны с минусом? Если кратко, то в двойной записи деньги (как и любая другая ценность) должны откуда-то переместиться куда-то. В нашем примере они пришли со статьи дохода на статью расхода. Поэтому на счете поступления показан плюсовой остаток, а на другом счете — отрицательный. Иными словами, на счете дохода их стало меньше, чем в нашем кошельке 🙂
Введем еще одну операцию:
2016/09/05 * Бензин
Кошелек:Наличные
Расходы:Авто 1000 руб
Вы можете вводить транзакции с помощью команды add, тогда вам не нужно запоминать форматирование, флаги и т.п. Однако, сам формат журнала ledger очень простой и вводить транзакции руками не сложно. Я чаще всего использую копирование предыдущих записей с правкой даты и суммы — для каждодневных трат это удобно.
Для редких записей несложно либо найти их ранее в журнале, либо ввести “с нуля”, для этого и важно понимать формат.
Чаще всего нужен ответ на вопрос “Сколько я трачу в месяц на …?” Увидеть это можно так:
hledger -M register Расходы:Авто
2016/09 Расходы:Авто 1000 руб 1000 руб
Теперь купим немного продуктов:
2016/09/21 * продукты
Кошелек:Наличные
Расходы:Продукты 700 руб
Запускаем баланс:
hledger balance
-10000 руб Доходы:Зарплата
8300 руб Кошелек:Наличные
1700 руб Расходы
1000 руб Авто
700 руб Продукты
--------------------
0
Выводим список наших транзакций:
hledger reg
2016/09/01 Зарплата Кошелек:Наличные 10000 руб 10000 руб
Доходы:Зарплата -10000 руб 0
2016/09/05 Бензин Кошелек:Наличные -1000 руб -1000 руб
Расходы:Авто 1000 руб 0
2016/09/21 продукты Кошелек:Наличные -700 руб -700 руб
Расходы:Продукты 700 руб 0
Ну и баланс еще раз:
# Сколько потратил на авто:
hledger bal Расходы:Авто
1000 руб Расходы:Авто
--------------------
1000 руб
# Сколько у меня денег:
hledger bal ^Расходы ^Доходы
-10000 руб Доходы:Зарплата
1700 руб Расходы
1000 руб Авто
700 руб Продукты
--------------------
-8300 руб
Один из самых важных вопросов в ведении личных доходов — удобное дерево статей (счетов).
Кто-то пытается максимально подробно вести учет, вплоть до того, что делают статьи чрезмерно большой вложенности: “Расходы — Продукты — Крупы — Гречка”. Если вы ведете учет финансов больше года, то это может быть оправдано, но если вы только начали, то ведение настолько подробного учета прогонит все желание продолжать.
Я предлагаю начать с малого и увеличивать количество статей в процессе. Итак, мы с вами уже описали счета “Кошелек:Наличные”, “Доходы:Зарплата”, “Расходы:Авто” и “Расходы:Продукты”. Отличное начало.
Теперь представим основные кошельки / доходы / расходы / долги и на основе этого (пока мысленно) составим наше дерево статей. К слову, у меня примерно такое (это не файл примера):
λ hledger accounts --tree
Кошелек
Кредитка
Наличные
Расходы
Авто
Бензин
Налоги
Ремонт
Здоровье
Коммунальные
Налоги
Одежда
Продукты
Прочие
Связь
Кредиты
Банк1
Банк2
Доход
Зарплата
Прочий
Еще момент про дерево статей: когда мне нужно увидеть какой-то расход более подробно, я создаю для него отдельный счет. К примеру, все продукты я учитываю на счете “Расходы:Продукты”, но, к примеру, мне стало интересно, сколько я трачу на кофе ( и это не праздный интерес, кофе действительно стало уменьшаться очень быстро 🙂 ). Для этого я создаю транзакции по покупке кофе так:
2016/10/01 * кофе
Кошелек:Наличные
Расходы:Продукты:Кофе 200 руб
Так в вашем балансе будет видно расходы в целом на продукты, а также отдельной строкой затраты на кофе. Очень удобно!
Вы теперь умеете вводить транзакции (через команду add или вручную в текстовом редакторе) и пользуетесь при этом вашим деревом статей. Замечательно. Теперь давайте сделаем наш журнал более удобным.
Откроем снова наш файл .hledger.journal:
; Это главный файл журнала hledger.
; Реальные данные содержатся в файлах в папке myledger
; Вложим актуальный журнал
include myledger/main.journal
Таким образом можно разбивать файлы транзакций по валютам, счетам, а также по годам для удобства. Что мы и сделаем:
Создайте папку myledger в домашней директории пользователя. Откройте ее.
Предупреждение: Вы можете пропустить этот абзац, если не планируте хранить ваш журнал в системе версий.
Зарегистрируйтесь на BitBucket и создайте новый приватный репозиторий. Нозовите его, к примеру, “myledger”. Откройте терминал и перейдите в эту папку:
cd myledger
git init
git remote add origin https://fokusov@bitbucket.org/fokusov/myledger.git
примечание: название репозитория и имя пользователя замените на свое.
Создадим файл main.journal в этой папке и откроем его:
alias Кредиты = Liabilities
alias Кошелек = Assets
alias Расходы = Expenses
alias Доходы = Income
D 1000.00 руб
include 2015.journal
include 2016.journal
end aliases
include prices.dat
Итак, в этом файле также нет транзакций, но указана метаинформация, очень важная для hledger.
Первые строки, начинающиеся с alias — это наши псевдонимы для счетов, чтобы программа могла составлять правильно отчетные формы, а мы могли писать название корневых счетов по-русски.
Далее идет строка D 1000.00 руб
, описывающая валюту по-умолчанию и ее формат. Таким образом, не указывая явно валюту в каждой транзакции, мы будем знать, что она рублевая и пересчет между валютами будет корректен.
Далее мы вкладываем журналы транзакций, разбитые по годам. Я веду учет три года и у меня вложены файлы журнала за последние три года.
Сортировать по годам необязательно, но очень удобно, что записи разных лет хранятся в разных файлах, а не в одном большом. Фразой end aliases
мы завершаем применение псевдонимов к нашим файлам и ниже вкладываем файл с ценами prices.dat.
Создайте указанные файлы (2015.journal, 2016.journal, prices.dat) или закомментируйте строку с ненужным файлом. Комментарии начинаются со знака ;
Сохраним наши файлы в репозитории:
git add *
git commit -m "Initial commit"
git push -u origin master
Теперь открываем файл нужного года (к примеру, 2016.journal) и вводим в него транзакции с помощью текстового редактора. Либо с помощью команды add, но с обязательным указание файла журнала, иначе она добавит наши транзакции в главный журнал:
hledger add -f myledger\2016.journal
Сделаем командный файл, который будет выгружать наши изменения в удаленный репозиторий:
myledger\upd.cmd:
git add -A
git commit -m "upd"
git push origin master
Добавим еще один служебный тег в текущий файл журнала (2016.journal):
Добавьте в начало файла указание на год:
Y2016
Теперь мы можем вводить транзакции немного быстрее:
10/01
Кошелек:Наличные
Расходы:Продукты 500
не указывая год и валюту (но если укажете год в транзакции, ничего страшного не произойдет). При этом программа знает, что это рублевая транзакция, совершенная в 2016 году.
В ledger очень легко вести учет в разных валютах и пересчитывать их из одной в другую автоматически.
Для этого необходимо вести файл с ценами/курсами (этот файл также нужен для автоматического расчета стоимости ценных бумаг), который можно сделать для автоматической загрузки из сети. У нас он уже есть, это файл prices.dat. Откроем его:
P 2016/10/28 10:00:00 USD 62.96 руб
P 2016/10/28 10:00:00 EUR 68.77 руб
Как мы видим, это официальные курсы валют центробанка на указанную дату, структурированные в формате ledger.
Если вы ведете транзакции в разной валюте, к примеру так:
2016/09/01 Зарплата
Кошелек:Наличные 10000 руб
Доходы:Зарплата
2016/09/05 * Бензин
Кошелек:Наличные
Расходы:Авто 1000 руб
2016/09/21 * продукты
Кошелек:Наличные
Расходы:Продукты 700 руб
2016/09/10 Шабашка
Кошелек:Наличные 500 USD
Доходы:Прочие
то баланс будет не очень красивый:
λ hledger bal
-500 USD
-10000 руб Доходы
-10000 руб Зарплата
-500 USD Прочие
500 USD
8300 руб Кошелек:Наличные
1700 руб Расходы
1000 руб Авто
700 руб Продукты
--------------------
0
# Попросим сконвертировать все данные в базовую валюту:
λ hledger bal -V
-41480.00 руб Доходы
-10000.00 руб Зарплата
-31480.00 руб Прочие
39780.00 руб Кошелек:Наличные
1700.00 руб Расходы
1000.00 руб Авто
700.00 руб Продукты
--------------------
0
Так лучше 🙂
Теперь введем валютную транзакцию, но чтобы она посчиталась корректно. Для этого есть три способа:
; 1. указываем уже рассчитанную стоимость в рублях - к примеру, когда наш банк уже пересчитал ее по своему курсу и снял с карты
2016/10/28 покупка домена
Кошелек:Карта
Расходы:Прочие 8.17 USD @@ 514.38 руб
; 2. указываем курс валюты / цену товара за единицу
2016/10/28 покупка домена
Кошелек:Карта
Расходы:Прочие 8.17 USD @ 62.96 руб
; 3. позволим hledger рассчитать курс / цену
2016/10/28 покупка домена
Кошелек:Карта -514.38 руб
Расходы:Прочие 8.17 USD
Выведите баланс в консоли и потом баланс с ключом -V.
У hledger есть немало команд, не говоря о плагинах. Но я рассмотрю те, которыми пользуюсь сам.
Команды:
print выводит список транзакций на экран
accounts выводит названия счетов
balance выводит счета и баланс (bal)
register транзакции и сальдо каждой (reg)
incomestatement отчет о доходах и расходах (is)
balancesheet выводит баланс - активы/пассивы (bs)
cashflow выводит денежный поток (cf)
activity выводит диаграмму в ascii о движении денег за период
(по умолчанию: за день)
stats выводит статистику журнала
Выведем статистику моего журнала:
λ hledger stats
Main file : C:\Users\fokusov\.hledger.journal
Included files : C:\Users\fokusov\myledger/main.journal
C:\Users\fokusov\myledger\2014.journal
C:\Users\fokusov\myledger\2015.journal
C:\Users\fokusov\myledger\2016.journal
C:\Users\fokusov\myledger\prices.dat
Transactions span : 2014-04-01 to 2016-11-03 (947 days)
Last transaction : 2016-11-02 (1 days ago)
Transactions : 431 (0.5 per day)
Transactions last 30 days: 76 (2.5 per day)
Transactions last 7 days : 12 (1.7 per day)
Payees/descriptions : 89
Accounts : 39 (depth 3)
Commodities : 3 (EUR, USD, руб)
Интересное применение команды print:
# заархивируем 2015 год в отдельном файле
hledger print -b 2015 -e 2016 > 2015.journal
Команда balancesheet
$ hledger balancesheet
Balance Sheet
Assets:
$-1 assets
$1 Банк:Вклад
$-2 Наличные
--------------------
$-1
Liabilities:
$1 liabilities:Долги
--------------------
$1
Total:
--------------------
0
Команда cashflow
$ hledger cashflow
Cashflow Statement
Cash flows:
$-1 assets
$1 Банк:Вклад
$-2 Наличные
--------------------
$-1
Total:
--------------------
$-1
Команда incomestatement
$ hledger incomestatement
Income Statement
Revenues:
$-2 income
$-1 Подарки
$-1 Зарплата
--------------------
$-2
Expenses:
$2 expenses
$1 Продукты
$1 Прочее
--------------------
$2
Total:
--------------------
0
Я опишу для примера несколько видов транзакций, которыми пользуюсь сам — это учет долгов, ввод начальных остатков, ввод большого чека. Это справочная информация, возможно, она вам не пригодится. Однако, для общего развития очень полезна:
2016/09/01 начальный остаток
Кошелек:Наличные 10000 руб
Старт
где “Старт” можно заменить на “Капитал:Открытие счета” или что-то подобное. Важно что на нужном счете появится нужная сумма, при этом взятая из другого источника (т.е. нам он не важен).
2016/09/01 Взял в долг у Ивана
Кошелек:Наличные 10000 руб
Долги:Иван
2016/09/11 Отдал долг Ивану
Кошелек:Наличные
Долги:Иван 10000 руб
2016/10/01 * Леруа
Кошелек:Наличные -47850 руб ; цифра введена для контроля, если ее не вводить, то она рассчитается автоматом
Расходы:Ремонт квартиры:Обои 8250 руб
Расходы:Ремонт квартиры:Краска 6300 руб
Расходы:Ремонт квартиры:Ламинат 23000 руб
Расходы:Ремонт квартиры:Светильник 10300 руб
Я продолжаю изучать возможности ledger и многое еще предстоит открыть.
В ближайших планах:
— настроить синхронизацию с мобильным приложением Monefy (или аналогом);
— найти хороший веб-интерфейс для просмотра отчетов ledger;
— настроить обмен данными с банками (выгрузка в csv);
— настроить автоматический расчет налогов с дохода (6% для фрилансера на УСН) при вводе транзакций.
Возможно, вы тоже нашли интересные штуки при работе с ledger, поделитесь ими в комментариях 🙂
Списки дел — это основной компонент моей продуктивности. Причем я использую систему GTD уже очень давно и перепробовал много хороших утилит, прежде чем прийти к системе Todo.txt
В данном разделе я рассматриваю ключевые особенности этой системы и существующие утилиты, помогающей в работе с ней, хотя, как вы наверное поняли, иногда достаточно простого текстового редактора 🙂
Эту систему разработала Gina Tripani — блогер, подскастер, разработчик и основатель LifeHacker.
Она сама, а также огромное количество разработчиков создали различное ПО для работы с этим форматом. Сейчас есть как утилиты командной строки, так и утилиты с графическим интерфейсом, прекрасно работающие во всех современных операционных системах.
Формат совершенно не сложный, но при этом отвечающий требованиям системы GTD :
(A) Позвонить маме @Телефон +Семья
(A) Запланировать ежегодный осмотр +Здоровье
(B) Содержание главы 5 +Роман @Компьютер
(C) Добавить обожку @Офис +TPSReports
Спланировать сад во дворе @Дом
Взять молоко @ПродуктовыйМагазин
Найти услуги самиздата +Роман @Компьютер
x Скачать Todo.txt в телефон @Телефон
Когда у вас появляется свободная минутка и есть возможность позвонить, вы проверяете задачи в контексте “@телефон” и делаете один-два звонка.
Это все реально с todo.txt.
Ваш Todo.txt это обычный текстовый файл. При этом, чтобы вы могли пользоваться всей мощью типа приоритетов, проектов, контекстов, дат создания и завершения, нужно соблюдать всего нескольких правил.
Первое и наиважнейшее правило гласит: одна строка файла todo.txt это одна задача.
Красота формата в том, что он неструктурирован. Вы можете создавать задачи так, как вам хочется.
Только используйте специальную нотацию для проектов (+Проект), контекстов (@Контекст) и приоритетов (А).
Правило 1. Если указан приоритет, то такая задача всегда наверху списка.
Приоритет указывается символами A-Z в верхнем регистре в скобках с обязательным последующим пробелом:
(A) Позвонить маме
К примеру, эти задачи не имеют приоритета:
Обязательно позвонить маме (A) @телефон @потом
(b) Сходить к боссу
(B)->Просмотреть отчет
Правило 2. Дата создания задачи (опциональна) указывается сразу после приоритета с пробелом
Если приоритета нет, то дата создания идет в начале строки в формате ГГГГ-ММ-ДД.
2016-03-02 Документ +TodoTxt формат задач
(A) 2016-03-02 Позвонить маме
Правило 3. Контексты и проекты указываются в любом месте строки, сразу после приоритета и даты создания.
Проекты начинаются со знака “плюс” и не должны содержать пробелов (так: “+МойСуперПроект”). Контексты начинаются со знака @ и также не должны содержать пробелов (пример: “@ПродуктовыйМагазин”).
К примеру, эта задача входит одновременно в проекты +Семья и +МирЛюбовьИСчастье, а также принадлежит контекстам @iphone и @телефон:
(A) Позвонить маме +Семья +МирЛюбовьИСчастье @iphone @телефон
Эта задача не содержит контекста:
Написать SoAndSo на soandso@example.com
А эта не входит ни в один проект:
Выучить как сложить 2+2
Правило 1. Завершенные задачи начинаются с символа x
Если задача начинается с символа x (латиницей с маленькой буквы) с последующим пробелом, то она считается завершенной:
x 2016-03-03 Позвонить маме
Это незавершенные задачи:
xylophone lesson
X 2012-01-01 наложить резолюцию
(A) x найти цены на билеты
мы используем символ “x” чтобы в любом текстовом редакторе автоматическая сортировка отнесла завершенные задачи вниз списка.
Правило 2. Дата завершения идет сразу за символом x после пробела
Пример:
x 2011-03-02 2011-03-01 Рассмотреть pull request Тима +TodoTxtTouch @github
при этом приоритет задачи теряется. Если вы не хотите этого, используйте приоритет так: pri:A
.
Формат todo.txt расширяем и многие утилиты используют свой синтаксис расширений формата ключ:значение
. К примеру, большинство приложений используют расширение due:2017-01-02
как срок выполнения задачи.
Использование: todo.sh [-fhpqvV] [-d ФАЙЛ_КОНФИГ] действие [номер_задачи] [описание_задачи]
Действия:
add "ЧТО Я ДОЛЖЕН СДЕЛАТЬ +проект @контекст"
a "ЧТО Я ДОЛЖЕН СДЕЛАТЬ +проект @контекст"
Добавляет "ЧТО Я ДОЛЖЕН СДЕЛАТЬ" в ваш файл todo.txt.
Проекты и контексты опциональны.
Кавычки опциональны.
addto Имя_Файла "ДОБАВИТЬ ТЕКСТ"
Добавляет строку в любой файл в папке с todo.txt.
К примеру, addto inbox.txt "решение об отпуске"
append НОМЕР "ДОПОЛНИТЬ ТЕКСТ"
app НОМЕР "ДОПОЛНИТЬ ТЕКСТ"
Добавит ДОПОЛНИТЬ ТЕКСТ в конец задачи в строке НОМЕР.
Кавычки опциональны.
archive
Переместит выполненные задачи из файла todo.txt в done.txt и удалит пустые строки.
del НОМЕР [ТЕРМИН]
rm НОМЕР [ТЕРМИН]
Удалит задачу в строке НОМЕР в todo.txt.
Если задан ТЕРМИН, удалится только он в этой строке.
depri НОМЕР
dp НОМЕР
Удалит приоритет у задачи в строке НОМЕР в todo.txt.
do НОМЕР
Пометит задачу в строке НОМЕР как выполненную в todo.txt.
list [ТЕРМИН...]
ls [ТЕРМИН...]
Выведет все задачи, содержащие слово ТЕРМИН, отсортированные по приоритету с
номерами строк. Если ТЕРМИН не задан, выведет все задачи в todo.txt.
listall [ТЕРМИН...]
lsa [ТЕРМИН...]
Выведет все задачи в todo.txt И done.txt, содержащие ТЕРМИН, отсортированные
по приоритету с номерами строк. Если ТЕРМИН не указан, выведет все задачи
в todo.txt И done.txt объединенные и сортированные.
listcon
lsc
Выведет все контексты в todo.txt.
listfile ФАЙЛ [ТЕРМИН...]
lf ФАЙЛ [ТЕРМИН...]
Выведет все строки в файле ФАЙЛ из папки с todo.txt, отсортированные
по приоритету с номерами строк. Если указан ТЕРМИН, выведет все строки,
содержащие ТЕРМИН в файле ФАЙЛ.
listpri [ПРИОРИТЕТ]
lsp [ПРИОРИТЕТ]
Выведет все задачи с приоритетом ПРИОРИТЕТ.
Если не указать ПРИОРИТЕТ, выведет все приоритетные задачи.
listproj
lsprj
Выведет все задачи с проектами (со знаком +) из todo.txt.
move НОМЕР ФАЙЛКУДА [ФАЙЛ]
mv НОМЕР ФАЙЛКУДА [ФАЙЛ]
Переместит строки из файла (ФАЙЛ) в файл (ФАЙЛКУДА).
Оба файла при этом должны находится в одной директории, указанной в
конфигурационном файле. Если ФАЙЛ не указан, то берется todo.txt.
prepend НОМЕР "ДОБАВИТЬ ТЕКСТ"
prep НОМЕР "ДОБАВИТЬ ТЕКСТ"
Добавит ДОБАВИТЬ ТЕКСТ в начало строки НОМЕР.
Кавычки опциональны.
pri НОМЕР ПРИОРИТЕТ
p НОМЕР ПРИОРИТЕТ
Добавит ПРИОРИТЕТ в задачу на строке НОМЕР. Если у задачи уже
указан приоритет, он будет заменен указанным приоритетом ПРИОРИТЕТ.
ПРИОРИТЕТ указывается буквами верхнего регистра от A до Z.
replace НОМЕР "ОБНОВЛЕННАЯ ЗАДАЧА"
Заменит задачу в строке НОМЕР на ОБНОВЛЕННАЯ ЗАДАЧА.
report
Добавит количество незавершенных задач и завершенных в файл report.txt.
Options:
-d ФАЙЛ_КОНФИГ
Будет задействован указанный конфигурационный файл вместо обычного ~/todo.cfg
-f
Выполняет действия без подтверждения или интерактивного ввода
-h
Выводит эту справку
-p
Плоский вид выключает раскраску
-a
Не перемещать задачи в архив автоматически при выполнении
-n
Не сохраняет номера строк; автоматически удаляет пустые строки
при удалении задачи
-v
Детальный режим включает подтверждения для действий
-V
Выводит версию, лицензию и благодарности
Сегодня мы создадим приложение — список задач с Vue.js, а также рассмотрим и другие удобные инструменты для создания современных веб-приложений.
Убедитесь, что у вас установлена Vue CLI! Если нет, то установите её командой
$ npm install --global vue-cli
Читать далее Это перевод поста «How to draw comics when you can’t actually draw.»
Итак, ты не умеешь рисовать, не умеешь в юмор, но всё ещё хочешь создать свой комиксы.
Хорошая новость: для создания комиксов не нужно уметь рисовать или быть смешным.
А вот что нужно:
Читать далее