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

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

Рубрика Программирование, компьютеры и кибернетика
Вид курсовая работа
Язык русский
Дата добавления 04.04.2015
Размер файла 234,9 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

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

Размещено на http://www.allbest.ru/

Размещено на http://www.allbest.ru/

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

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

Введение

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

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

Задачи

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

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

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

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

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

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

Этап

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

1.

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

2,5 месяца

2.

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

1 месяц

3.

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

1 месяц

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

· JavaEE 7.0

· Primefaces 5.1

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

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

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

· 2GB DDR3 Memory

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

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

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

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

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

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

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

Задача

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

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

4

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

4

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

8

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

2

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

4

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

16

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

80

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

40

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

16

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

6

Суммарно

180

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

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

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

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

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

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

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

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

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

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

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

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

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

Методология

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

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

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

Стратегия

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

После составления списка основных функций, наступает черёд составления плана разработки программного обеспечения. Владение классами распределяется среди программистов путем упорядочивания и организации свойств (или наборов свойств) в классы. Методы и конструкторы проекта (см. Приложение 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

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

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

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

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

· Среда Eclipse Luna

· Сервер Wildfly

· СУБД PostgreSQL

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

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

Были использованы стандарты кодирования, изложенные в документа Java Code Conventions: http://www.oracle.com/technetwork/java/codeconventions-150003.pdf.

Используются стандартные библиотеки, модули и пакеты Java, а также набор библиотек Java EE.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Заключение

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

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

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

Приложение

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

BalanceBacking.java

package ru.ulstu.secretary.chart;

import java.util. Date;

import javax.faces.view. ViewScoped;

import javax.inject. Inject;

import javax.inject. Named;

import ru.ulstu.secretary.db. ActionByDateService;

@Named

@ViewScoped

public class BalanceBacking extends DateChartBacking {

private static final long serialVersionUID = 8470304964338154695L;

@Inject

private ActionByDateService actionByDateService;

protected double getNextY (double y, Date x) {

return y + actionByDateService.getList(x).stream().mapToDouble (task -> task.getBalance()).sum();

}

@Override

protected String getRedirect() {

return «diary»;

}

}

CategoryBalanceBacking.cs

package ru.ulstu.secretary.chart;

import javax.faces.view. ViewScoped;

import javax.inject. Inject;

import javax.inject. Named;

import ru.ulstu.secretary.db. CategoryService;

import ru.ulstu.secretary.db. TaskByCategoryService;

import ru.ulstu.secretary.entity. Category;

@Named

@ViewScoped

public class CategoryBalanceBacking extends ChartBacking<Category> {

private static final long serialVersionUID = 1L;

@Inject

private CategoryService categoryService;

@Inject

private TaskByCategoryService taskByCategoryService;

@Override

protected Iterable<Category> getRangeOfX() {

return categoryService.getList();

}

@Override

protected double getNextY (double y, Category x) {

return taskByCategoryService.getList(x).stream().mapToDouble (task -> task.getBalance()).sum();

}

@Override

protected String getRedirect() {

return «»;

}

@Override

protected void prepareRedirect (Category category) {

}

}

ChartBacking.java

package ru.ulstu.secretary.chart;

import java.io. Serializable;

import org.primefaces.model.chart. BarChartModel;

import org.primefaces.model.chart. ChartSeries;

public abstract class ChartBacking<X> implements Serializable {

private static final long serialVersionUID = 5722395681760535076L;

protected abstract Iterable<X> getRangeOfX();

protected abstract double getNextY (double y, X x);

public BarChartModel getModel() {

BarChartModel model = new BarChartModel();

ChartSeries series = new ChartSeries();

double y = 0;

for (X x: getRangeOfX()) {

y = getNextY (y, x);

series.set (x, y);

}

model.addSeries(series);

return model;

}

public X getMin() {

X result = null;

double resultValue = Double.MAX_VALUE;

double y = 0;

for (X x: getRangeOfX()) {

y = getNextY (y, x);

if (y <= resultValue) {

resultValue = y;

result = x;

}

}

return result;

}

public X getMax() {

X result = null;

double resultValue = Double.MIN_VALUE;

double y = 0;

for (X x: getRangeOfX()) {

y = getNextY (y, x);

if (y >= resultValue) {

resultValue = y;

result = x;

}

}

return result;

}

public double getMinValue() {

double resultValue = Double.MAX_VALUE;

double y = 0;

for (X x: getRangeOfX()) {

y = getNextY (y, x);

if (y <= resultValue) {

resultValue = y;

}

}

return resultValue;

}

public double getMaxValue() {

double resultValue = Double.MIN_VALUE;

double y = 0;

for (X x: getRangeOfX()) {

y = getNextY (y, x);

if (y >= resultValue) {

resultValue = y;

}

}

if (resultValue == Double.MIN_VALUE) {

return 0;

}

return resultValue;

}

protected abstract void prepareRedirect (X selected);

protected abstract String getRedirect();

public String redirect (X selected) {

prepareRedirect(selected);

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

return redirect;

}

}

DateChartBacking.java

package ru.ulstu.secretary.chart;

import java.util. Calendar;

import java.util. Date;

import java.util. GregorianCalendar;

import java.util.concurrent. TimeUnit;

import java.util.stream. IntStream;

import javax.annotation. PostConstruct;

import javax.inject. Inject;

import ru.ulstu.secretary.grid. DateBacking;

import ru.ulstu.secretary.utils. DateUtil;

public abstract class DateChartBacking extends ChartBacking<Date> {

private static final long serialVersionUID = -5928036826842490016L;

private Date from;

private Date to;

@Inject

private DateBacking dateBacking;

@PostConstruct

private void init() {

from = DateUtil.getToday();

to = DateUtil.getToday();

change (-1, 1);

}

@Override

protected Iterable<Date> getRangeOfX() {

long dayCount = TimeUnit.DAYS.convert (to.getTime() - from.getTime(), TimeUnit.MILLISECONDS) + 1;

return () -> IntStream.iterate (0, i -> i + 1).limit(dayCount).mapToObj (i -> {

Calendar calendar = new GregorianCalendar();

calendar.setTime(from);

calendar.add (Calendar.DATE, i);

return calendar.getTime();

}).iterator();

}

public Date getFrom() {

return from;

}

public void setFrom (Date from) {

this.from = from;

}

public Date getTo() {

return to;

}

public void setTo (Date to) {

this.to = to;

}

public void change (int left, int right) {

Calendar calendar = new GregorianCalendar();

calendar.setTime(from);

calendar.add (Calendar.DATE, left);

from = calendar.getTime();

calendar.setTime(to);

calendar.add (Calendar.DATE, right);

to = calendar.getTime();

}

@Override

protected void prepareRedirect (Date selected) {

dateBacking.setDate(selected);

}

}

DayBacking.java

package ru.ulstu.secretary.chart;

import java.util. Date;

import javax.faces.view. ViewScoped;

import javax.inject. Inject;

import javax.inject. Named;

import ru.ulstu.secretary.db. ActionByDateService;

@Named

@ViewScoped

public class DayBacking extends DateChartBacking {

private static final long serialVersionUID = 8470304964338154695L;

@Inject

private ActionByDateService actionByDateService;

protected double getNextY (double y, Date x) {

return actionByDateService.getList(x).stream().mapToDouble (task -> task.getBalance()).sum();

}

@Override

protected String getRedirect() {

return «diary»;

}

}

UnpaidBacking.java

package ru.ulstu.secretary.chart;

import java.util. Date;

import javax.faces.view. ViewScoped;

import javax.inject. Inject;

import javax.inject. Named;

import ru.ulstu.secretary.db. EntityService;

import ru.ulstu.secretary.entity. Debt;

@Named

@ViewScoped

public class UnpaidBacking extends DateChartBacking {

private static final long serialVersionUID = 981680502855109121L;

@Inject

private EntityService entityService;

@Override

protected double getNextY (double y, Date x) {

return entityService.getList (Debt.class).stream().mapToDouble (debt -> debt.getUnpaid(x)).sum();

}

@Override

protected String getRedirect() {

return «diary»;

}

}

CriteriaService.java

package ru.ulstu.secretary.criteria;

import java.util. Collection;

import javax.annotation. PostConstruct;

import javax.persistence. EntityManager;

import javax.persistence. PersistenceContext;

import javax.persistence.criteria. CriteriaBuilder;

import javax.persistence.criteria. CriteriaQuery;

import javax.persistence.criteria. Predicate;

import javax.persistence.criteria. Root;

public abstract class CriteriaService<Entity> {

@PersistenceContext

private EntityManager entityManager;

private CriteriaBuilder builder;

private CriteriaQuery<Entity> query;

private Root<Entity> root;

@PostConstruct

private void initCriteriaService() {

builder = entityManager.getCriteriaBuilder();

query = builder.createQuery (getType());

root = query.from (getType());

}

protected abstract Class<Entity> getType();

protected CriteriaBuilder getBuilder() {

return builder;

}

protected CriteriaQuery<Entity> getQuery() {

return query;

}

protected Root<Entity> getRoot() {

return root;

}

protected Collection<Entity> getList (Predicate restriction) {

query.where(restriction);

return entityManager.createQuery(query).getResultList();

}

}

PropertyCriteriaService.java

package ru.ulstu.secretary.criteria;

import java.util. Collection;

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

public Collection<Entity> getList (Property property) {

return getList (getBuilder().equal (getRoot().get (getProperty()), property));

}

protected abstract String getProperty();

}

RangeCriteriaService.java

package ru.ulstu.secretary.criteria;

import java.util. Collection;

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

public Collection<Entity> getAll (Property from, Property to) {

return getList (getBuilder().between (getRoot().get (getProperty()), from, to));

}

protected abstract String getProperty();

}

UpperLimitCriteriaService.java

package ru.ulstu.secretary.criteria;

import java.util. Collection;

public abstract class UpperLimitCriteriaService<X extends Comparable<X>, Y> extends CriteriaService<Y> {

public Collection<Y> getList (X x) {

return getList (getBuilder().lessThanOrEqualTo (getRoot().get (getProperty()), x));

}

protected abstract String getProperty();

}

ActionByDateService.java

package ru.ulstu.secretary.db;

import java.util. Date;

import javax.ejb. Stateless;

import ru.ulstu.secretary.criteria. PropertyCriteriaService;

import ru.ulstu.secretary.entity. Action;

@Stateless

public class ActionByDateService extends PropertyCriteriaService<Action, Date> {

@Override

protected String getProperty() {

return «date»;

}

@Override

protected Class<Action> getType() {

return Action.class;

}

}

CategoryService.java

package ru.ulstu.secretary.db;

import java.util. Arrays;

import javax.ejb. Stateless;

import javax.inject. Named;

import ru.ulstu.secretary.entity. Category;

@Named

@Stateless

public class CategoryService {

public Iterable<Category> getList() {

return Arrays.asList (Category.values());

}

}

DebtByDateService.java

package ru.ulstu.secretary.db;

import java.util. Date;

import javax.ejb. Stateless;

import ru.ulstu.secretary.criteria. UpperLimitCriteriaService;

import ru.ulstu.secretary.entity. Debt;

@Stateless

public class DebtByDateService extends UpperLimitCriteriaService<Date, Debt> {

@Override

protected String getProperty() {

return «date»;

}

@Override

protected Class<Debt> getType() {

return Debt.class;

}

}

EntityService.java

package ru.ulstu.secretary.db;

import java.util. Collection;

import javax.ejb. Stateless;

import javax.persistence. EntityManager;

import javax.persistence. PersistenceContext;

import javax.persistence.criteria. CriteriaBuilder;

import javax.persistence.criteria. CriteriaQuery;

@Stateless

public class EntityService {

@PersistenceContext

private EntityManager entityManager;

public <T> Collection<T> getList (Class<T> type) {

CriteriaBuilder builder = entityManager.getCriteriaBuilder();

CriteriaQuery<T> query = builder.createQuery(type);

query.from(type);

return entityManager.createQuery(query).getResultList();

}

public <T> T save (T entity) {

return entityManager.merge(entity);

}

public <T> void remove (T entity) {

entity = entityManager.merge(entity);

entityManager.remove(entity);

}

}

PayByDateService.java

package ru.ulstu.secretary.db;

import java.util. Date;

import javax.ejb. Stateless;

import ru.ulstu.secretary.criteria. PropertyCriteriaService;

import ru.ulstu.secretary.entity. Pay;

@Stateless

public class PayByDateService extends PropertyCriteriaService<Pay, Date> {

@Override

protected String getProperty() {

return «date»;

}

@Override

protected Class<Pay> getType() {

return Pay.class;

}

}

RepayByDateService.java

package ru.ulstu.secretary.db;

import java.util. Date;

import javax.ejb. Stateless;

import ru.ulstu.secretary.criteria. PropertyCriteriaService;

import ru.ulstu.secretary.entity. Repay;

@Stateless

public class RepayByDateService extends PropertyCriteriaService<Repay, Date> {

@Override

protected String getProperty() {

return «date»;

}

@Override

protected Class<Repay> getType() {

return Repay.class;

}

}

TaskByCategoryService.java

package ru.ulstu.secretary.db;

import javax.ejb. Stateless;

import ru.ulstu.secretary.criteria. PropertyCriteriaService;

import ru.ulstu.secretary.entity. Category;

import ru.ulstu.secretary.entity. Task;

@Stateless

public class TaskByCategoryService extends PropertyCriteriaService<Task, Category> {

@Override

protected String getProperty() {

return «category»;

}

@Override

protected Class<Task> getType() {

return Task.class;

}

}

TaskByDateService.java

package ru.ulstu.secretary.db;

import java.util. Date;

import javax.ejb. Stateless;

import ru.ulstu.secretary.criteria. PropertyCriteriaService;

import ru.ulstu.secretary.entity. Task;

@Stateless

public class TaskByDateService extends PropertyCriteriaService<Task, Date> {

@Override

protected String getProperty() {

return «date»;

}

@Override

protected Class<Task> getType() {

return Task.class;

}

}

UnitService.java

package ru.ulstu.secretary.db;

import javax.ejb. Stateless;

import javax.inject. Named;

import ru.ulstu.secretary.entity. Unit;

@Named

@Stateless

public class UnitService {

public Unit[] getList() {

return Unit.values();

}

}

Action.java

package ru.ulstu.secretary.entity;

import java.util. Date;

import javax.persistence. Entity;

@Entity

public class Action extends BaseEntity {

private Date date;

private Double balance;

private String comment;

private Category category;

private boolean complete;

public Date getDate() {

return date;

}

public void setDate (Date date) {

this.date = date;

}

public Double getBalance() {

return balance;

}

public void setBalance (Double money) {

this.balance = money;

}

public String getComment() {

return comment;

}

public void setComment (String comment) {

this.comment = comment;

}

public Category getCategory() {

return category;

}

public void setCategory (Category category) {

this.category = category;

}

public boolean isComplete() {

return complete;

}

public void setComplete (boolean complete) {

this.complete = complete;

}

}

BaseEntity.java

package ru.ulstu.secretary.entity;

import javax.persistence. GeneratedValue;

import javax.persistence. Id;

import javax.persistence. MappedSuperclass;

@MappedSuperclass

public class BaseEntity {

@Id

@GeneratedValue

private int id;

public int getId() {

return id;

}

public void setId (int id) {

this.id = id;

}

}

Category.java

package ru.ulstu.secretary.entity;

public enum Category {

AUTO («auto»),

HOME («home»);

private final String i18n;

private Category (String i18n) {

this.i18n = i18n;

}

public String toString() {

return i18n;

}

}

Debt.java

package ru.ulstu.secretary.entity;

import java.util. ArrayList;

import java.util. Date;

import java.util. List;

import javax.persistence. CascadeType;

import javax.persistence. Entity;

import javax.persistence. FetchType;

import javax.persistence. Inheritance;

import javax.persistence. InheritanceType;

import javax.persistence. OneToMany;

@Entity

@Inheritance (strategy = InheritanceType.JOINED)

public class Debt extends Action {

private Date deadline;

private Double repay;

private Integer frequency;

private Unit unit;

@OneToMany (fetch = FetchType.EAGER, cascade = CascadeType.ALL)

private List<Repay> repays;

public Debt() {

unit = Unit.DAY;

repays = new ArrayList<>();

}

public Date getDeadline() {

return deadline;

}

public void setDeadline (Date deadline) {

this.deadline = deadline;

}

public Double getRepay() {

return repay;

}

public void setRepay (Double repay) {

this.repay = repay;

}

public Integer getFrequency() {

return frequency;

}

public void setFrequency (Integer frequency) {

this.frequency = frequency;

}

public Unit getUnit() {

return unit;

}

public void setUnit (Unit unit) {

this.unit = unit;

}

public List<Repay> getRepays() {

return repays;

}

public void setRepays (List<Repay> repays) {

this.repays = repays;

}

public double getUnpaid (Date moment) {

if (moment.before (getDate())) {

return 0;

}

double sum = repays.stream().filter (repay ->! repay.getDate().after(moment)).mapToDouble (repay -> repay.getBalance()).sum();

return Math.max (0, getBalance() + sum);

}

}

Pay.java

package ru.ulstu.secretary.entity;

import javax.persistence. Entity;

import javax.persistence. Inheritance;

import javax.persistence. InheritanceType;

@Entity

@Inheritance (strategy = InheritanceType.JOINED)

public class Pay extends Task {}

Repay.java

package ru.ulstu.secretary.entity;

import javax.persistence. CascadeType;

import javax.persistence. Entity;

import javax.persistence. Inheritance;

import javax.persistence. InheritanceType;

import javax.persistence. ManyToOne;

@Entity

@Inheritance (strategy = InheritanceType.JOINED)

public class Repay extends Task {

@ManyToOne (cascade = CascadeType.ALL)

private Debt debt;

public Debt getDebt() {

return debt;

}

public void setDebt (Debt debt) {

this.debt = debt;

}

}

Task.java

package ru.ulstu.secretary.entity;

import javax.persistence. Entity;

import javax.persistence. Inheritance;

import javax.persistence. InheritanceType;

@Entity

@Inheritance (strategy = InheritanceType.JOINED)

public class Task extends Action {}

Unit.java

package ru.ulstu.secretary.entity;

import java.util. Calendar;

public enum Unit {

YEAR («year», Calendar.YEAR),

MONTH («month», Calendar.MONTH),

WEEK («week», Calendar.WEEK_OF_MONTH),

DAY («day», Calendar.DAY_OF_WEEK);

private final String i18n;

private final int code;

private Unit (String i18n, int code) {

this.i18n = i18n;

this.code = code;

}

public int getCode() {

return code;

}

public String toString() {

return i18n;

}

}

DateBacking.java

package ru.ulstu.secretary.grid;

import java.io. Serializable;

import java.util. Date;

import javax.annotation. PostConstruct;

import javax.enterprise.context. SessionScoped;

import javax.inject. Named;

import ru.ulstu.secretary.utils. DateUtil;

@Named

@SessionScoped

public class DateBacking implements Serializable {

private static final long serialVersionUID = -7664901585738595118L;

private Date date;

@PostConstruct

private void init() {

date = DateUtil.getToday();

}

public Date getDate() {

return date;

}

public void setDate (Date date) {

this.date = date;

}

}

DebtBacking.java

package ru.ulstu.secretary.grid;

import java.util. Calendar;

import java.util. GregorianCalendar;

import javax.faces.view. ViewScoped;

import javax.inject. Named;

import ru.ulstu.secretary.entity. Debt;

import ru.ulstu.secretary.entity. Repay;

import ru.ulstu.secretary.utils. DateUtil;

@Named

@ViewScoped

public class DebtBacking extends GridBacking<Debt> {

private static final long serialVersionUID = 714120325390373523L;

private Debt debt;

@Override

protected Debt getNewBlank() {

Debt debt = new Debt();

debt.setDate (DateUtil.getToday());

return debt;

}

@Override

protected Class<Debt> getType() {

return Debt.class;

}

@Override

public void save() throws Exception {

Calendar calendar = new GregorianCalendar();

calendar.setTime (getBlank().getDate());

while (true) {

calendar.add (getBlank().getUnit().getCode(), 1);

if (calendar.getTime().after (getBlank().getDeadline())) {

break;

}

Repay repay = new Repay();

repay.setDate (calendar.getTime());

repay.setCategory (getBlank().getCategory());

repay.setBalance (-getBlank().getRepay());

getBlank().getRepays().add(repay);

}

debt = getBlank();

super.save();

}

public Debt getDebt() {

return debt;

}

public void setDebt (Debt debt) {

this.debt = debt;

}

}

DiaryPayBacking.java

package ru.ulstu.secretary.grid;

import java.util. Collection;

import javax.faces.view. ViewScoped;

import javax.inject. Inject;

import javax.inject. Named;

import ru.ulstu.secretary.db. ActionByDateService;

import ru.ulstu.secretary.db. PayByDateService;

import ru.ulstu.secretary.entity. Pay;

@Named

@ViewScoped

public class DiaryPayBacking extends GridBacking<Pay> {

private static final long serialVersionUID = -3370333139341916306L;

@Inject

private DateBacking dateBacking;

@Inject

private ActionByDateService actionByDateService;

@Inject

private PayByDateService payByDateService;

@Override

protected Class<Pay> getType() {

return Pay.class;

}

@Override

protected Pay getNewBlank() {

Pay pay = new Pay();

pay.setDate (dateBacking.getDate());

return pay;

}

@Override

public Collection<Pay> getList() {

return payByDateService.getList (dateBacking.getDate());

}

public double getBalance() {

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

}

}

DiaryRepayBacking.java

package ru.ulstu.secretary.grid;

import java.util. Collection;

import javax.faces.view. ViewScoped;

import javax.inject. Inject;

import javax.inject. Named;

import ru.ulstu.secretary.db. RepayByDateService;

import ru.ulstu.secretary.entity. Repay;

@Named

@ViewScoped

public class DiaryRepayBacking extends GridBacking<Repay> {

private static final long serialVersionUID = 8966176107954231754L;

@Inject

private DateBacking dateBacking;

@Inject

private RepayByDateService repayByDateService;

@Override

protected Class<Repay> getType() {

return Repay.class;

}

public Collection<Repay> getList() {

return repayByDateService.getList (dateBacking.getDate());

}

}

GridBacking.java

package ru.ulstu.secretary.grid;

import java.io. Serializable;

import java.util. Collection;

import javax.annotation. PostConstruct;

import javax.inject. Inject;

import ru.ulstu.secretary.db. EntityService;

public abstract class GridBacking<Entity> implements Serializable {

private static final long serialVersionUID = -2639437488394357753L;

@Inject

private EntityService entityService;

private Entity blank;

@PostConstruct

private void init() throws Exception {

blank = getNewBlank();

}

protected abstract Class<Entity> getType();

protected Entity getNewBlank() throws Exception {

return getType().getConstructor().newInstance();

}

public Collection<Entity> getList() {

return entityService.getList (getType());

}

public Entity getBlank() {

return blank;

}

public void save() throws Exception {

entityService.save(blank);

blank = getNewBlank();

}

public void remove (Entity obj) {

entityService.remove(obj);

}

}

PayBacking.java

package ru.ulstu.secretary.grid;

import javax.faces.view. ViewScoped;

import javax.inject. Named;

import ru.ulstu.secretary.entity. Pay;

import static ru.ulstu.secretary.utils. DateUtil.getToday;

@Named

@ViewScoped

public class PayBacking extends GridBacking<Pay> {

private static final long serialVersionUID = -520158973748994729L;

@Override

protected Class<Pay> getType() {

return Pay.class;

}

protected Pay getNewBlank() {

Pay pay = new Pay();

pay.setDate (getToday());

return pay;

}

public int getCount() {

return getList().size();

}

public double getBalance() {

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

}

}

RepayBacking.java

package ru.ulstu.secretary.grid;

import java.util. Collection;

import javax.faces.view. ViewScoped;

import javax.inject. Inject;

import javax.inject. Named;

import ru.ulstu.secretary.entity. Repay;

@Named

@ViewScoped

public class RepayBacking extends GridBacking<Repay> {

private static final long serialVersionUID = -5042825198701507477L;

@Inject

private DebtBacking debtBacking;

@Override

protected Class<Repay> getType() {

return Repay.class;

}

@Override

public Collection<Repay> getList() {

return debtBacking.getDebt() == null? null: debtBacking.getDebt().getRepays();

}

}

TodayBacking.java

package ru.ulstu.secretary.grid;

import java.io. Serializable;

import javax.faces.view. ViewScoped;

import javax.inject. Inject;

import javax.inject. Named;

import ru.ulstu.secretary.db. TaskByDateService;

import ru.ulstu.secretary.utils. DateUtil;

@Named

@ViewScoped

public class TodayBacking implements Serializable {

private static final long serialVersionUID = -6983619217861517215L;

@Inject

private TaskByDateService taskByDateService;

public int getCount() {

return taskByDateService.getList (DateUtil.getToday()).size();

}

}

DateUtil.java

package ru.ulstu.secretary.utils;

import java.util. Calendar;

import java.util. Date;

import java.util. GregorianCalendar;

public class DateUtil {

public static Date getToday() {

Calendar calendar = new GregorianCalendar();

calendar.set (Calendar.HOUR_OF_DAY, 0);

calendar.set (Calendar.MINUTE, 0);

calendar.set (Calendar.SECOND, 0);

calendar.set (Calendar.MILLISECOND, 0);

return calendar.getTime();

}

}

Balance.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>

Category.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>

Day.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>

Debt.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>

Diary.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 class= «panel panel-info»>

<div class= «panel-heading»><span class= «glyphicon glyphicon-calendar»/> #{i18n.date}</div>

<div class= «panel-body»>

<div class= «form-inline»>

<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 class= «panel panel-info»>

<div class= «panel-heading»><span class= «glyphicon glyphicon-ok»/> #{i18n.total}</div>

<div class= «panel-body»>

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

</div>

</div>

</ui:define>

</ui:composition>

Pay.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 class= «panel panel-info»>

<div class= «panel-heading»><span class= «glyphicon glyphicon-ok»/> #{i18n.total}</div>

<div class= «panel-body»>

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

</div>

</div>

</ui:define>

</ui:composition>

Unpaid.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>

Chart.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>

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

<div class= «panel panel-info»>

<div class= «panel-heading»><span class= «glyphicon glyphicon-calendar»/> #{i18n.date}</div>

<div class= «panel-body»>

<div class= «form-inline»>

<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 class= «panel panel-info» style= «overflow: hidden»>

<div class= «panel-heading»><span class= «glyphicon glyphicon-th-list»/> #{i18n.graphics}</div>

<div class= «panel-body»>

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

</div>

</div>

<div class= «panel panel-info»>

<div class= «panel-heading»><span class= «glyphicon glyphicon-ok»/> #{i18n.total}</div>

<div class= «panel-body»>

<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>

Grid.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 class= «panel panel-info»>

<div class= «panel-heading»><span class= "#{cc.attrs.icon}"/> #{i18n [cc.attrs.name]}</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>

Debt.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}">


Подобные документы

  • Устройство соединения сегментов сети. Выбор необходимого программного обеспечения на современном предприятии. Расчет стоимости оборудования. Выбор принтеров для необходимого программного обеспечения. Структура базового технического обеспечения компании.

    презентация [492,4 K], добавлен 02.08.2015

  • Требования к функциям и задачам, выполняемым системой "Подбор кредита ОАО "Россельхозбанк". Проектирование архитектуры программного продукта. Структурная схема программного продукта. Описание компонент программного обеспечения. План менеджмента проекта.

    курсовая работа [684,0 K], добавлен 03.05.2015

  • Исследование объектно-ориентированного подхода к проектированию программного обеспечения будильника. Модель программного обеспечения. Взаимодействие между пользователями и системой. Диаграммы и генерация программного кода при помощи средств Rational Rose.

    курсовая работа [355,8 K], добавлен 26.09.2014

  • Общая характеристика и основные структуры кодирования. Качество программного обеспечения, показатели в ГОСТ 28195 и ГОСТ Р ИСО/МЭК 9126, характеристика по функциональным возможностям. Основные критерии и процесс оценки качества программного обеспечения.

    курсовая работа [219,5 K], добавлен 25.02.2012

  • Создание электронного учебника, написанного на языке гипертекстовой разметки HTML. Характеристика программного обеспечения ЭВМ, необходимого для создания и эксплуатации информационной системы. Алгоритм функционирования системы, отладка программы.

    курсовая работа [1,0 M], добавлен 22.12.2012

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

    дипломная работа [2,7 M], добавлен 18.04.2014

  • Внешний, концептуальный и внутренний уровень архитектуры ANSI/SPARC. Логическая и физическая модель. Основные требования к функциям системы. SQL скрипты, триггеры, последовательности, запросы базы данных "Бухгалтерия (учет материальных ценностей)".

    курсовая работа [1,7 M], добавлен 03.12.2014

  • Обзор предметной области и описание основных понятий в сфере ведения домашней бухгалтерии. Домашняя бухгалтерия Lite 4,4.5.0.2, "Дребеденьги" и прочие аналоги. Архитектура разрабатываемого Web-сайта: описание таблиц в базе данных и работы сайта.

    дипломная работа [3,5 M], добавлен 11.07.2012

  • Основные функции автоматизированной системы "Решатель математических формул". Требования к техническим средствам, информационной и программной совместимости. Стратегии конструирования программного обеспечения. Проектирование, разработка программного кода.

    курсовая работа [600,0 K], добавлен 25.02.2012

  • Характеристика и обоснование выбора технических средств и программного обеспечения: Windows XP, "1C:Бухгалтерия 8", Microsoft Office 2003. Экономическое обоснование расходов на конфигурацию, адаптацию, приобретение аппаратных средств и обучение.

    курсовая работа [32,0 K], добавлен 29.11.2008

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.