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


КУРСОВОЙ ПРОЕКТ

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


Введение

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

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

Задачи

Цель «Домашней бухгалтерии» - автоматизировать наши повседневные финансовые расчёты.

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

Система позволит вести учёт не только совершённых финансовых операциях, но и планируемых. Мы можем брать дениги в долг, выплачивать кредиты и т.д. «Домашняя бухгалтерия» позволит нам вести дневник долгов и выплат по ним, рассчитывать, сколько денег осталось выплатить и уведомлять о предстоящих выплатах.

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


1. Планирование разработки проекта


Работы по созданию системы выполняются в три этапа:

ЭтапПродолжительность1.Проектирование, разработка эскизного проекта, разработка технического проекта2,5 месяца2.Разработка рабочей документации. Адаптация программ1 месяц3.Ввод в действие1 месяц

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


. Описание проектирования


Диаграмма вариантов использования


Требования к функциям, выполняемые системой

Программа должна предоставлять следующие возможности:

·Добавлять и изменять записи о совершённых и планируемых денежных поступлениях и расходах

·Добавлять и изменять записи о долгах и устанавливать по ним планы выплат: сколько денег нужно вернуть, до какого числа должен быть выплачен долг и с какой периодичностью будут проводиться выплаты

·Вручную добавлять и изменять записи о выплатах по долгам

·Указывать, к какой категории относится финансовая опрация

·Отображать информацию о текущем состоянии баланса

·Уведомлять пользователя о запланированных действиях

·Строить графики изменения баланса и указывать, в какой момент времени баланс достиг максимального / минимального значения

·Строить графики сравнения моментов времени по сумме финансовых операций и указывать, в какой момент времени сумма финансовых операций была наибольшей / наименьшей

·Строить графики сравнения категорий по сумме финансовых операций и указывать, в какой категории сумма финансовых операций была наибольшей / наименьшей

Исходные данные:

·Данные о денежных поступлениях и расходах пользователя: дата, категория, сумма, комментарий

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

Выходные данные:

·Список сохранённых данных по финансовым операциям пользователя

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

Требования к надёжности

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

Условия эксплуатации

Условия эксплуатации программы совпадают с условиями эксплуатации ПК. Программа должна быть рассчитана на непрофессионального пользователя.

Взаимодействие с другими модулями

Приложение работает с использованием следующих библиотек:

·JavaEE 7.0

·Primefaces 5.1

Требования к составу и параметрам технических средств

·Клавиатура, мышь, дисплей

·Процессор с тактовой частотой от 1 GHz

·2GB DDR3 Memory

Требования к составу и содержанию работ по подготовке объекта автоматизации к вводу системы в действие

В перечень основных мероприятий включают:

·Приведение поступающей в систему информации (в соответствии с требованиями к информационному и лингвистическому обеспечению) к виду, пригодному для обработки с помощью ЭВМ;

·Изменения, которые необходимо осуществить в объекте автоматизации;

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


3. Описание, обоснование выбора процедур процесса конструирования


Календарный план

ЗадачаВремя (в часах)Исследование аналогов системы4Составление списка функций4Проектирование макета8Выбор стратегии разработки проекта2Проектирование диаграммы4Разработка прототипа16Разработка ПО80Тестирование ПО, исправление багов40Документирование16Составление актов сдачи приёмки6Суммарно180

Описание функций:

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

.Авторизация пользователей - проверка истинности введённых логина и пароля пользователя.

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

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

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

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

.График сравнения дней по сумме финансовых операций - рассчитвается сумма всех поступлений / затрат по каждому дню и отображается на графике.

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

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

.Список выплат по долгам - при создании долга в систему добавляются записи по выплатам. На странице списка долгов можно выбрать долг для просмотра и редактирования выплат.

.График сравнения дней по сумме задолженностей - рассчитывается сумма невыплаченных долгов по каждому дню и отображается на графике.

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

Методология

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

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

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

Стратегия

Разработка общей модели

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

Составление списка необходимых функций системы

Информация, собранная при построении общей модели, используется для составления списка функций. Это осуществляется разбиением областей на подобласти (предметные области) с точки зрения функциональности. Каждая отдельная подобласть соответствует какому-либо бизнес-процессу, шаги которого становятся списком функций (свойств). В данном случае функции - это маленькие части понимаемых пользователем функций, представленных в виде «<действие> <результат> <объект>», например, «проверка пароля пользователя».

В данном случае рассмотрим бизнес процессы ведения БД товаров, материалов, списка клиентов, пользователей, поставщиков; журналирование заказов; ведение отчетности и прайс листа. Данные бизнес процессы включают в себя выделенные далее функции.

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

.Список выделенных функций:

.Регистрация пользователей

.Авторизация пользователей

.Смена и восстановление пароля

.Список расходов и поступлений

.Дневник расходов и поступлений

.График изменения баланса

.График сравнения дней по сумме финансовых операций

.График сравнения категорий по сумме финансовых операций

.Список долгов

.Список выплат по долгам

.График сравнения дней по сумме задолженностей

.Интерактивные графики

Планирование работы над каждой функцией

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

Проектирование функции

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

Реализация функции

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


Время, затраченное на реализацию функций

ФункцияЗатраченные часыИтерацииРегистрация пользователей42Авторизация пользователей21Смена и восстановление пароля23Список расходов и поступлений248Дневник расходов и поступлений166График изменения баланса164График сравнения дней по сумме финансовых операций42График сравнения категорий по сумме финансовых операций42Список долгов84Список выплат по долгам44График сравнения дней по сумме задолженностей42Интерактивные графики84Суммарно9642

4. Используемые языки


Используемый язык программирования - Java. Для вёрстки и дизайна веб-страниц были использованы языки XHTML и CSS. Конфигурационные файлы реализованы в формате XML.


. Инструменты


Перечень программ:

·Среда Eclipse Luna

·Сервер Wildfly

·СУБД PostgreSQL

Серверная часть должна работать под управлением систем Linux или Windows. Клиентская часть должна работать под управлением браузеров Mozilla Firefox, Google Chrome или Opera.


. Техника кодирования


Были использованы стандарты кодирования, изложенные в документа Java Code Conventions: #"justify">Используются стандартные библиотеки, модули и пакеты Java, а также набор библиотек Java EE.


. Качество конструирования


Было проведено ручное тестирование каждого модуля системы. Ниже приведён процесс тестирования и результаты.

1. Тестирование модуля регистрации

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

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

При попытке создания пользователя с некорректным email-адресом система выдавала сообщение об ошибке.

2. Тестирование модуля авторизации

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

3. Тестирование модуля восстановления и смены пароля

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

4. Тестирование списка расходов и поступлений

1.Добавление поступления - дата: 9.03.2014 (сегодня), сумма: 1000, категория: «Auto». Платёж успешно добавлен, отображается количество платежей - 1. В вехнем левом углу экрана отображается количество действий, которые нужно выполнить сегодня - 1.

.Добавление расхода - дата: 10.03.2014, сумма: -500, категория: «Home». Расход успешно добавлен, отображается количество платежей - 2.

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

5. Тестирование дневника расходов и поступлений

1.Выполнение действий 4.1 и 4.2. Переход в дневник. Отображается сегодняшняя дата: 9.03.2015. Отображается действие 4.1, баланс: 1000, количество: 1. Смена даты на 10.03.2015. Отображается действие 3.2, баланс: 500, количество: 1.

.Добавление платежа - сумма: -200, категория: «Eat». Платёж успешно добавлен, отображается баланс - 300, количество: 2.

6. Тестирование списка долгов и списка выплат

1.Переход на страницу списка долгов. Добавление долга - дата: 10.03.2015, окончание: 10.03.2016, сумма: 100000, сумма выплаты: 1000, частота выплат: 1 месяц, категория: «Relax». Долг успешно добавлен и отображён в списке, также успешно добавлены и отображены 12 выплат суммой по 1000.

.Удаление долга - после нажатии кнопки удаления долг был успешно удалён.

7. Тестирование графика изменения баланса

Выполнение действий 4.1, 4.2, 5.2. Добавление долга - дата: 10.03.2015, окончание 10.03.2016, сумма: 10000, сумма выплаты: 2000, частота выплат: 1 день, категория: «Auto». На странице графика выбираем диапазон отображается следующая динамика баланса: 800, 10300, 8300, 6300, 4300, 2300.



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

Выполнение действий из пункта 7. Полученный график: 800, 9500, -2000, -2000, -2000, -2000.


9. Тестирование графика сравнения дней по сумме задолженностей

Выполнение действий 7.



. Тестирование графика сравнения категорий по сумме финансовых операций

Выполнение действий 4.1, 4.2, 5.2. Полученный график: 1000, -500, -200.


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


Заключение


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

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

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


Приложение


Код программы


BalanceBacking.java

package ru.ulstu.secretary.chart;

java.util. Date;

javax.faces.view. ViewScoped;javax.inject. Inject;javax.inject. Named;

ru.ulstu.secretary.db. ActionByDateService;


@Named

@ViewScopedclass BalanceBacking extends DateChartBacking {

static final long serialVersionUID = 8470304964338154695L;


@InjectActionByDateService actionByDateService;

double getNextY (double y, Date x) {y + actionByDateService.getList(x).stream().mapToDouble (task -> task.getBalance()).sum();

}


@OverrideString getRedirect() {«diary»;

}

}.csru.ulstu.secretary.chart;

javax.faces.view. ViewScoped;javax.inject. Inject;javax.inject. Named;

ru.ulstu.secretary.db. CategoryService;ru.ulstu.secretary.db. TaskByCategoryService;ru.ulstu.secretary.entity. Category;


@Named

@ViewScopedclass CategoryBalanceBacking extends ChartBacking<Category> {

static final long serialVersionUID = 1L;


@InjectCategoryService categoryService;


@InjectTaskByCategoryService taskByCategoryService;


@OverrideIterable<Category> getRangeOfX() {categoryService.getList();

}


@Overridedouble getNextY (double y, Category x) {taskByCategoryService.getList(x).stream().mapToDouble (task -> task.getBalance()).sum();

}


@OverrideString getRedirect() {«»;

}


@Overridevoid prepareRedirect (Category category) {

}

}.javaru.ulstu.secretary.chart;

java.io. Serializable;

org.primefaces.model.chart. BarChartModel;org.primefaces.model.chart. ChartSeries;

abstract class ChartBacking<X> implements Serializable {

static final long serialVersionUID = 5722395681760535076L;


protected abstract Iterable<X> getRangeOfX();

abstract double getNextY (double y, X x);

BarChartModel getModel() {model = new BarChartModel();series = new ChartSeries();y = 0;(X x: getRangeOfX()) {= getNextY (y, x);.set (x, y);

}.addSeries(series);model;

}

X getMin() {result = null;resultValue = Double.MAX_VALUE;y = 0;(X x: getRangeOfX()) {= getNextY (y, x);(y <= resultValue) {= y;= x;

}

}result;

}


public X getMax() {result = null;resultValue = Double.MIN_VALUE;y = 0;(X x: getRangeOfX()) {= getNextY (y, x);(y >= resultValue) {= y;= x;

}

}result;

}

double getMinValue() {resultValue = Double.MAX_VALUE;y = 0;(X x: getRangeOfX()) {= getNextY (y, x);(y <= resultValue) {= y;

}

}resultValue;

}

double getMaxValue() {resultValue = Double.MIN_VALUE;y = 0;(X x: getRangeOfX()) {= getNextY (y, x);(y >= resultValue) {= y;

}

}(resultValue == Double.MIN_VALUE) {0;

}resultValue;

}

abstract void prepareRedirect (X selected);

abstract String getRedirect();

String redirect (X selected) {(selected);redirect = getRedirect() +»? faces-redirect=true»;redirect;

}

}.javaru.ulstu.secretary.chart;

java.util. Calendar;java.util. Date;java.util. GregorianCalendar;java.util.concurrent. TimeUnit;java.util.stream. IntStream;


import javax.annotation. PostConstruct;javax.inject. Inject;

ru.ulstu.secretary.grid. DateBacking;ru.ulstu.secretary.utils. DateUtil;

abstract class DateChartBacking extends ChartBacking<Date> {

static final long serialVersionUID = -5928036826842490016L;

Date from;

Date to;


@InjectDateBacking dateBacking;


@PostConstructvoid init() {= DateUtil.getToday();= DateUtil.getToday();(-1, 1);

}


@OverrideIterable<Date> getRangeOfX() {dayCount = TimeUnit.DAYS.convert (to.getTime() - from.getTime(), TimeUnit.MILLISECONDS) + 1;() -> IntStream.iterate (0, i -> i + 1).limit(dayCount).mapToObj (i -> {calendar = new GregorianCalendar();.setTime(from);.add (Calendar.DATE, i);calendar.getTime();

}).iterator();

}

Date getFrom() {from;

}

void setFrom (Date from) {.from = from;

}

Date getTo() {to;

}

void setTo (Date to) {.to = to;

}

void change (int left, int right) {calendar = new GregorianCalendar();.setTime(from);.add (Calendar.DATE, left);= calendar.getTime();.setTime(to);.add (Calendar.DATE, right);= calendar.getTime();

}


@Overridevoid prepareRedirect (Date selected) {.setDate(selected);

}

}.javaru.ulstu.secretary.chart;

java.util. Date;

javax.faces.view. ViewScoped;javax.inject. Inject;javax.inject. Named;

ru.ulstu.secretary.db. ActionByDateService;


@Named

@ViewScopedclass DayBacking extends DateChartBacking {

static final long serialVersionUID = 8470304964338154695L;


@InjectActionByDateService actionByDateService;

double getNextY (double y, Date x) {actionByDateService.getList(x).stream().mapToDouble (task -> task.getBalance()).sum();

}


@OverrideString getRedirect() {«diary»;

}

}.javaru.ulstu.secretary.chart;

java.util. Date;

javax.faces.view. ViewScoped;javax.inject. Inject;javax.inject. Named;

ru.ulstu.secretary.db. EntityService;ru.ulstu.secretary.entity. Debt;


@Named

@ViewScopedclass UnpaidBacking extends DateChartBacking {

static final long serialVersionUID = 981680502855109121L;


@InjectEntityService entityService;


@Overridedouble getNextY (double y, Date x) {entityService.getList (Debt.class).stream().mapToDouble (debt -> debt.getUnpaid(x)).sum();

}


@OverrideString getRedirect() {«diary»;

}

}.javaru.ulstu.secretary.criteria;

java.util. Collection;

javax.annotation. PostConstruct;javax.persistence. EntityManager;javax.persistence. PersistenceContext;javax.persistence.criteria. CriteriaBuilder;javax.persistence.criteria. CriteriaQuery;javax.persistence.criteria. Predicate;javax.persistence.criteria. Root;

abstract class CriteriaService<Entity> {


@PersistenceContextEntityManager entityManager;

CriteriaBuilder builder;

CriteriaQuery<Entity> query;Root<Entity> root;


@PostConstructvoid initCriteriaService() {= entityManager.getCriteriaBuilder();= builder.createQuery (getType());= query.from (getType());

}

abstract Class<Entity> getType();

CriteriaBuilder getBuilder() {builder;

}

CriteriaQuery<Entity> getQuery() {query;

}

Root<Entity> getRoot() {root;

}

Collection<Entity> getList (Predicate restriction) {.where(restriction);entityManager.createQuery(query).getResultList();

}

}.javaru.ulstu.secretary.criteria;java.util. Collection;

abstract class PropertyCriteriaService<Entity, Property> extends CriteriaService<Entity> {

Collection<Entity> getList (Property property) {getList (getBuilder().equal (getRoot().get (getProperty()), property));

}

abstract String getProperty();

}.javaru.ulstu.secretary.criteria;

java.util. Collection;

abstract class RangeCriteriaService<Entity, Property extends Comparable<Property>> extends CriteriaService<Entity> {

Collection<Entity> getAll (Property from, Property to) {getList (getBuilder().between (getRoot().get (getProperty()), from, to));

}

abstract String getProperty();

}.javaru.ulstu.secretary.criteria;

java.util. Collection;abstract class UpperLimitCriteriaService<X extends Comparable<X>, Y> extends CriteriaService<Y> {

Collection<Y> getList (X x) {getList (getBuilder().lessThanOrEqualTo (getRoot().get (getProperty()), x));

}

abstract String getProperty();

}.javaru.ulstu.secretary.db;

java.util. Date;

javax.ejb. Stateless;

ru.ulstu.secretary.criteria. PropertyCriteriaService;ru.ulstu.secretary.entity. Action;


@Statelessclass ActionByDateService extends PropertyCriteriaService<Action, Date> {


@OverrideString getProperty() {«date»;

}


@OverrideClass<Action> getType() {Action.class;

}

}.javaru.ulstu.secretary.db;

java.util. Arrays;

javax.ejb. Stateless;javax.inject. Named;

ru.ulstu.secretary.entity. Category;


@Named

@Statelessclass CategoryService {

Iterable<Category> getList() {Arrays.asList (Category.values());

}

}.javaru.ulstu.secretary.db;

java.util. Date;

javax.ejb. Stateless;

ru.ulstu.secretary.criteria. UpperLimitCriteriaService;ru.ulstu.secretary.entity. Debt;


@Statelessclass DebtByDateService extends UpperLimitCriteriaService<Date, Debt> {


@OverrideString getProperty() {«date»;

}


@OverrideClass<Debt> getType() {Debt.class;

}

}.javaru.ulstu.secretary.db;

java.util. Collection;

javax.ejb. Stateless;javax.persistence. EntityManager;javax.persistence. PersistenceContext;javax.persistence.criteria. CriteriaBuilder;javax.persistence.criteria. CriteriaQuery;


@Statelessclass EntityService {


@PersistenceContextEntityManager entityManager;

<T> Collection<T> getList (Class<T> type) {builder = entityManager.getCriteriaBuilder();<T> query = builder.createQuery(type);.from(type);entityManager.createQuery(query).getResultList();

}

<T> T save (T entity) {entityManager.merge(entity);

}

<T> void remove (T entity) {= entityManager.merge(entity);.remove(entity);

}

}.javaru.ulstu.secretary.db;

java.util. Date;

javax.ejb. Stateless;

ru.ulstu.secretary.criteria. PropertyCriteriaService;ru.ulstu.secretary.entity. Pay;


@Statelessclass PayByDateService extends PropertyCriteriaService<Pay, Date> {


@OverrideString getProperty() {«date»;

}


@OverrideClass<Pay> getType() {Pay.class;

}

}.javaru.ulstu.secretary.db;

java.util. Date;

javax.ejb. Stateless;

ru.ulstu.secretary.criteria. PropertyCriteriaService;ru.ulstu.secretary.entity. Repay;


@Statelessclass RepayByDateService extends PropertyCriteriaService<Repay, Date> {


@OverrideString getProperty() {«date»;

}


@OverrideClass<Repay> getType() {Repay.class;

}

}.javaru.ulstu.secretary.db;

javax.ejb. Stateless;

ru.ulstu.secretary.criteria. PropertyCriteriaService;ru.ulstu.secretary.entity. Category;ru.ulstu.secretary.entity. Task;


@Statelessclass TaskByCategoryService extends PropertyCriteriaService<Task, Category> {


@OverrideString getProperty() {«category»;

}


@OverrideClass<Task> getType() {Task.class;

}

}.javaru.ulstu.secretary.db;

java.util. Date;

javax.ejb. Stateless;

ru.ulstu.secretary.criteria. PropertyCriteriaService;ru.ulstu.secretary.entity. Task;


@Statelessclass TaskByDateService extends PropertyCriteriaService<Task, Date> {


@OverrideString getProperty() {«date»;

}


@OverrideClass<Task> getType() {Task.class;

}

}.javaru.ulstu.secretary.db;

javax.ejb. Stateless;javax.inject. Named;


import ru.ulstu.secretary.entity. Unit;


@Named

@Statelessclass UnitService {

Unit[] getList() {Unit.values();

}

}.javaru.ulstu.secretary.entity;

java.util. Date;

javax.persistence. Entity;


@Entityclass Action extends BaseEntity {

Date date;

Double balance;

String comment;

Category category;

boolean complete;

Date getDate() {date;

}

void setDate (Date date) {.date = date;

}

Double getBalance() {balance;

}

void setBalance (Double money) {.balance = money;

}

String getComment() {comment;

}

void setComment (String comment) {.comment = comment;

}

Category getCategory() {category;

}

void setCategory (Category category) {.category = category;

}

boolean isComplete() {complete;

}

void setComplete (boolean complete) {.complete = complete;

}

}.javaru.ulstu.secretary.entity;

javax.persistence. GeneratedValue;javax.persistence. Id;javax.persistence. MappedSuperclass;


@MappedSuperclassclass BaseEntity {


@Id

@GeneratedValueint id;

int getId() {id;

}

void setId (int id) {.id = id;

}

}.javaru.ulstu.secretary.entity;

enum Category {

(«auto»),(«home»);

final String i18n;

Category (String i18n) {.i18n = i18n;

}

String toString() {i18n;

}

}.javaru.ulstu.secretary.entity;

java.util. ArrayList;java.util. Date;java.util. List;

javax.persistence. CascadeType;javax.persistence. Entity;javax.persistence. FetchType;javax.persistence. Inheritance;javax.persistence. InheritanceType;javax.persistence. OneToMany;


@Entity

@Inheritance (strategy = InheritanceType.JOINED)class Debt extends Action {

Date deadline;

Double repay;

Integer frequency;

Unit unit;


@OneToMany (fetch = FetchType.EAGER, cascade = CascadeType.ALL)List<Repay> repays;

Debt() {= Unit.DAY;= new ArrayList<>();

}

Date getDeadline() {deadline;

}

void setDeadline (Date deadline) {.deadline = deadline;

}

Double getRepay() {repay;

}

void setRepay (Double repay) {.repay = repay;

}

Integer getFrequency() {frequency;

}

void setFrequency (Integer frequency) {.frequency = frequency;

}

Unit getUnit() {unit;

}

void setUnit (Unit unit) {.unit = unit;

}

List<Repay> getRepays() {repays;

}


public void setRepays (List<Repay> repays) {.repays = repays;

}

double getUnpaid (Date moment) {(moment.before (getDate())) {0;

}sum = repays.stream().filter (repay ->! repay.getDate().after(moment)).mapToDouble (repay -> repay.getBalance()).sum();Math.max (0, getBalance() + sum);

}

}.javaru.ulstu.secretary.entity;

javax.persistence. Entity;javax.persistence. Inheritance;javax.persistence. InheritanceType;


@Entity

@Inheritance (strategy = InheritanceType.JOINED)class Pay extends Task {}.javaru.ulstu.secretary.entity;

javax.persistence. CascadeType;javax.persistence. Entity;javax.persistence. Inheritance;javax.persistence. InheritanceType;javax.persistence. ManyToOne;


@Entity

@Inheritance (strategy = InheritanceType.JOINED)class Repay extends Task {


@ManyToOne (cascade = CascadeType.ALL)Debt debt;

Debt getDebt() {debt;

}

void setDebt (Debt debt) {.debt = debt;

}

}.javaru.ulstu.secretary.entity;

javax.persistence. Entity;javax.persistence. Inheritance;javax.persistence. InheritanceType;


@Entity

@Inheritance (strategy = InheritanceType.JOINED)class Task extends Action {}.javaru.ulstu.secretary.entity;java.util. Calendar;

enum Unit {

(«year», Calendar.YEAR),(«month», Calendar.MONTH),(«week», Calendar.WEEK_OF_MONTH),(«day», Calendar.DAY_OF_WEEK);

final String i18n;

final int code;

Unit (String i18n, int code) {.i18n = i18n;.code = code;

}

int getCode() {code;

}

String toString() {i18n;

}

}.javaru.ulstu.secretary.grid;

java.io. Serializable;java.util. Date;

javax.annotation. PostConstruct;javax.enterprise.context. SessionScoped;javax.inject. Named;

ru.ulstu.secretary.utils. DateUtil;


@Named

@SessionScopedclass DateBacking implements Serializable {

static final long serialVersionUID = -7664901585738595118L;

Date date;


@PostConstructvoid init() {= DateUtil.getToday();

}

Date getDate() {date;

}

void setDate (Date date) {.date = date;

}

}.javaru.ulstu.secretary.grid;

java.util. Calendar;java.util. GregorianCalendar;

javax.faces.view. ViewScoped;javax.inject. Named;

ru.ulstu.secretary.entity. Debt;ru.ulstu.secretary.entity. Repay;ru.ulstu.secretary.utils. DateUtil;


@Named

@ViewScopedclass DebtBacking extends GridBacking<Debt> {

static final long serialVersionUID = 714120325390373523L;

Debt debt;


@OverrideDebt getNewBlank() {debt = new Debt();.setDate (DateUtil.getToday());debt;

}


@OverrideClass<Debt> getType() {Debt.class;

}


@Overridevoid save() throws Exception {calendar = new GregorianCalendar();.setTime (getBlank().getDate());(true) {.add (getBlank().getUnit().getCode(), 1);(calendar.getTime().after (getBlank().getDeadline())) {;

}repay = new Repay();.setDate (calendar.getTime());.setCategory (getBlank().getCategory());.setBalance (-getBlank().getRepay());().getRepays().add(repay);

}= getBlank();.save();

}

Debt getDebt() {debt;

}

void setDebt (Debt debt) {.debt = debt;

}

}.javaru.ulstu.secretary.grid;

java.util. Collection;

javax.faces.view. ViewScoped;javax.inject. Inject;javax.inject. Named;

ru.ulstu.secretary.db. ActionByDateService;ru.ulstu.secretary.db. PayByDateService;ru.ulstu.secretary.entity. Pay;


@Named

@ViewScopedclass DiaryPayBacking extends GridBacking<Pay> {

static final long serialVersionUID = -3370333139341916306L;


@InjectDateBacking dateBacking;


@InjectActionByDateService actionByDateService;


@InjectPayByDateService payByDateService;


@OverrideClass<Pay> getType() {Pay.class;

}


@OverridePay getNewBlank() {pay = new Pay();.setDate (dateBacking.getDate());pay;

}


@OverrideCollection<Pay> getList() {payByDateService.getList (dateBacking.getDate());

}

double getBalance() {actionByDateService.getList (dateBacking.getDate()).stream().mapToDouble (task -> task.getBalance()).sum();

}

}.javaru.ulstu.secretary.grid;

java.util. Collection;

javax.faces.view. ViewScoped;javax.inject. Inject;javax.inject. Named;

ru.ulstu.secretary.db. RepayByDateService;ru.ulstu.secretary.entity. Repay;

@Named

@ViewScopedclass DiaryRepayBacking extends GridBacking<Repay> {

static final long serialVersionUID = 8966176107954231754L;


@InjectDateBacking dateBacking;


@InjectRepayByDateService repayByDateService;


@OverrideClass<Repay> getType() {Repay.class;

}

Collection<Repay> getList() {repayByDateService.getList (dateBacking.getDate());

}

}.javaru.ulstu.secretary.grid;

java.io. Serializable;java.util. Collection;

javax.annotation. PostConstruct;javax.inject. Inject;


import ru.ulstu.secretary.db. EntityService;

abstract class GridBacking<Entity> implements Serializable {

static final long serialVersionUID = -2639437488394357753L;


@InjectEntityService entityService;

Entity blank;


@PostConstructvoid init() throws Exception {= getNewBlank();

}

abstract Class<Entity> getType();

Entity getNewBlank() throws Exception {getType().getConstructor().newInstance();

}

Collection<Entity> getList() {entityService.getList (getType());

}

Entity getBlank() {blank;

}


public void save() throws Exception {.save(blank);= getNewBlank();

}

void remove (Entity obj) {.remove(obj);

}

}.javaru.ulstu.secretary.grid;

javax.faces.view. ViewScoped;javax.inject. Named;

ru.ulstu.secretary.entity. Pay;static ru.ulstu.secretary.utils. DateUtil.getToday;


@Named

@ViewScopedclass PayBacking extends GridBacking<Pay> {

static final long serialVersionUID = -520158973748994729L;


@OverrideClass<Pay> getType() {Pay.class;

}

Pay getNewBlank() {pay = new Pay();.setDate (getToday());pay;

}

int getCount() {getList().size();

}

double getBalance() {getList().stream().mapToDouble (pay -> pay.getBalance()).sum();

}

}.javaru.ulstu.secretary.grid;

java.util. Collection;

javax.faces.view. ViewScoped;javax.inject. Inject;javax.inject. Named;

ru.ulstu.secretary.entity. Repay;


@Named

@ViewScopedclass RepayBacking extends GridBacking<Repay> {

static final long serialVersionUID = -5042825198701507477L;


@InjectDebtBacking debtBacking;


@OverrideClass<Repay> getType() {Repay.class;

}


@OverrideCollection<Repay> getList() {debtBacking.getDebt() == null? null: debtBacking.getDebt().getRepays();

}

}.javaru.ulstu.secretary.grid;

java.io. Serializable;

javax.faces.view. ViewScoped;javax.inject. Inject;javax.inject. Named;

ru.ulstu.secretary.db. TaskByDateService;ru.ulstu.secretary.utils. DateUtil;


@Named

@ViewScopedclass TodayBacking implements Serializable {


private static final long serialVersionUID = -6983619217861517215L;


@InjectTaskByDateService taskByDateService;

int getCount() {taskByDateService.getList (DateUtil.getToday()).size();

}

}.javaru.ulstu.secretary.utils;

java.util. Calendar;java.util. Date;java.util. GregorianCalendar;

class DateUtil {

static Date getToday() {calendar = new GregorianCalendar();.set (Calendar.HOUR_OF_DAY, 0);.set (Calendar.MINUTE, 0);.set (Calendar.SECOND, 0);.set (Calendar.MILLISECOND, 0);calendar.getTime();

}

}.xhtml

<ui:composition template=»/WEB-INF/tpl/base.xhtml» xmlns:ui= «#"justify"><ui:define name= «title»>#{i18n.balance}</ui:define>

<ui:define name= «body»>

<s:chart backing= "#{balanceBacking}"/>

</ui:define>

</ui:composition>.xhtml

<ui:composition template=»/WEB-INF/tpl/base.xhtml» xmlns:ui= «#"justify"><ui:define name= «title»>#{i18n.category}</ui:define>

<ui:define name= «body»>

<s:chart backing= "#{categoryBalanceBacking}» hasPeriod= «false»/>

</ui:define>

</ui:composition>.xhtml

<ui:composition template=»/WEB-INF/tpl/base.xhtml» xmlns:ui= «#"justify"><ui:define name= «title»>#{i18n.day}</ui:define>

<ui:define name= «body»>

<s:chart backing= "#{dayBacking}"/>

</ui:define>

</ui:composition>.xhtml

<ui:composition template=»/WEB-INF/tpl/base.xhtml» xmlns= «#"justify"><ui:define name= «title»>Debt</ui:define>

<ui:define name= «body»>

<s:grid name= «debt» backing= "#{debtBacking}"/>

<s:grid name= «repay» backing= "#{repayBacking}» editable= «false»/>

</ui:define>

</ui:composition>.xhtml

<ui:composition template=»/WEB-INF/tpl/base.xhtml» xmlns= «#"justify"><ui:define name= «title»>#{i18n.diary}</ui:define>

<ui:define name= «body»>

<div>

<div>

<div>

<div>

<h:inputText styleClass= «form-control» value= "#{dateBacking.date}">

<f:convertDateTime pattern= «yyyy-MM-dd»/>

</h:inputText>

<h:commandButton styleClass= «btn btn-primary» value= "#{i18n.see}"/>

</div>

</div>

</div>

<s:grid name= «diary» backing= "#{diaryPayBacking}"/>

<s:grid name= «repay» backing= "#{diaryRepayBacking}» editable= «false»/>

<div>

<div>

<div>

<p><strong>#{i18n.balance}</strong>: #{diaryPayBacking.balance}</p>

</div>

</div>

</ui:define>

</ui:composition>.xhtml

<ui:composition template=»/WEB-INF/tpl/base.xhtml» xmlns= «#"justify"><ui:define name= «title»>#{i18n.pay}</ui:define>

<ui:define name= «body»>

<s:grid name= «pay» backing= "#{payBacking}"/>

<div>

<div>

<div>

<p><strong>#{i18n.count}</strong>: #{payBacking.count}</p>

</div>

</div>

</ui:define>

</ui:composition>.xhtml

<ui:composition template=»/WEB-INF/tpl/base.xhtml» xmlns:ui= «#"justify"><ui:define name= «title»>#{i18n.unpaid}</ui:define>

<ui:define name= «body»>

<s:chart backing= "#{unpaidBacking}"/>

</ui:define>

</ui:composition>.xhtml

<html xmlns= «#"justify"><c:interface>

<c:attribute name= «backing»/>

<c:attribute name= «hasPeriod» default= «true»/>

</c:interface>

<c:implementation>

<ui:fragment rendered= "#{cc.attrs.hasPeriod}">

<div>

<div>

<div>

<div>

<h:inputText styleClass= «form-control» value= "#{cc.attrs.backing.from}">

<f:convertDateTime pattern= «yyyy-MM-dd»/>

</h:inputText>

<h:inputText styleClass= «form-control» value= "#{cc.attrs.backing.to}">

<f:convertDateTime pattern= «yyyy-MM-dd»/>

</h:inputText>

<p:commandButton styleClass= «btn btn-primary» ajax= «none» value= "#{i18n.see}"/>

</div>

</div>

</div>

</ui:fragment>

<div>

<div>

<div>

<p:chart type= «bar» model= "#{cc.attrs.backing.model}"/>

</div>

</div>

<div>

<div>

<div>

<p><p:commandButton styleClass= «btn btn-primary» action= "#{cc.attrs.backing.redirect (cc.attrs.backing.min)}» value= "#{i18n.see}"/> #{i18n.min}: #{cc.attrs.backing.minValue}</p>

<p><p:commandButton styleClass= «btn btn-primary» action= "#{cc.attrs.backing.redirect (cc.attrs.backing.max)}» value= "#{i18n.see}"/> #{i18n.max}: #{cc.attrs.backing.maxValue}</p>

</div>

</div>

</c:implementation>

</html>.xhtml

<html xmlns= «#"justify"><c:interface>

<c:attribute name= «name»/>

<c:attribute name= «backing»/>

<c:attribute name= «icon» default= «glyphicon glyphicon-th-list»/>

<c:attribute name= «editable» default= «true»/>

</c:interface>

<c:implementation>

<div>

<div>

<p:dataTable tableStyleClass= «table» value= "#{cc.attrs.backing.list}» var= «obj»>

<ui:include src=»/WEB-INF/grid/#{cc.attrs.name}.xhtml»/>

<p:column rendered= "#{cc.attrs.editable}» style= «width: 1%»>

<p:commandButton style= «display: inline-block» value=»» ajax= «none» icon= «glyphicon glyphicon-remove» styleClass= «btn btn-danger» action= "#{cc.attrs.backing.remove(obj)}"/>

<f:facet name= «footer»>

<p:commandButton style= «display: inline-block» value=»» ajax= «none» icon= «glyphicon glyphicon-plus» styleClass= «btn btn-primary» action= "#{cc.attrs.backing.save}"/>

</f:facet>

</p:column>

</p:dataTable>

</div>

</c:implementation>

</html>.xhtml

<ui:composition xmlns= «#"justify"><ui:include src=»/WEB-INF/grid/pay.xhtml»/>

<p:column headerText= "#{i18n.deadline}">

<h:outputText value= "#{obj.deadline}">

<f:convertDateTime pattern= «yyyy-MM-dd»/>

</h:outputText>

<f:facet name= «footer»>

<h:inputText styleClass= «form-control» value= "#{cc.attrs.backing.blank.deadline}» a:placeholder= "#{i18n.deadline}">

<f:convertDateTime pattern= «yyyy-MM-dd»/>

</h:inputText>

</f:facet>

</p:column>

<p:column headerText= "#{i18n.repay}">

#{obj.repay}

<f:facet name= «footer»>

<h:inputText styleClass= «form-control» value= "#{cc.attrs.backing.blank.repay}» a:placeholder= "#{i18n.repay}"/>


</f:facet>

</p:column>

<p:column headerText= "#{i18n.frequency}">

#{obj.frequency}

<f:facet name= «footer»>

<h:inputText styleClass= «form-control» value= "#{cc.attrs.backing.blank.frequency}» a:placeholder= "#{i18n.frequency}"/>

</f:facet>

</p:column>

<p:column headerText= "#{i18n.unit}">

#{i18n [obj.unit]}

<f:facet name= «footer»>

<h:selectOneMenu styleClass= «form-control» value= "#{cc.attrs.backing.blank.unit}">

<f:selectItems value= "#{unitService.list}» var= «unit» itemLabel= "#{i18n[unit]}"/>

</h:selectOneMenu>

</f:facet>

</p:column>

</ui:composition>.xhtml

<ui:composition xmlns= «#"justify"><p:column headerText= "#{i18n.balance}">

#{obj.balance}

<f:facet name= «footer»>

<h:inputText styleClass= «form-control» value= "#{cc.attrs.backing.blank.balance}» a:placeholder= "#{i18n.balance}"/>

</f:facet>

</p:column>

<p:column headerText= "#{i18n.category}">

#{i18n [obj.category]}

<f:facet name= «footer»>

<h:selectOneMenu styleClass= «form-control» value= "#{cc.attrs.backing.blank.category}">

<f:selectItems value= "#{categoryService.list}» var= «category» itemLabel= "#{i18n[category]}"/>

</h:selectOneMenu>

</f:facet>

</p:column>

<p:column headerText= "#{i18n.comment}">

#{obj.comment}

<f:facet name= «footer»>

<h:inputText styleClass= «form-control» value= "#{cc.attrs.backing.blank.comment}» a:placeholder= "#{i18n.comment}"/>

</f:facet>

</p:column>

</ui:composition>.xhtml

<ui:composition xmlns= «#"justify"><p:column headerText= "#{i18n.date}">

<h:outputText value= "#{obj.date}">

<f:convertDateTime pattern= «yyyy-MM-dd»/>

</h:outputText>

<f:facet name= «footer»>

<h:inputText styleClass= «form-control» value= "#{cc.attrs.backing.blank.date}» a:placeholder= "#{i18n.date}">

<f:convertDateTime pattern= «yyyy-MM-dd»/>

</h:inputText>

</f:facet>

</p:column>

<ui:include src=»/WEB-INF/grid/diary.xhtml»/>

</ui:composition>.xhtml

<ui:composition xmlns= «#"justify"><p:column headerText= "#{i18n.date}">

<h:outputText value= "#{obj.date}">

<f:convertDateTime pattern= «yyyy-MM-dd»/>

</h:outputText>

<ui:fragment rendered= "#{cc.attrs.editable}">

<f:facet name= «footer»>

<h:inputText styleClass= «form-control» value= "#{cc.attrs.backing.blank.date}» a:placeholder= "#{i18n.date}">

<f:convertDateTime pattern= «yyyy-MM-dd»/>

</h:inputText>

</f:facet>

</ui:fragment>

</p:column>

<p:column headerText= "#{i18n.balance}">

#{obj.balance}

<ui:fragment rendered= "#{cc.attrs.editable}">

<f:facet name= «footer»>

<h:inputText rendered= "#{cc.attrs.editable}» styleClass= «form-control» value= "#{cc.attrs.backing.blank.balance}» a:placeholder= "#{i18n.balance}"/>

</f:facet>

</ui:fragment>

</p:column>

</ui:composition>.xhtml

<! DOCTYPE html PUBLIC «- //W3C //DTD XHTML 1.0 Strict //EN» «#"justify"><html xmlns= «#"justify"><h:head>

<title>#{i18n.appTitle}</title>

<h:outputScript library= «bootstrap» name= «js/bootstrap.min.js» />

<link rel= «stylesheet» href= "#{request.contextPath}/resources/bootstrap/css/bootstrap.min.css»/>

</h:head>

<h:body>

<div>

<div>

<ul>

<li>

<h:link outcome= «diary» style="#{todayBacking.count > 0? 'color: white; background: #E74C3C': «}»>

<span>

</h:link>

</li>

<li><h:link outcome= «pay»><span>

<li><h:link outcome= «debt»><span>

<li>

<a href= "#»>

<ul>

<li><h:link outcome= «balance»>#{i18n.balance}</h:link></li>

<li><h:link outcome= «day»>#{i18n.day}</h:link></li>

<li><h:link outcome= «unpaid»>#{i18n.unpaid}</h:link></li>

<li><h:link outcome= «category»>#{i18n.category}</h:link></li>

</ul>

</li>

</ul>

</div>

<div>

<h1><ui:insert name= «title»/></h1>

</div>

<h:form>

<p:messages/>

<ui:insert name= «body»/>

</h:form>

</div>

</h:body>

</html>.xml


<web-app xmlns= «#"justify"><servlet>

<servlet-name>Faces Servlet</servlet-name>

<servlet-class>javax.faces.webapp. FacesServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<servlet-mapping>

<servlet-name>Faces Servlet</servlet-name>

<url-pattern>*.xhtml</url-pattern>

</servlet-mapping>

<context-param>

<param-name>primefaces.THEME</param-name>

<param-value>none</param-value>

</context-param>

<context-param>

<param-name>javax.faces.DATETIMECONVERTER_DEFAULT_TIMEZONE_IS_SYSTEM_TIMEZONE</param-name>

<param-value>true</param-value>

</context-param>

</web-app>config.xml

<faces-config xmlns= «#"justify"><application>

<locale-config>

<default-locale>en</default-locale>

</locale-config>

<resource-bundle>

<base-name>ru.ulstu.secretary.i18n</base-name>

<var>i18n</var>

</resource-bundle>

</application>

</faces-config>.xml

<persistence xmlns= «#"justify"><persistence-unit name= «secretaryPU» transaction-type= «JTA»>

<exclude-unlisted-classes>false</exclude-unlisted-classes>

<properties>

<property name= «javax.persistence.jdbc.driver» value= «org.h2. Driver»/>

<property name= «javax.persistence.jdbc.url» value= «jdbc:h2:mem:test»/>

<property name= «javax.persistence.jdbc.user» value= «sa»/>

<property name= «javax.persistence.schema-generation.database.action» value= «create» />

<property name= «hibernate.show_sql» value= «true»/>

</properties>

</persistence-unit>

</persistence>n.properties=Home Secretary

=Pay=Diary=Debt=Repay

=Data=Total

=Date=Sum=Category=Comment=Action=Delete=Complete=Count=Graphic=Day=Deadline=Required=Frequency=Unit=Year=Month=Week=Unpaid

=Add=See

=Auto=Home

=Min=Max


Теги: Домашняя бухгалтерия  Курсовая работа (теория)  Информационное обеспечение, программирование
Просмотров: 1406
Найти в Wikkipedia статьи с фразой: Домашняя бухгалтерия
Назад