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

Домашняя бухгалтерия , КУРСОВОЙ ПРОЕКТ

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

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

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

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

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

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

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

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

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

Этап

Продолжительность

1.

Проектирование, разработка эскизного проекта, разработка технического проекта

2,5 месяца

2.

Разработка рабочей документации. Адаптация программ

1 месяц

3.

Ввод в действие

1 месяц

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • JavaEE 7.0

  • Primefaces 5.1

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

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

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

  • 2GB DDR3 Memory

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

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

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

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

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

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

Задача

Время (в часах)

Исследование аналогов системы

4

Составление списка функций

4

Проектирование макета

8

Выбор стратегии разработки проекта

2

Проектирование диаграммы

4

Разработка прототипа

16

Разработка ПО

80

Тестирование ПО, исправление багов

40

Документирование

16

Составление актов сдачи приёмки

6

Суммарно

180

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

В данном случае функции — это маленькие части понимаемых пользователем функций, представленных в виде «<действие> <результат> <объект>», например, «проверка пароля пользователя».

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Функция

Затраченные часы

Итерации

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

4

2

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

2

1

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

2

3

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

24

8

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

16

6

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

16

4

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

4

2

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

4

2

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

8

4

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

4

4

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

4

2

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

8

4

Суммарно

96

42

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

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

  • Среда Eclipse Luna
  • Сервер Wildfly
  • СУБД PostgreSQL

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

Были использованы стандарты кодирования, изложенные в документа Java Code Conventions: #»792254.files/image002.jpg»>

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

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

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

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

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

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

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

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

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

В ходе выполнения курсовой работы были использованы гибкие методологии разработки продукта, язык программирования — 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= «http://java.sun.com/jsf/facelets» xmlns:p= «http://primefaces.org/ui» xmlns:s= «http://java.sun.com/jsf/composite/secretary»>

<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= «http://java.sun.com/jsf/facelets» xmlns:p= «http://primefaces.org/ui» xmlns:s= «http://java.sun.com/jsf/composite/secretary»>

<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= «http://java.sun.com/jsf/facelets» xmlns:s= «http://java.sun.com/jsf/composite/secretary»>

<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= «http://www.w3.org/1999/xhtml» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:p= «http://primefaces.org/ui» xmlns:h= «http://java.sun.com/jsf/html» xmlns:f= «http://java.sun.com/jsf/core» xmlns:a= «http://xmlns.jcp.org/jsf/passthrough» xmlns:s= «http://java.sun.com/jsf/composite/secretary»>

<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= «http://www.w3.org/1999/xhtml» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:p= «http://primefaces.org/ui» xmlns:h= «http://java.sun.com/jsf/html» xmlns:f= «http://java.sun.com/jsf/core» xmlns:a= «http://xmlns.jcp.org/jsf/passthrough» xmlns:s= «http://java.sun.com/jsf/composite/secretary»>

<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= «http://www.w3.org/1999/xhtml» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:h= «http://java.sun.com/jsf/html» xmlns:p= «http://primefaces.org/ui» xmlns:s= «http://java.sun.com/jsf/composite/secretary»>

<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= «http://java.sun.com/jsf/facelets» xmlns:s= «http://java.sun.com/jsf/composite/secretary»>

<ui:define name= «title»>#{i18n.unpaid}</ui:define>

<ui:define name= «body»>

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

</ui:define>

</ui:composition>.xhtml

<html xmlns= «http://www.w3.org/1999/xhtml» xmlns:c= «http://java.sun.com/jsf/composite» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:h= «http://java.sun.com/jsf/html» xmlns:p= «http://primefaces.org/ui» xmlns:f= «http://java.sun.com/jsf/core»>

<c:interface>

<c:attribute name= «backing»/>

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

</c:interface>

<c:implementation>

<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= «http://www.w3.org/1999/xhtml» xmlns:c= «http://java.sun.com/jsf/composite» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:p= «http://primefaces.org/ui» xmlns:f= «http://java.sun.com/jsf/core»>

<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= «http://www.w3.org/1999/xhtml» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:p= «http://primefaces.org/ui» xmlns:h= «http://java.sun.com/jsf/html» xmlns:a= «http://xmlns.jcp.org/jsf/passthrough» xmlns:f= «http://java.sun.com/jsf/core»>

<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= «http://www.w3.org/1999/xhtml» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:p= «http://primefaces.org/ui» xmlns:h= «http://java.sun.com/jsf/html» xmlns:a= «http://xmlns.jcp.org/jsf/passthrough» xmlns:f= «http://java.sun.com/jsf/core»>

<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= «http://www.w3.org/1999/xhtml» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:p= «http://primefaces.org/ui» xmlns:h= «http://java.sun.com/jsf/html» xmlns:a= «http://xmlns.jcp.org/jsf/passthrough» xmlns:f= «http://java.sun.com/jsf/core»>

<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= «http://www.w3.org/1999/xhtml» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:p= «http://primefaces.org/ui» xmlns:h= «http://java.sun.com/jsf/html» xmlns:a= «http://xmlns.jcp.org/jsf/passthrough» xmlns:f= «http://java.sun.com/jsf/core»>

<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» «http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd»>

<html xmlns= «http://www.w3.org/1999/xhtml» xmlns:h= «http://java.sun.com/jsf/html» xmlns:p= «http://primefaces.org/ui» xmlns:ui= «http://java.sun.com/jsf/facelets» xmlns:f= «http://java.sun.com/jsf/core»>

<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= «http://java.sun.com/xml/ns/javaee» xmlns:xsi= «http://www.w3.org/2001/XMLSchema-instance» xsi:schemaLocation= «http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd» version= «3.0»>

<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= «http://xmlns.jcp.org/xml/ns/javaee» xmlns:xsi= «http://www.w3.org/2001/XMLSchema-instance» xsi:schemaLocation= «http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd» version= «2.2»>

<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= «http://java.sun.com/xml/ns/persistence» xmlns:xsi= «http://www.w3.org/2001/XMLSchema-instance» xsi:schemaLocation= «http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd» version= «1.0»>

<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