Будь ласка, використовуйте цей ідентифікатор, щоб цитувати або посилатися на цей матеріал:
https://er.chdtu.edu.ua/handle/ChSTU/8976| Назва: | Автоматизована система інвентаризації матеріальних цінностей торговельного підприємства |
| Автори: | Чичужко, Марина Володимирівна Ляшевський, Сергій Володимирович |
| Дата публікації: | чер-2022 |
| Короткий огляд (реферат): | У додатку було реалізовано наступні функції: – формування календаря інвентаризацій за кожним типом товарів за кожною торговельною точкою; – перегляд, додавання і редагування типів товарів (з календарем та валідацією) і торгових точок, а також взаємодія між цими сутностями (додання товарів до точок); – формування звіту за результатами інвентаризацій в необхідному вигляді. |
| URI (Уніфікований ідентифікатор ресурсу): | https://er.chdtu.edu.ua/handle/ChSTU/8976 |
| Розташовується у зібраннях: | 174 Автоматизація, комп'ютерно-інтегровані технології та робототехніка (Автоматизація та комп'ютерно-інтегровані системи та компоненти) |
Файли цього матеріалу:
| Файл | Опис | Розмір | Формат | |
|---|---|---|---|---|
| Б_174_2022_Ляшевський.pdf Restricted Access | 1.1 MB | Adobe PDF | Переглянути/Відкрити Запит копії |
Усі матеріали в архіві електронних ресурсів захищено авторським правом, усі права збережено.
Extracted text
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
ЧЕРКАСЬКИЙ ДЕРЖАВНИЙ ТЕХНОЛОІЧНИЙ УНІВЕРСИТЕТ
Факультет інформаційних технологій і систем
Кафедра робототехніки та спеціалізованих комп’ютерних систем
Пояснювальна записка
до кваліфікаційної роботи
освітнього ступеня «бакалавр»
на тему:
АВТОМАТИЗОВАНА СИСТЕМА ІНВЕНТАРИЗАЦЇЇ МАТЕРІАЛЬНИХ
ЦІННОСТЕЙ ТОРГОВЕЛЬНОГО ПІДПРИЄМСТВА
Виконав:студент __4__курсу, групи АКІТС-2099
Спеціальність
151 «Автоматизація та комп'ютерно-інтегровані
технології»
(шифр і назва напряму підготовки)
Студент_________Ляшевський С.В.______________
( прізвище та ініціали)
Керівник _________Чичужко М.В.______________
( прізвище та ініціали)
Рецензент _________Пономар Л.Л.__________
(прізвище та ініціали)
Черкаси 2022 року
ЗМІСТ
СПИСОК СКОРОЧЕНЬ ТА УМОВНИХ ПОЗНАЧЕНЬ ................................. 5
Вступ...................................................................................................................... 6
1 Постановка задачі ............................................................................................. 8
1.1 Опис предметної області ........................................................................... 8
1.2 Опис програм-аналогів ............................................................................ 10
1.3 Постановка завдання ................................................................................ 15
2 Технології і засоби реалізації системи .......................................................... 17
2.1 Мова програмування groovy ................................................................... 17
2.2 Фреймворк grails ...................................................................................... 19
2.3 Середовище розробки Intellij IDEA ....................................................... 23
2.4 СУБД MySQL ........................................................................................... 27
3 Опис розробленої системи ............................................................................. 30
3.1 База даних ................................................................................................. 30
3.2 Структура проекту програми .................................................................. 31
3.3 Опис програми .......................................................................................... 32
3.3.1 Аутентифікація та авторизація користувачів у програмі ............. 35
3.3.2 Формування плану інвентаризацій ................................................. 36
Висновки ............................................................................................................. 40
Список ВИКОРИСТАНИХ ДЖЕРЕЛ .............................................................. 41
ЧДТУ.222084.001 ПЗ
Змн. Лист № докум. Підпис Дата
Розроб. Ляшевський Автоматизована система інвента- Літ. Лист Листів
Перевір. Чичужко ризацїй матеріальних цінностей У 2 72
Реценз. торговельного підприємства
Н. Контр. Пояснювальна записка ЧДТУ, АКІТС-2099
Затверд. Лукашенко
СПИСОК СКОРОЧЕНЬ ТА УМОВНИХ ПОЗНАЧЕНЬ
IDE – Integrated Development Environment
JDK – Java Development Kit
JRE – Java Runtime Environment
RFID Радіочастотна ідентифікація
UI User Interface
URL Uniform Resource Locator
ПЗ – Програмне забезпечення
ОС – Операційна система
ТСД Термінали збору даних
Лист
ЧДТУ. 222084.001 ПЗ
5
Змн. Лист № докум. Підпис Дата
ВСТУП
Економічні інформаційні системи – це людино-машинні системи, які
збирають, накопичують, зберігають, оброблюють і видають за запитом чи
замовленням інформацію у вигляді даних і знань, необхідних для управління
економічним об’єктом.
Сучасні економічні інформаційні системи призначені для обробки великих
обсягів інформації при жорстких обмеженнях на час створення результатів. Вони
мають багаторівневу формалізацію процедур прийняття рішень для більшості
задач, високий ступінь інтеграції елементів, які входять до складу системи,
значну кількість зв’язків між елементами, характеризуються гнучкістю і
здібністю до модифікації.
В економіці роль нервової системи імітують інформаційні потоки.
Порушення в потоках інформації призводять до проблем як в роботі конкретного
підприємства, так і всього господарства, а без достовірної, повної та своєчасної
інформації неможливо управляти будь-яким виробництвом.
В даний час інформаційні системи, що автоматизують виробничу
діяльність, мають критично важливе значення в діяльності будь-якого суб'єкту
господарювання. Складно уявити собі фірму чи підприємство, які не
використовують, наприклад, автоматизованого бухгалтерського чи складського
обліку.
Системи автоматизації економічної діяльності мають достатньо широкий
спектр функцій. Автоматизація складської діяльності є однією з цікавіших сфер
даного програмного забезпечення. Воно має також значну кількість
різноманітних функцій.
Серед найважливіших видів діяльності в галузі складського обліку є
інвентаризація, в рамках якої співставляють наявний на складі чи торгівельному
приміщенні товар з тим, який проходить по документах. В різних програмних
системах є програми підтримки проведення інвентаризації, але вони не завжди
відповідають особливостям потреб користувача.
Лист
ЧДТУ. 222084.001 ПЗ
6
Змн. Лист № докум. Підпис Дата
Серед функцій, які необхідні в автоматизованій системі, що включає
підтримку проведення інвентаризацій, є функція планування інвентаризацій. Її
використання дає можливість зробити процес співставлення задокументованих
та фактичних товарних цінностей системним, унеможливити вплив людського
фактору, звести до мінімуму запізнілі рішення.
Лист
ЧДТУ. 222084.001 ПЗ
7
Змн. Лист № докум. Підпис Дата
1 ПОСТАНОВКА ЗАДАЧІ
1.1 Опис предметної області
В даній бакалаврській кваліфікаційній роботі розглядається питання
створення програмного забезпечення для планування інвентаризацій
матеріальних цінностей на складах та торговельних точках типового
торговельного підприємства як частини автоматизації складського обліку на
цьому підприємстві.
Основними цілями інвентаризації є:
– перевірка правильності інформації поточного обліку та виявлення
припущених помилок;
– відображення пропущених господарських і фінансових операцій;
– контроль за повнотою і правильністю розрахунків за господарськими
договорами та зобов'язаннями, щодо сплати податків і зборів;
– контроль збереження майна;
– перевірка умов і процедури зберігання товарів;
– перевірка стану обліку і організація руху товарних запасів;
– виявлення залежаливших, неходових, застарілих товарів;
– перевірка відповідності принципу матеріальної відповідальності;
– перевірка відображення переліку господарських операцій в документах і
в бухгалтерському обліку тощо.
Необхідність інвентаризації обумовлена низкою причин, важливішими з
яких є:
– виявлення суттєвих помилок в обліку, які можуть призвести до серйозних
матеріальних втрат - штрафам за приховування прибутку тощо;
– зміна фізичних властивостей товарно-матеріальних цінностей. Деякі
матеріальні цінності (наприклад, продукти харчування) в результаті фізичного
убутку змінюють свої фізичні властивості (маса, об'єм тощо) або просто
приходять в непридатність. За допомогою інвентаризації виявляється реальний
стан справ, що відбивається документально;
Лист
ЧДТУ. 222084.001 ПЗ
8
Змн. Лист № докум. Підпис Дата
– недовіру до матеріально відповідальної особи;
– проведення ревізій, аудиторських перевірок;
– крадіжки, зловживання;
– при зміні відповідального при бригадній матеріальної відповідальності;
– стихійні лиха, пожежа, аварія тощо;
– на вимогу судово-слідчих органів.
Кількість інвентаризацій у звітному році, час їх проведення, перелік майна
і фінансових зобов'язань, що перевіряються при кожній з них, встановлюються
керівником організації.
Підприємство, для якого створюється система, працює з значною
номенклатурою товарів, які зберігаються на складах та торговельних точках.
Періодично в кожному з даних місць проводиться інвентаризація відповідно
певної групи товарів. У різних груп товарів відмінна періодичність проведення
інвентаризацій, зокрема є сезонні товари, для яких інвентаризації проводяться
тільки в певний період часу, є святкові товари, для яких інвентаризація може
проводитися раз на рік, а є звичайні товари, для яких інвентаризація проводиться
звичайно через більший чи менший відрізок часу. Крім того, для різних
торговельних точок вона може проводитися в різний час для одного і того ж
товару.
По завершенню кожної інвентаризації відповідальний за неї працівник
складає звіт за формою, зображеною в таблиці 1.1.
Таблиця 1.1 – Таблиця звітності за результатами інвентаризації
Відповідаль- № Артикул Назва Дата за Дата Повинно Фактично
на особа інвентариза- товару товару планом фактична бути є
ційного опису
Для діяльності підприємства важливо, щоб інвентаризації проводилися в
термін. Керівник може аналізувати дані результатів проведених інвентаризацій і
оцінити ефективність діяльності підприємства за деякими критеріями. Власне, за
Лист
ЧДТУ. 222084.001 ПЗ
9
Змн. Лист № докум. Підпис Дата
допомогою автоматизованої системи він може встановити, чи була проведена
потрібна інвентаризація взагалі, таким чином контролюючи трудову дисципліну.
1.2 Опис програм-аналогів
Роздрібна торгівля – «піонер» інвентаризації. При безперервному
розширенні, відкритті і закритті магазинів, необхідності поставок товарів та
обліку залишків на складах не дивно, що саме ритейлери застосовують сучасні
інструменти і технології інвентаризації частіше багатьох інших галузей. Ритейлу
інвентаризація потрібна не просто «для галочки». Роздрібна торгівля – це галузь,
в якій, як правило, документація складається дуже акуратно і грамотно, оскільки
від контролю безпосередньо залежить прибутковість бізнесу. Але скрізь
присутній людський фактор і помилитися або втратити важливий документ при
частій зміні ситуації, відкритті і закритті магазинів, на жаль, не складно. Таким
чином, керівництво торговельних роздрібних компаній часто не має точне
уявлення про те, що з товару у нього є на залишку, при тому, що відомості ці
необхідні.
Ще десятиліття тому інвентаризація була «головним болем» більшості
підприємств, в якій би сфері воно не функціонувало. Раніше інвентаризацію в
роздрібній торгівлі проводили вручну – ревізори ходили по магазину,
розшукуючи заявлені в інвентаризаційного опису предмети і товари, вручну
позначали у себе в списку наявність, робили мітки на меблях, касових апаратах і
іншому майні, створюючи безлад у приміщенні магазину та на складах. Далі ці
дані передавалися бухгалтеру, який, у свою чергу, вручну фіксував їх у себе в
програмі. Інвентаризаційний опис складає величезну кількість найменувань,
тому на проведення інвентаризації «від і до» витрачалося значну кількість часу.
Але за останнє десятиліття технології інвентаризації зробили крок далеко вперед,
і технічно стало простим проводити інвентаризацію великих торгових об'єктів і
складів за лічені години і з мінімумом незручностей для компаній. Багато торгові
компанії досі не володіють технологіями сучасної інвентаризації і навіть не
Лист
ЧДТУ. 222084.001 ПЗ
10
Змн. Лист № докум. Підпис Дата
знають про них, між тим як значна кількість роздрібних мереж вже давно
поставили «блага цивілізації» собі на службу.
Підприємства рітейлу постійно відчувають потребу в двох основних типах
інвентаризації: інвентаризації основних фондів та інвентаризації товарних
запасів. Інвентаризація основних фондів встановлює кількість, склад і стан
торговельного обладнання (такого як касові апарати, маркувальна техніка,
сканери тощо), меблів та оргтехніки (плазмові панелі, вивіски і покажчики,
верстати та інструменти, вантажно-розвантажувальна техніка тощо), автомобілів
та інших товарів, за допомогою яких оформляється і функціонує магазин.
Інвентаризація ж товарних запасів являє собою повний перелік товарів у
торговельному залі та на складі магазину.
Для вирішення проблем, пов'язаних з обліком основних засобів і товарних
запасів, використовується технологія, яка базується на штриховому кодуванні.
Носієм інформації про об'єкти є окрема етикетка з штриховим кодом. В даний
час практично всі товари харчування та багато товарів повсякденного вжитку,
включаючи меблі та побутову техніку, оснащені штрих-кодом. Сучасна
інвентаризація використовує цю особливість, базуючи свої прості методи обліку
на скануванні штрих-кодів. Для збору інформації про прихід, переміщення та
зняття з обліку використовуються термінали збору даних (ТСД) з вбудованим
сканером штрихового коду. Термінал збору даних – пристрій, що поєднує в собі
функцію сканера штрихового коду і здібність обробки даних, отриманих в
результаті розпізнавання штрихового коду. Таке поєднання реалізує можливість
мобільного і автономного збору інформації, її зберігання і обробки.
Здавалося б, не складно просто взяти і перерахувати все. Однак для того,
щоб не заплутатися в типах предметів, відділів та магазинів, необхідно
вибудувати чітку робочу модель інвентаризації, що передбачає всі можливі
варіанти врахування помилок і збоїв. Таким чином, попередня підготовка є
суттєвою частиною успішної інвентаризації. Перед початком інвентаризації
фахівцями-інвентаризаторами попередньо складаються і затверджуються плани
інвентаризації згідно потреб тієї чи іншої компанії і відповідно до стандартів
Лист
ЧДТУ. 222084.001 ПЗ
11
Змн. Лист № докум. Підпис Дата
інвентаризації. Для кожного випадку створюється персональний план організації
та проведення інвентаризації. На основі цього плану компанія потім отримує
максимально точні результати про проведення підрахунку майна. Далі на
підприємство приїжджають фахівці зі спеціальними приладами. Фахівці
спираються на документи, що вказують, що саме вони повинні враховувати і для
чого. Вони проходять по торговому залу і зчитують штрих- коди з товарів, що
потрапляють під інвентаризацію. За підсумками інвентаризації кожен прилад
інвентаризатора містить обсяг точної інформації, яка потім передається на
комп'ютер, де перетворюється в графіки і звичні таблиці формату Excel за
допомогою спеціальних програм.
Інвентаризатор приклеюють штрих-коди, сканують їх і ідентифікують
описаний товар в базі даних. У разі необхідності встановити точну кількість
вагових продуктів, таких як м'ясо, овочі, фрукти тощо, складно, продукція
зважується, упаковується і товарам присвоюється певна номенклатура.
Інвентаризація часто здійснюється в денний час в момент роботи об'єктів
інвентаризації. Налагодженість процесів і технологічна оснащеність
інвентаризаторів дозволяють реалізувати інвентаризацію без відриву від
робочого процесу. У деяких випадках, коли це можливо, інвентаризація
проводиться в нічні або ранкові години до приходу покупців.
Після проведення інвентаризації фахівці вивчають отриману інформацію.
Термінал збору даних синхронізується з базою комп'ютера. Не потрібно ніякої
«ручної роботи», передача даних здійснюється автоматично. Передача даних
може проводитися не тільки за допомогою безпосереднього підключення
терміналу до комп'ютера, а й дистанційно, через Wi-Fi. Ну а готові списки
товарів оперативно в електронному вигляді передаються керівництву .
Основною задачею використання програмного комплексу для
інвентаризації є підвищення ефективності та достовірності обліку та
інвентаризації основних засобів при суттєвому зниженні трудовитрат на їх
проведення і негативного впливу «людського фактору» на результати
інвентаризації. Дані, оброблені в інвентаризаційних програмах, синхронізовані з
Лист
ЧДТУ. 222084.001 ПЗ
12
Змн. Лист № докум. Підпис Дата
усіма діючими бухгалтерськими програмами, в тому числі з 1С, тому бухгалтеру
залишається лише скопіювати дані до себе на комп'ютер і оновити базу. Невірне
оформлення результатів інвентаризації в ході комплексного річного бухобліку
може спричинити за собою серйозні наслідки для компанії. Використання
автоматичного обліку захищає бухгалтера від помилок. Крім того,
інвентаризатор здійснюють лише певну частину своєї роботи, для повного обліку
їм не потрібен допуск до всіх бухгалтерських баз компанії, що гарантує
конфіденційність робіт для кожного клієнта.
На ринку є достатньо програмних продуктів, які працюють в галузі
оперативного обліку та інвентаризації майна та товарів, наприклад, "АйТи-АИ"
[9]. Вона призначена для спрощення обліку товарів:
– наведення порядку – досягнення повної прозорості у галузі обліку майна
(основних засобів, МЗП);
– зниження числа помилок при передачі майна матеріально відповідальним
людям;
– зниження числа помилок при співставленні результатів інвентаризації;
– зниження кількості помилок при списанні матеріальних засобів;
– зниження матеріальних витрат на придбання майна;
– скорочення термінів і спрощення процесу інвентаризації;
– оптимізація взаємодії різних підрозділів підприємства.
Основною технологією є радіочастотна ідентифікація (RFID), також
застосовуються технології штрихового кодування (двовимірне кодування).
Радіочастотна ідентифікація (RFID)-метод автоматичної ідентифікації
(розпізнавання) товарів, при якому за допомогою радіосигналів зчитуються
(записуються) інформація, що зберігаються в RFID-мітках.
Використання RFID надає наступні переваги:
– перезапис інформації на мітці;
– безконтактне зчитування з суттєвої відстані без прямої видимості мітки;
– точна і швидка ідентифікація різних об'єктів обліку одночасно;
– використання міток в поганих умовах зовнішнього середовища;
Лист
ЧДТУ. 222084.001 ПЗ
13
Змн. Лист № докум. Підпис Дата
– використання міток значний період часу (мітки мають практично
необмежений термін служби – до 10 років).
Регулярне проведення інвентаризацій є запорукою збереження майна
підприємств. 1С Підприємство, продукт, який є лідером серед бухгалтерських і
складських програм в Україні, забезпечує ефективну реалізацію інвентаризацій
товарно-матеріальних цінностей на складах, у процесі яких кількість товарно-
матеріальних цінностей на складах співставляється з залишками цінностей за
даними інформаційної бази, з певною корекцією всіх надходжень і вибуття [14].
Для підготовки інвентаризації та реєстрації її результатів в інформаційній базі
розроблено документ "Інвентаризація товарів на складі».
Рисунок 1.1 – Вікно модулю інвентаризації програми "1С Підприємство 8"
Конфігурація підтримує різні способи проведення інвентаризації. Так, для
прискорення роботи до проведення інвентаризації можна автоматично створити
документ "Інвентаризація товарів на складі" відомостями про залишки товарів на
складі, що містяться в інформаційній базі, і потім роздрукувати на носіях типову
форму інв-19 "Порівняльна відомість". При великому розмірі складського
господарства можна сформувати повний комплект документів "Інвентаризація
товарів на складі" – за окремим документом для кожної групи товарно-
матеріальної цінності і місця зберігання – і роздрукувати повний комплект
порівнювальних відомостей. Після цього інвентаризаційної комісії необхідно
провести огляд майна і вручну внести у кінцеву відомість дані про фактичну
наявність цінностей.
Лист
ЧДТУ. 222084.001 ПЗ
14
Змн. Лист № докум. Підпис Дата
Після завершення роботи інвентаризаційної комісії отримані дані про
фактичну наявність товарів вносяться в інформаційну базу шляхом виправлення
або повторного заповнення документа "Інвентаризація товарів на складі". При
виявленні надлишків товарно-матеріальних цінностей необхідно автоматично
сформувати документ оприбуткування цих цінностей, при виявленні недостачі –
документ списання на підставі документа "Інвентаризація товарів на складі".
"1С Підприємство 8" забезпечує автоматичне складання
інвентаризаційного опису та інших документів, необхідних для оформлення
підсумків інвентаризації.
1.3 Постановка завдання
Завданням на бакалаврську роботу є створення веб-програми, яка б дала
можливість реалізувати процес планування проведення інвентаризацій на
торговельному підприємстві.
Послідовність виконання роботи наступна:
1. Аналіз дослідної області, виділення сутностей та їх зв’язків, позначення
проблем.
2. Постановка задачі, формулювання технічного завдання.
3. Розробка та вдосконалення бази даних.
4. Створення структури програмного проекту.
5. Розробка веб-додатку у відповідності з технічним завданням.
6. Тестування роботи додатку на реальних об’єктах.
Вимоги щодо функцій, які необхідно бути реалізовані в програмі:
– формування календаря інвентаризацій за кожним типом товарів за
кожною торговельною точкою;
– перегляд, додавання і редагування видів товарів (з календарем та
валідацією) і торгових точок, а також зв'язки між цими складовими (додання
товарів до точок);
– формування звіту за результатами інвентаризацій в заданому вигляді.
Вимоги щодо інтерфейсу програми:
Лист
ЧДТУ. 222084.001 ПЗ
15
Змн. Лист № докум. Підпис Дата
– програма повинна коректно відображатись на екрані розміром від 13
дюймів;
– програма повинна бути з інтуїтивно зрозумілим інтерфейс;
– меню повинно динамічно змінюватись.
Лист
ЧДТУ. 222084.001 ПЗ
16
Змн. Лист № докум. Підпис Дата
2 ТЕХНОЛОГІЇ І ЗАСОБИ РЕАЛІЗАЦІЇ СИСТЕМИ
2.1 Мова програмування groovy
Groovy – об'єктно-орієнтована мова програмування, створена для
платформи Java як додаток до мови Java з інтеграцією Python, Ruby і Smalltalk.
Groovy дозволяє розробнику реалізувати свої ідеї в короткій і зрозумілій
для нього формі, тому він простий для вивчення і розуміння. Java розробники
високо оцінюють його стандартний синтаксис і абсолютно повну інтеграцію,
вони здібні викликати Java клас з Groovy класу і навпаки.
Groovy побудований на Java-подібному синтаксису з динамічною
компіляцією в JVM байт -код і безпосередньо працює з іншим Java кодом і
бібліотеками. Мова може реалізовуватися в будь-якому Java проекті або як
скриптова мова.
Groovy реалізував процес стандартизації в Java Community Process JSR 241.
Можливості Groovy ( що відрізняють його від Java)[10] :
– вбудований синтаксис для списків, масивів і регулярних виразів,
асоціативних масивів;
– статична і динамічна типізація;
– замикання;
– перевантаження операцій.
Першою згадкою про мову Groovy було в написі в блозі Джеймса Стречі
(англ. James Strachan (programmer)) [12] від серпня 2003 року. Через деякий час
було випущено кілька версій між 2004 і 2006 роками. Після початку процесу
стандартизації JCP, нумерація версій була модифікована, і версію називають
«1.0». Версія «1.0» була реалізована 2 січня 2007 року. У грудні 2007 року
вийшов Groovy 1.1, ця версія зразу була перенумерована як «1.5» внаслідок
значних змін у мові.
Стречі залишив проект за рік до релізу Groovy 1.0 в 2007 році, а в липні
2009 року Стречі повідомив у своєму блозі, що можливо не створив би Groovy,
Лист
ЧДТУ. 222084.001 ПЗ
17
Змн. Лист № докум. Підпис Дата
якби в 2003 році вивчив книгу Мартіна Одерського з співавторами про
програмування на мові Scala (що вийшла в 2007) [13] .
Проект розробки мови і комітет JSR-241 з 2007 року працює під
керівництвом Гійом Лафорж.
На відміну від Java, в Groovy вихідний код може бути написаний як
звичайний скрипт, якщо містить код за межами визначення класу або клас з
методом main або Runnable або GroovyTestCase. Groovy має ще цілий набір
відмінностей від Java. Рядки в Groovy бувають Java Strings з одинарними
лапками і GStrings з подвійними лапками, наприклад:
def javaStyleString = 'java String style'
def GStringsStyleString = "${javaStyleString}"
def j = '${javaStyleString}'
def bigGroovyString = """
${javaStyleString}
${GStringsStyleString}
"""
println bigGroovyString
Groovy неявно генерує методи для доступу до змінних (setColor (String
color) і getColor ()):
class AGroovyBean {
String color
}
def myGroovyBean = new AGroovyBean()
myGroovyBean.setColor('blue')
assert myGroovyBean.getColor() == 'blue'
myGroovyBean.color = 'green'
assert myGroovyBean.color == 'green'
Groovy пропонує простий і послідовний доступ до списків, мепів і масивів:
def myList = ['One', 'Two', 'Three']
assert myList[2] == 'Three'
Лист
ЧДТУ. 222084.001 ПЗ
18
Змн. Лист № докум. Підпис Дата
myList[3] = 'Four'
assert myList.size() == 4
def monthMap = [ 'January' : 31, 'February' : 28, 'March' : 31 ]
assert monthMap['March'] == 31
monthMap['April'] = 30
assert monthMap.size() == 4
return у функції наводити не обов'язково – за замовчуванням буде
повернуто значення останньої наведеної змінної.
Groovy може застосовуватися в Web-додатках Spring, Hibernate і JPA через
фреймворк Grails, прилаштовуючи зовнішню бізнес-логіку, мови предметної
області (Domain-Specific Languages) і багато різного, щоб полегшити розробку.
2.2 Фреймворк grails
Grails – програмний каркас для реалізації веб-додатків, написаний на
скриптовій мові Groovy, який у свою чергу побудований на Java. Grails
створений під значним впливом широко відомого Ruby on Rails і реалізований на
шаблоні «Модель-представлення-контролер» (MVC). Grails був створений з
метою створити інтерес користувачів до платформи Java і дати Java-розробникам
можливості для простої побудови веб-додатків з легкістю і гнучкістю, яка була
недоступна раніше.
Розробка продукту ведеться з липня 2005. Перший реліз 0.1 з’явився в
березні 2006 р.
Grails розробляється з наступними цілями :
– сумісність з відомими технологіями Java , такими як Hibernate і Spring ;
– надати швидкий програмний каркас для веб -розробки для платформи
Java;
– запропонувати несуперечливий, одноманітний каркас, що дозволить
уникнути невизначеності і буде легким до вивчення;
– документувати тільки ті частини фреймворка, які важливі для
користувачів;
Лист
ЧДТУ. 222084.001 ПЗ
19
Змн. Лист № докум. Підпис Дата
– надати приклади додатків, які реалізують можливості даного
програмного каркаса;
– запропонувати користувачам те , що вони бажають бачити в областях
часто складних і суперечливих: потужна і безкомпромісна підтримка
персистенції (збереження даних), динамічні бібліотеки тегів для легкої побудови
компонентів веб-сторінок, потужні і легкі у роботі шаблони сторінок (view), які
використовують GSP (Groovy Server Pages); повна підтримка Ajax, легко
розширюється і настроюється під цілі розробника Grails - Ajax (бібліотеки:
jQuery (за замовчуванням), Rico, Prototype, Dojo і YUI - за допомогою плагінів);
– забезпечити процедуру розробки, що включає вбудований веб-сервер і
напівавтоматичне перевантаження ресурсів.
У Grails три характеристики суттєво підвищують продуктивність
розробника в порівнянні з класичною Java веб-розробкою:
– готовий до використання простір розробки;
– відсутність XML конфігурацій;
– функціональність, створена завдяки використанню домішок (mixins).
Grails – досить сучасний фреймоворк, в галузі промислового
програмування, який не дуже сильно поширився, на відміну від Java-based
фреймворків.
Grails – це Web фреймворк з відкритим вихідним кодом, який дозволяє
підвищити продуктивність розробки Web додатків. Grails перетворює ідею на
реальність, за рахунок конвенцій і стандартних налаштувань він надає готовий
фундамент, який вимагає мінімальної кастомізації з боку програміста.
Розробка реалізується за допомогою мови Groovy.
В основі Grails лежить стандартний шаблон - MVC, так що вам не важко
почати розробку. Архітектура фреймворка зображена на рисунку 2.1.
Grails – дітище Spring Source, і в його будові лежать деякі компоненти цієї
компанії, які розроблені на Java (центральний компонент на рисунку, це Spring) .
Можна відмітити, що весь код, написаний на Groove транслюється в Java і
запускається в рамках віртуальної машини (Java Virtual Machine), в якості
Лист
ЧДТУ. 222084.001 ПЗ
20
Змн. Лист № докум. Підпис Дата
провайдера персистентності і БД замовчуванням використовується зв'язка
Hibernate + HSQLDB.
Рисунок 2.1 – Архітектура фреймворка Grails
Модель (Domains) – класи, що знаходяться в директорії domains, описуючі
Java мовою – всі класи мають анотацію @Entity і відображаються в БД.
Контролер (Controllers) – взаємодіє з Spring службами, а також керує
роботу доменної області і представлень.
Представлення (GSPs) - Groovy Server Pages, аналог JSP з підтримкою тегів
Ruby on Rails.
До сильних сторін Grails можна віднести:
1) Convention over configuration. Це дуже значний бонус Grails. Коли
відкрити не свій проект, то можна знати, що де знаходиться, як запускається і як
працює. До того ж, код виглядає зрозуміліше і не захаращений зайвими
анотаціями, наприклад.
2) Плагіни. Другий величезний бонус Grails. Багато вже було розібрано
раніше. Часто потрібно всього лише обрати правильний плагін. Потрібні
надсилання на пошту? Будь ласка. Компіляція less? Є таке. Керування
статичними ресурсами? NoSQL? Безпека? ...
Лист
ЧДТУ. 222084.001 ПЗ
21
Змн. Лист № докум. Підпис Дата
3) Auto reloading ( grails run - app) . Часто (але не завжди! ) немає
необхідності перезапускати програму, щоб протестувати зміни. Просто потрібно
писати, f5 і працює. Звичайно, іноді auto reloading не працює, часто глючить, але
все-одно це значний time saver.
4) Groovy. Groovy добра і потужна мова. Віна дозволяє писати чіткий,
читабельний і красивий код. Звичайно, тут необхідно слідувати точним угодам,
щоб не перетворити проект в макаронну фабрику. Можливо, цей пункт зникне з
виходом нової Java, але поки це величезний плюс.
Grails – це майже фреймворк для побудови Web додатків. Але історично
так склалося, що частина функцій Grails скоріше можна співставити з якою-
небудь системою збірки, а не до Web фреймворку. Grails:
– створює вихідні коди в war файл (grails war);
– управляє залежностями (використовуючи Ivy або Maven, починаючи з
версії 2.3);
– навіть може запустити зібраний war у внутрішньому контейнері (grails
run - war).
Проблеми починаються, коли ви бажаєте використовувати Grails проект з
повноцінною системою складання. Офіційна підтримка Maven'а таки є. Але зараз
Maven морально застаріває. Зараз частіше намагаються збирати проекти,
використовуючи Gradle.
Існують два Gradle плагіна, які дозволяють це робити - grails-gradle-plugin і
gradle-grails-wrapper. Розглянемо, що між ними спільного і що їх відрізняє.
1) Обидва плагіна використовують команди grails-* для складання Grails
проекту.
2) Насправді збірка все так же реалізується за допомогою Grails -
наприклад, команда gradle grails - war застосовує складальник, використовуваний
командою grails war.
3) Обидва плагіна не потребують встановленого на комп'ютері Grails - для
складання проекту необхідний тільки Gradle.
Лист
ЧДТУ. 222084.001 ПЗ
22
Змн. Лист № докум. Підпис Дата
4) Основна відмінність в плагінах - плагін gradle - grails - wrapper
застосовує Grails для управління залежностями. Це має свої переваги і недоліки.
Наприклад, в цьому випадку вам не має необхідності переносити залежності з
BuildConfig.groovy, але у все так же залишаються складнощі зі SNAPSHOT
залежностями і не буде підтримки багатомодульної збірки в Gradle (project
залежності). Плагін grails - gradle - plugin , навпаки, використовує Gradle для
керування залежностями. Таким чином, необхідно перенести всі залежності з
BuildConfig.groovy в файл build.gradle.
gradle - grails - wrapper простий. Все що робить плагін - створює
необхідний Grails для збірки і збирає проект, використовуючи код Grails'а.
Слідство з попереднього пункту - у вас точно не виникне проблем при
складанні. Якщо ваш проект збирається Grails'ом, то він точно буде зібраний і
Gradle'ом. Поки ми намагалися інтегрувати grails - gradle - plugin в наш проект, у
нас було багато проблем, в основному за помилкової роботи з Logback плагіном.
Можна як і раніше створювати проекти, використовуючи Grails. Це дуже
зручно в процесі розробки, тому що IDE точно знає як працювати з звичайним
Grails проектом, а от Grails проект , в якому безпосередньо управляються через
Gradle їй зовсім незрозумілий.
2.3 Середовище розробки Intellij IDEA
IntelliJ IDEA – комерційний інтегрований додаток для розробки для Java
від компанії JetBrains. Система поставляється у пакеті урізаної по
функціональності безплатної версії "Community Edition" і повнофункціональної
комерційної версії "Ultimate Edition", для якої провідні розробники відкритих
проектів мають можливість отримати безплатну ліцензію. Сирцеві тексти
Community-версії поширюються в межах ліцензії Apache 2.0. Бінарні релізи
підготовлені для Linux, Mac OS X і Windows [11].
Перша версія IntelliJ IDEA з'явилася у січні 2001 року й зразу здобула
популярність, як перша Java IDE із достатнім набором інтегрованих інструментів
для рефакторингу, це давало можливість програмістам швидко реорганізовувати
Лист
ЧДТУ. 222084.001 ПЗ
23
Змн. Лист № докум. Підпис Дата
сирцевий код програм. Дизайн додатку орієнтовано на продуктивність роботи
програмістів, дозволяючи їм сконцентруватися на створенні функціональності,
тоді як IntelliJ IDEA бере на себе виконання простих операцій.
Починаючи з шостої версії продукту IntelliJ IDEA має інтегрований
інструментарій для створення графічного користувацького інтерфейсу.
З версії 9.0 є безплатна версія Community Edition з відкритими кодами.
Сирцеві коди відкритої версії IntelliJ IDEA Community Edition існують в рамках
ліцензії Apache 2.0. Бінарні пакунки підготовлені для Linux, Mac OS X і
Windows.
До складу IntelliJ IDEA включені розробки, створені в результаті спільної
роботи з компанією Google, яка використовувала IntelliJ IDEA в якості основи
для свого нового відкритого середовища розробки Android Studio. Завдяки
співпраці значно розширені штатні можливості IntelliJ IDEA з розробки
застосунків для платформи Android.
Community версія продукту IntelliJ IDEA підтримує інструменти для
проведення тестування TestNG і JUnit, процедур контролю версій CVS,
Subversion, Mercurial і Git, засоби складання Maven і Ant, мови програмування
Java, Java ME, Scala, Clojure і Groovy. Підтримується розробка продуктів для
мобільної платформи Android. До складу входить додаток візуального
проектування GUI-інтерфейсу Swing UI Designer, XML-редактор, редактор
регулярних виразів, система відповідності коректності коду, система перевірки
за виконанням завдань і додаток для імпорту та експорту проектів з Eclipse.
Доступні продукти інтеграції з системами відстеження помилокJIRA, Trac,
Redmine, Pivotal Tracker, GitHub, YouTrack, Lighthouse.
Комерційна версія "Ultimate Edition" відрізняється присутністю підтримки
додаткових мов програмування (наприклад, PHP, Ruby, Python, JavaScript,
CoffeeScript, HTML, CSS, SQL), підтримкою технологій Java EE, UML-діаграм,
визначення покриття коду, адаптацією роботи з фреймворками (Rails, Grails,
Google Web Toolkit, Spring, Play Java Web framework і Hibernate), способами
інтеграції з Perforce, Microsoft Team Foundation Server і Rational ClearCase.
Лист
ЧДТУ. 222084.001 ПЗ
24
Змн. Лист № докум. Підпис Дата
В проекті використовувалась Intellij IDEA свіжої версії 13, яка включає
немало нових функцій:
– підтримана Java EE 7, остання версія корпоративної платформи Oracle,
додана підтримка віжих версій серверів додатків: Glassfish 4, Wildfly 8, Tomcat 8
та інших. Крім цього, в IDE нтегрована допомога у створенні коду для CDI 1.1,
JSF 2.2, JAX -RS 2.0 і для batch processing'a.
– розробники, що використовують Spring, зитивно оцінюють
удосконалення, внесеними до складу цієї технології: IDE автоматично виявляє
unmapped contexts, встановлені за допомогою @Configuration, і пропонує
інтегрувати їх в налаштування проекту, нова закладка MVC в Spring tool window
допомагає простіше проводити навігацію між способами контролера в проекті, в
ній же можна подивитися необхідні mapped URL, method і path variables, а вікно
Spring Beans tool дозволяє реалізувати навігацію між бінамі, встановити зв'язок
між ними і документацію по бінам. Крім цього, в новій версії IntelliJ IDEA
вдосконалено продуктивність при роботі з проектами з великою кількістю бінів;
– внесено багато удосконалень для розробників під Android, в тому числі
вдосконалено редактор коду і дизайнер графічного інтерфейсу додатків, а також
суттєво полегшену роботу з БД SQLite;
– перероблена підтримка Gradle: в першу чергу, додано автодоповнення
для залежностей і плагінів, генерація коду. З'явилися спливаючі підказки Quick
Documentation для Gradle DSL, IntelliJ IDEA тепер автоматично будує web facet
та імпортує конфігурації артефактів WAR. Крім того, реалізується налагодження
завдань Gradle, наприклад, test і exec, а завдяки Gradle 1.8 прискорений імпорт
проектів Gradle;
– вдосконалено інтерфейс користувача: тепер за замовчуванням IDE
приховує основний toolbar і кнопки tool window . Додано вдосконалений світлий
look and feel, який доступний для Windows і Linux, як для Community Edition, так
і для Ultimate, причому для Community Edition він буде працювати за
замовчуванням, а під Linux він буде за замовчуванням і для Ultimate. Додані і
інші зручні фішки, наприклад, функція Search everywhere;
Лист
ЧДТУ. 222084.001 ПЗ
25
Змн. Лист № докум. Підпис Дата
– змінено плагін Database Support : став простіше інтерфейс налаштування
зв'язку з БД, з'явилися Structure View, навігація і вигляд для foreign і primary keys
в редакторі таблиць. У підтримці роботи з БД зроблені і багато суттєвих
покращень, серед яких варто відзначити query filter. З його допомогою можна
відфільтрувати обрані дані при перегляді таблиці або в результатах SQL-запиту,
а за функцією сортування за стовпчиками можна налащтувати таблицю прямо в
IDE, не відправляючи жних запитів базі даних;
– поліпшено інструменти роботи з Git, Mercurial і Subversion (а саме
підтримку Subversion 1.8), відладчик, підтримка Groovy , Scala (і інтеграція з
SBT), вдосконалені інструменти для веб-розробника, підтримка CloudFoundry
2.0, OpenShift і Heroku.
IDEA підтримує швидке кодування. IntelliJ IDEA орієнтована на зростання
продуктивності, формуючі найрозумніші підказки в розробці коду, позбавляє
програміста від класичної рутини і економить час, забезпечуючи:
- – розширений і надійний рефакторинг;
- чутливе до контексту і вибору типу автозавершення;
– живі шаблони;
– глибока навігація.
Статичний аналіз коду реалізується IntelliJ IDEA на льоту. У середовищі
IDEA виявляє помилки в коді при введенні і одразу пропонує миттєво
виправити:
– загальні профілі інспекції;
– побажання і швидкі рішення;
– аналіз коду на льоту;
– користувальницькі інспекції.
IntelliJ IDEA включає сучасний набір інструментів, які працюють з ходу і
роблять розробку більш продуктивною:
– VCS інструменти з Git, GitHub, SVN та інші;
– підтримка Maven, Gradle, Gant і Ant;
– Groovy конвертер Java;
Лист
ЧДТУ. 222084.001 ПЗ
26
Змн. Лист № докум. Підпис Дата
– модульне тестування і застосування інструментів з підтримкою JUnit,
TestNG, Spock і Cucumber;
– вбудована Groovy оболонка.
Для розробки діючих корпоративних додатків IntelliJ IDEA – це кращий
вибір завдяки його повній підтримці передових веб фреймворків та інструментів
баз даних:
– HTML5, JavaScript, CoffeeScript, CSS3, LESS тощо;
– підтримка Grails, Griffon і Spring Framework;
– інструменти для баз даних та підтримка SQL.
2.4 СУБД MySQL
MySQL – система управління реляційними базами даних з відкритим
вихідним кодом. Поширюється під ліцензією GPL, що дозволяє застосовувати її
(без змін) в некомерційних цілях без згодження з розробниками. Розроблена
фірмою MySQL AB, що з 2008 року рацює в складі Sun Microsystems. Розробка
ведеться з 1995 року. Підтримує значну кількість функцій стандарту ANSI
SQL:99 [15].
MySQL — простий багатонитковий сервер баз даних. Характеризується
стабільною швидкістю, стійкістю і простотою використання.
MySQL вважається чудовим рішенням для малих і середніх розробок.
Початкові коди сервера компілюються на майже всіх платформах. Найповніше
можливості сервера розкриваються в UNIX-системах, де є підтримка
багатонитковості, що покращує продуктивність системи в цілому.
До переваг MySQL відносять:
– MySQL – безкоштовна СУБД, що відрізняє її від інших комерційних
продуктів;
– багатопоточність: підтримка декількох одночасних запитів;
– записи фіксованої і змінної довжини;
– оптимізація зв'язків з приєднанням багатьох даних за один прохід;
– ODBC драйвер в комплекті з вихідним кодом;
Лист
ЧДТУ. 222084.001 ПЗ
27
Змн. Лист № докум. Підпис Дата
– до 16 ключів в таблиці , кожен ключ може мати до 15 полів;
– гнучка система привілеїв і паролів;
– підтримка чисел довжиною від 1 до 4 байт (ints, float, double, fixed),
рядків змінної довжини і міток часу;
– підтримка ключових полів і спеціальних полів в операторові CREATE ;
– інтерфейс з мовами C і Perl;
– заснована на потоках, швидка система пам'яті;
– псевдоніми застосовні як до таблиць, так і до окремих колонкам в
таблиці;
– всі дані зберігаються у форматі ISO8859_1;
– утиліта перевірки і ремонту таблиці (isamchk) ;
– всі операції роботи з рядками не звертають уваги на регістр символів в
оброблюваних рядках ;
– всі поля мають значення за замовчуванням. INSERT можна
використовувати на будь-якому підмножині полів;
– легкість управління таблицею, включаючи додавання і видалення ключів
і полів.
В MySQL реалізується декілька основних механізмів зберігання.
MyISAM – історично перший движок MySQL. Працює за замовчуванням
до версії 5.5. В основі механізму розширений і вдосконалений спосіб зберігання
даних за допомогою індексно-послідовного доступу ISAM. У MyISAM для
кожної таблиці існує окремий файл, а пошук запису реалізується за окремими
індексним таблицями, що має маленький розмір. При застосуванні цього
механізму зберігання під час запису, на відміну від читання, необхідно
блокувати всю таблицю. Тому таблиці MyISAM чудово підходять для
використання в WWW та інших середовищах, де присутні запити на читання.
InnoDB – входить до складу MYSQL починаючи з версії 3.23 і є
результатом розробок проведених в університеті Гельсінкі співробітником
фінської компанії Innobase. Дані в цьому додатку розташовані у великих файлах
з спільним доступом. Підтримується механізм транзакцій і блокування даних на
Лист
ЧДТУ. 222084.001 ПЗ
28
Змн. Лист № докум. Підпис Дата
рівні рядка, що дозволяє проводити декілька паралельних операцій
читання/запису над однією таблицею. Використовується за замовчуванням
починаючи з версії 5.5.
Falcon – власний проект Sun. Створювався як альтернатива InnoDB. В
даний час існує лише на стадії альфа тестування і вдосконалюватись надалі не
буде. Реалізує посилальну цілісність таблиць, оптимізацію для роботи в системах
з значним об'ємом оперативної пам'яті, повну мультиверсійність.
Лист
ЧДТУ. 222084.001 ПЗ
29
Змн. Лист № докум. Підпис Дата
3 ОПИС РОЗРОБЛЕНОЇ СИСТЕМИ
3.1 База даних
Для системи було створено реляційну базу даних, яка складається з семи
таблиць, що пов’язані між собою з використанням механізму зовнішніх ключів.
Структура бази зображена на рисунку 3.1
Рисунок 3.1 – Структура бази даних
База включає в себе чотири довідники, дані до яких завантажуються з
інших інформаційних баз компанії; на створені таблиці посилаються інші
таблиці, які вміщують інформацію, що стосується бізнес-логіки додатку.
Довідниками є таблиці outlet – вміщує дані про торговельні точки, folders –
категорії товару, сортовані в деревоподібну структуру, employees – працівники
(вони можуть бути закріплені на різних торгових точках, періодично переходячи
з однієї на іншу), interval_kinds – типи інтервалів часу між окремими
інвентаризаціями (дні, місяць, місяці, раз в рік тощо).
Лист
ЧДТУ. 222084.001 ПЗ
30
Змн. Лист № докум. Підпис Дата
Таблиця folders_intervals задає типи інтервалів для окремих видів категорій
товарів, вона має зв’язок у вигляді один-до-одного з таблицею folders та зв’язок
типу багато-до-одного з таблицею interval_kinds.
Таблиця inventories задає план інвентаризацій – в ній записано інформацію
про те, на які дати заплановані інвентаризації для конкретних категорій товарів
певної торговельної точки.
Таблиця reports збирає інформацію про звіти за результатами
інвентаризації. В ній зберігається інформація про те, що виявила інвентаризація і
в яку дату вона була дійсно проведена, а також який працівник її проводив.
3.2 Структура проекту програми
Структура проект програми відображає дійсну структуру проекту Grails
(рисунок 3.2).
Розроблювані модулі програми розташовані в двох папках – grails-app та
web-app.
В першій розташовано переважно groovy-файли – конфігураційні у папці
conf, контролери у папці controllers, моделі у папці domain, сервіси у папці
services, утиліти у папці utils, сторінки у форматі gsp у папці views тощо.
В другій розміщено файли, що забезпечують роботу безпосередньо web, а
саме css, javascript, графічні зображення, деякі конфігураційні файли веб-
програми, шрифти та tld.
При роботі проекту результати компіляції та інші результати зберігаються
у папку target.
Лист
ЧДТУ. 222084.001 ПЗ
31
Змн. Лист № докум. Підпис Дата
Рисунок 3.2 – Структура проекту програми
3.3 Опис програми
Функціонал програми складається з частин. Оскільки вхідною інформацією
для будь-якої функції в MVC-програмах є методи контролера, то групи функцій
вірно відображаються через класи контролерів.
В програмі є п'ять класів контролерів:
– CalendarController – контролер для функцій, працюючий з
календарним планом інвентаризацій;
– MerchTypeController – контролер для функцій, працюючий з
типами товарів;
Лист
ЧДТУ. 222084.001 ПЗ
32
Змн. Лист № докум. Підпис Дата
– RegistrationController – контролер для функцій, працюючий з
реєстрацією користувачів;
– OutletController – контролер для функцій, працюючий з
торговельними точками;
– ReportController – контролер для функцій, працюючий з побудовою
звіту за результатами проведення інвентаризацій.
Рисунок 3.3 – Контролери в проекті програми
Програма працює на базі технології ajax для взаємодії клієнтської та
серверної частини. Центральною частиною програми є JavaScript файл
application.js та клас сервісу EventService – вони є програмною основою
реалізації функцій програми.
Файл application.js реалізує функцію, яка відправляє запит та обробляє
відповідь від контролера – використовується на майже всіх сторінках. Формат
дати передачі інформації – це JSON:
if (typeof jQuery !== 'undefined') {
(function($) {
$('#spinner').ajaxStart(function() {
$(this).fadeIn();
Лист
ЧДТУ. 222084.001 ПЗ
33
Змн. Лист № докум. Підпис Дата
}).ajaxStop(function() {
$(this).fadeOut();
});
})(jQuery);
}
Основним методом класу EventService є List<EventJSONTemplate>
getEventsForYear(MerchType merchType, String description), який формує задачі
для розкладу інвентаризацій на рік. Метод формує дані відповідно до типу
інтервалу між інвентаризаціями. Найбільш важливим є блок, в я кому інтервал
встановлюється у днях, що є типовим:
case Repeat.DAY_INTERVAL:
Date date = new Date().clearTime(); //TODO: fix this line
int nextyear = date.year + 1
while(date.year != nextyear) {
if(!merchType.daysInterval || merchType.daysInterval <= 0) break
result.add createEventJSONTemplate(merchType, date.time, description)
date = date.plus(merchType.daysInterval)
}
Результуючі дані мають повертатись у форматі JSON, тому тут
використовується метод createEventJSONTemplate, який робить з об’єктів JSON-
рядок:
private EventJSONTemplate createEventJSONTemplate(MerchType
merchType, long date, String description){
new EventJSONTemplate(
date: date,
title: merchType.name,
description: description,
url: grailsLinkGenerator.link(controller: 'merchType', action: 'show', id:
merchType.id)
)
Лист
ЧДТУ. 222084.001 ПЗ
34
Змн. Лист № докум. Підпис Дата
}
Клас EventJSONTemplate встановлює властивості JSON, який формується,
обираючи ті дані, які будуть передаватися клієнту:
class EventJSONTemplate {
String date
String type = ""
String title
String description
String url
}
3.3.1 Аутентифікація та авторизація користувачів у програмі
Першою сторінкою при запуску програми є сторінка входу в систему, де
користувачеві пропонується ввести ім'я та пароль, якщо він уже зареєстрований у
системі чи зареєструватись у іншому випадку. Користувач не має можливості
виконувати ніяких функцій, поки він не залогується до системи.
Функції аутентифікації та авторизації у даному додатку працюють через
використання бібліотеки spring-security 2.0. Для її використання потрібно додати
необхідний плагін до проекту (target/work/plugins/spring-security-core-2.0-RC2), а
також додати його у файл конфігурації BuildConfig.groovy разом з іншими
плагінами:
plugins {
build ":tomcat:7.0.52.1"
compile ":scaffolding:2.0.2"
compile ':cache:1.1.1'
compile ':spring-security-core:2.0-RC2'
runtime ":hibernate:3.6.10.9" // or ":hibernate4:4.3.4"
runtime ":database-migration:1.3.8"
runtime ":jquery:1.11.0.2"
runtime ":resources:1.2.7"
Лист
ЧДТУ. 222084.001 ПЗ
35
Змн. Лист № докум. Підпис Дата
}
Параметри авторизації налаштовуються у файлі BootStrap.groovy – додаток
реалізує дві ролі – користувача і менеджера:
def init = { servletContext ->
Role userRole = Role.findByAuthority("ROLE_USER")
if(!userRole) {
userRole = new Role(authority: "ROLE_USER").save(flush: true)
}
Role managerRole = Role.findByAuthority("ROLE_MANAGER")
if(!managerRole) {
managerRole = new Role(authority: "ROLE_MANAGER").save(flush: true)
}
}
Користувачеві доступна лише та інформація, яку додав він (користувачами
у системі є працівники торговельних точок), в той час як менеджеру доступна
вся інформація (це відповідальна особа підприємства, наприклад).
3.3.2 Формування плану інвентаризацій
Вхідною точкою для роботи даного функціоналу є контролер
CalendarController. Він реалізує два методи, index() та events(), які реагують на
вхід на сторінку та події, викликані діями користувача.
Функція методу events() – отримати дані про майбутні інвентаризації і
сформувати їх у формат JSON. При цьому базовою одиницею бізнес-логіки, яка
застосовується для виконання даної функції, є клас EventService, який отримує
дані з бази у відповідності до вибраного інтервалу часу для заданого товару і
формує дані у відповідному вигляді. Основним методом тут є
List<EventJSONTemplate> getEventsForYear(MerchType merchType, String
description), який реалізує відповідну операцію в залежності від проміжку часу,
наприклад, для щомісячних інвентаризацій
case Repeat.MONTHLY:
Лист
ЧДТУ. 222084.001 ПЗ
36
Змн. Лист № докум. Підпис Дата
if(merchType.dates.size() != 1) break
Date date = merchType.dates.iterator().next()
int nextyear = new Date().year + 1
while(date.year != nextyear) {
result.add createEventJSONTemplate(merchType, date.time, description)
date.month++
}
При цьому вихідний формат даних описується шаблоном, який
створюється методом private EventJSONTemplate
createEventJSONTemplate(MerchType merchType, long date, String description) –
шаблон реалізується у форматі JSON:
new EventJSONTemplate(
date: date,
title: merchType.name,
description: description,
url: grailsLinkGenerator.link(controller: 'merchType', action: 'show', id:
merchType.id)
)
CalendarController отримує дані EventService для кожного товару,
обробляючі їх в циклі і додаючи до колекції:
List<Long> outletIdList = params.list("outlet[]").collect {it.toLong()}
Outlet.findAllByIdInList(outletIdList).each {
String description = it.address
List<Long> merchTypeIdList = params.list("merchType[]").collect
{it.toLong()}
it.merchTypes.findAll { merchTypeIdList.contains(it.id) }.each {
result.addAll(eventService.getEventsForYear(it, description))
}
}
Лист
ЧДТУ. 222084.001 ПЗ
37
Змн. Лист № докум. Підпис Дата
Колекція повертається у вигляді JSON процедурою render(result as JSON)
до викликаючої функції AJAX drawCalendar(), яка є універсальною для всіх
запитів відповідно до плану інвентаризації. Дана функції розташовується у файлі
calendar/index.gsp сторінки плану.
Дана функція реалізує підготовку вхідних даних, відправку запиту та
рендеринг результату з інформації у форматі JSON.
Підготовка вхідних даних реалізується шляхом формування відповідних
структур даних з використанням jquery, наприклад
var outletValues = $('input:checkbox:checked.outlet').map(function () {
return this.value;
}).get();
var merchTypeValues = $('input:checkbox:checked.merchType').map(function () {
return this.value;
}).get();
Структура JSON формується наступним чином:
var jsonCheckboxValues = {
"outlet": outletValues,
"merchType": merchTypeValues
}
Відправка запиту до контролеру виконується командою $.get('<g:createLink
action="events"/>', jsonCheckboxValues, function(jsonArray), потім результат
обробляється (а саме відображається) в коллбек-функції. Для цього
застосовується JavaScript бібліотека jquery.eventCalendar, яка вміє відображати
дані з JSON-форматі у вигляді календаря. Для цього просто викликається
функція $('#calendar').eventCalendar().
Загальний шаблон сторінки calendar/index.gsp має вигляд таблиці, в якій
Лист
ЧДТУ. 222084.001 ПЗ
38
Змн. Лист № докум. Підпис Дата
виводиться сам план інвентаризацій і елементи для задання критеріїв відбору
інформації про план, тобто торговельних точок та товарів.
Лист
ЧДТУ. 222084.001 ПЗ
39
Змн. Лист № докум. Підпис Дата
ВИСНОВКИ
В рамках даної бакалаврської роботи було створено та описано додаток для
побудови плану проведення інвентаризацій в торгівельній галузі. В процесі
створення додатку було проаналізовано предметну область, виділено сутності та
їх зв’язки, позначено проблеми. На основі цього було зроблено постановку
задачі, сформульовано технічне завдання.
Безпосередньо розробка складалася з розробки бази даних, створення
архітектури програмного проекту, компіляцію веб-додатку у відповідності з
технічним завданням.
Розроблений додаток було перевірено на тестових даних.
У додатку було реалізовано наступні функції:
– формування календаря інвентаризацій за кожним типом товарів за
кожною торговельною точкою;
– перегляд, додавання і редагування типів товарів (з календарем та
валідацією) і торгових точок, а також взаємодія між цими сутностями (додання
товарів до точок);
– формування звіту за результатами інвентаризацій в необхідному вигляді.
Програму було побудовано з інтуїтивно зрозумілим інтерфейсом, суттєве
значення було приділено точному відображенню на дисплеях різної роздільної
здатності та розміру.
В ході роботи повністю вивчено прийоми роботи з мовою програмування
Groovy та фреймворком Grails, а також технологією AJAX.
Лист
ЧДТУ. 222084.001 ПЗ
40
Змн. Лист № докум. Підпис Дата
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ
1 Мартін Р. Чистий код. Створення, аналіз і рефакторинг. [Текст] / Р. Мартін.
— К.: УкрІНТЕІ, 2010 — 358 c.
2 Пономаренко В. Проектування інформаційних систем. [Текст] / В.
Пономаренко. — К. Київ: Видавничий центр «Академія», 2002 — 440 с.
3 Groovy за 15 хвилин – короткий огляд. [Електронний ресурс] Режим
доступу: habrahabr.ru/post/122127/
4 IntelliJ Community [Електронний ресурс] Режим доступу:
http://www.jetbrains.org/display/IJOS/Home;jsessionid=C81C7C8B74643ABBEE1D4
D8C34D5C3D1
5 James Strachan. Groovy — the birth of a new dynamic language for the Java
platform [Електронний ресурс] Режим доступу: http://radio-
weblogs.com/0112098/2003/08/29.html
6 Scala as the long term replacement for java/javac? (July 6, 2009). [Електронний
ресурс] Режим доступу: http://macstrac.blogspot.com/2009/04/scala-as-long-term-
replacement-for.html
7 Сервер баз даних MySQL [Електронний ресурс] Режим доступу:
http://mysql.com.
8 Бегг К. Бази даних. Проектування, реалізація і супровід. Теорія та
практика / К. Бегг, Т. Конноллі. – 2003. – 1238 с.
9 Берюх И. С. Вибір технології розробки програмного забезпечення
інформаційних систем. ScienceRise. Харків, 2018. № 5/2. С. 40–43
10 Брюс У. Javaсервлети і JSP. Збірник рецептів. [Текст] / У. Брюс. —
Львів, Захід-Прес, 2009 — 768 с.
11 Васильєв Н. Об'єктно-орієнтоване програмування. [Текст] / Н. Васильєв.
— К. Львів: «Афіша», 2011 — 400 с.
12 Інтернет-бізнес в Україні [Електронний ресурс] // Український інтернет-
журнал АIN.UА – Режим доступу: http://Аin.uА/5-trendov-progrАmmirovАniyА-
kotorye-izmenyАt-industriyu.
Лист
ЧДТУ. 222084.001 ПЗ
41
Змн. Лист № докум. Підпис Дата
13 Інженерія якості програмного забезпечення: навч. посібник / Г.В
Табунщик, Р.К. Кудерметов, Т.І. Брагіна. - Запоріжжя: ЗНТУ, 2013. - 180 с.
14 Кеннеді Б. Вивчаємо HTML / Б. Кеннеді, Ч. Маскиано. – 2018. – 272 с.
15 Концепція розвитку цифрової економіки та суспільства України на
2018-2020 роки: Розпорядженням Кабінету Міністрів України від 17 січня 2018 р.
№ 67-р. URL : https://zakon.rada.gov.ua/laws/show/67-2018-%D1%80.
16 Лоусон Б. HTML і XHTML. Детальне керівництво / Б. Лоусон, Р. Шарп.
– 2000. – 752 с.
17 МатовО.Я., ХрамоваІ.О. Сучасні технології інтеграції інформаційних
ресурсів. Реєстрація, зберігання і обробка даних. 2009, Т. 11, № 1. С.33-42.
18 Офіційний сайт MySQL [Електронний ресурс]. - Режим
доступа: http://dev.mysql.com/
19 Панченко С. В. Математичне моделювання в розподілених
інформаційних системах: Монографія. Харків: ФОП Бровін О. В., 2019. – 220с.
Лист
ЧДТУ. 222084.001 ПЗ
42
Змн. Лист № докум. Підпис Дата
ДОДАТОК А
АВТОМАТИЗОВАНА СИСТЕМА ІНВЕНТАРИЗАЦЇЙ МАТЕРІАЛЬНИХ
ЦІННОСТЕЙ ТОРГОВЕЛЬНОГО ПІДПРИЄМСТВА
Специфікація
Позначення Найменування Примітка
Документація
482.ЧДТУ.142132-01 12-01 Текст програми
482.ЧДТУ.142132-01 34-01 Інструкція користувача
482.ЧДТУ.142132-01 90-01 Графічні матеріали
Лист
ЧДТУ. 222084.001 ПЗ
43
Змн. Лист № докум. Підпис Дата
ДОДАТОК Б
МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
АВТОМАТИЗОВАНА СИСТЕМА ІНВЕНТАРИЗАЦЇЙ МАТЕРІАЛЬНИХ ЦІННОСТЕЙ
ТОРГОВЕЛЬНОГО ПІДПРИЄМСТВА
Текст програми
UA.ЧДТУ.222084-01 12 01
Листів 21
2022
Лист
ЧДТУ. 222084.001 ПЗ
44
Змн. Лист № докум. Підпис Дата
1 Текст програмних файлів
class CalendarController {
EventService eventService
def index() {
int currentYear = new Date().year + 1900;
return [year: currentYear, outletList: Outlet.list(), merchTypeList: MerchType.list()]
}
def events() {
List<EventJSONTemplate> result = new ArrayList<>()
List<Long> outletIdList = params.list("outlet[]").collect {it.toLong()}
Outlet.findAllByIdInList(outletIdList).each {
String description = it.address
List<Long> merchTypeIdList = params.list("merchType[]").collect {it.toLong()}
it.merchTypes.findAll { merchTypeIdList.contains(it.id) }.each {
result.addAll(eventService.getEventsForYear(it, description))
}
}
render(result as JSON)
}
}
@Transactional(readOnly = true)
class MerchTypeController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond MerchType.list(params), model:[merchTypeInstanceCount: MerchType.count()]
}
def show(MerchType merchTypeInstance) {
respond merchTypeInstance
}
def create() {
respond new MerchType(params)
}
@Transactional
def save(MerchType merchTypeInstance) {
//TODO: add some validation
Лист
ЧДТУ. 222084.001 ПЗ
45
Змн. Лист № докум. Підпис Дата
switch(params.repeat) {
case "MONTHLY":
case "YEARLY":
merchTypeInstance.addToDates(new Date(params.datesstring))
break
case "DATES":
MerchTypeUtils.stringToDateSet(params.datesstring).each {merchTypeInstance.addToDates(it)}
break
}
if (merchTypeInstance == null) {
notFound()
return
}
if (merchTypeInstance.hasErrors()) {
respond merchTypeInstance.errors, view:'create'
return
}
merchTypeInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code:
'merchTypeInstance.label', default: 'MerchType'), merchTypeInstance.id])
redirect merchTypeInstance
}
'*' { respond merchTypeInstance, [status: CREATED] }
}
}
def edit(MerchType merchTypeInstance) {
respond merchTypeInstance
}
@Transactional
def update(MerchType merchTypeInstance) {
//TODO: add some validation
switch(params.repeat) {
case "MONTHLY":
case "YEARLY":
merchTypeInstance?.dates?.clear()
merchTypeInstance.addToDates(new Date(params.datesstring))
break
case "DATES":
MerchTypeUtils.stringToDateSet(params.datesstring).each {merchTypeInstance.addToDates(it)}
Лист
ЧДТУ. 222084.001 ПЗ
46
Змн. Лист № докум. Підпис Дата
break
}
if (merchTypeInstance == null) {
notFound()
return
}
if (merchTypeInstance.hasErrors()) {
respond merchTypeInstance.errors, view:'edit'
return
}
merchTypeInstance.save flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'MerchType.label',
default: 'MerchType'), merchTypeInstance.id])
redirect merchTypeInstance
}
'*'{ respond merchTypeInstance, [status: OK] }
}
}
@Transactional
def delete(MerchType merchTypeInstance) {
if (merchTypeInstance == null) {
notFound()
return
}
merchTypeInstance.delete flush:true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'MerchType.label',
default: 'MerchType'), merchTypeInstance.id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
Лист
ЧДТУ. 222084.001 ПЗ
47
Змн. Лист № докум. Підпис Дата
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code:
'merchTypeInstance.label', default: 'MerchType'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
@Transactional(readOnly = true)
class OutletController {
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Outlet.list(params), model: [outletInstanceCount: Outlet.count()]
}
def show(Outlet outletInstance) {
respond outletInstance
}
def create() {
respond new Outlet(params), model: [merchTypeList: MerchType.findAll()]
}
@Transactional
def save(Outlet outletInstance) {
params.list("merchType")?.each {outletInstance.addToMerchTypes(MerchType.get(it.toLong()))}
if (outletInstance == null) {
notFound()
return
}
if (outletInstance.hasErrors()) {
respond outletInstance.errors, view: 'create'
return
}
outletInstance.save flush: true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'outletInstance.label',
default: 'Outlet'), outletInstance.id])
Лист
ЧДТУ. 222084.001 ПЗ
48
Змн. Лист № докум. Підпис Дата
redirect outletInstance
}
'*' { respond outletInstance, [status: CREATED] }
}
}
def edit(Outlet outletInstance) {
respond outletInstance, model: [merchTypeList: MerchType.findAll()]
}
@Transactional
def update(Outlet outletInstance) {
outletInstance?.merchTypes?.clear()
params.list("merchType")?.each {outletInstance.addToMerchTypes(MerchType.get(it.toLong()))}
if (outletInstance == null) {
notFound()
return
}
if (outletInstance.hasErrors()) {
respond outletInstance.errors, view: 'edit'
return
}
outletInstance.save flush: true
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'Outlet.label',
default: 'Outlet'), outletInstance.id])
redirect outletInstance
}
'*' { respond outletInstance, [status: OK] }
}
}
@Transactional
def delete(Outlet outletInstance) {
if (outletInstance == null) {
notFound()
return
}
outletInstance.delete flush: true
request.withFormat {
Лист
ЧДТУ. 222084.001 ПЗ
49
Змн. Лист № докум. Підпис Дата
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'Outlet.label', default:
'Outlet'), outletInstance.id])
redirect action: "index", method: "GET"
}
'*' { render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code:
'outletInstance.label', default: 'Outlet'), params.id])
redirect action: "index", method: "GET"
}
'*' { render status: NOT_FOUND }
}
}
}
@Transactional(readOnly = true)
class RegistrationController {
static allowedMethods = [save: "POST"]
def index() {
respond new User()
}
@Transactional
def save(User userInstance){
if (userInstance == null) {
notFound()
return
}
if (userInstance.hasErrors()) {
respond userInstance.errors, view: 'index'
return
}
userInstance.save flush: true
UserRole.create(userInstance, Role.findByAuthority("ROLE_USER"), true)
redirect(controller: "login", action: "auth")
}
Лист
ЧДТУ. 222084.001 ПЗ
50
Змн. Лист № докум. Підпис Дата
}
@Transactional(readOnly = true)
class ReportController {
static allowedMethods = [save: "POST"]
SpringSecurityService springSecurityService
EventService eventService
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond Report.list(params), model:[ReportInstanceCount: Report.count()]
}
def choose() {
return [outletList: Outlet.list(), merchTypeList: MerchType.list()]
}
def create() {
User user = springSecurityService.currentUser.asType(User.class)
Outlet outlet = Outlet.get(params.long("outlet"))
Report report = new Report(
outlet: outlet,
responsiblePerson: user.firstName + " " + user.lastName
)
List<Long> merchTypeIdList = params.merchType.split(',').collect {it.toLong()}
outlet.merchTypes.findAll {merchTypeIdList.contains(it.id)} .each {
SubReport subReport = new SubReport();
subReport.merchType = it;
List<EventJSONTemplate> events = eventService.getEventsForYear(it, null).sort {it.date}
events = events.reverse()
Date now = new Date().clearTime()
Date plannedDate
if(!events.empty){
plannedDate = new Date(events.find {it.date.toLong() <= now.time} ?.date?.toLong() ?:
events.last()?.date?.toLong()) //TODO: split the line
} else {
plannedDate = new Date()
}
subReport.plannedDate = plannedDate
subReport.realDate = now
report.addToSupReports subReport
}
Лист
ЧДТУ. 222084.001 ПЗ
51
Змн. Лист № докум. Підпис Дата
return [report: report]
}
def show(Report reportInstance) {
respond reportInstance
}
@Transactional
def save() {
Report report = new Report(
outlet: Outlet.findByAddress(params.address),
responsiblePerson: params.responsiblePerson
)
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd")
List<Integer> supposedToBeList = params.list('supposedToBe')?.collect {it.toInteger()}
List<Integer> factList = params.list('fact')?.collect {it.toInteger()}
List<Date> plannedDateList = params.list('plannedDate')?.collect {format.parse(it)}
List<Date> realDateList = params.list('realDate')?.collect {format.parse(it)}
params.list('merchType').eachWithIndex {merchType, i ->
SubReport subReport = new SubReport(
merchType: MerchType.get(merchType.toLong()),
supposedToBe: supposedToBeList.get(i),
fact: factList.get(i),
plannedDate: plannedDateList.get(i),
realDate: realDateList.get(i)
)
report.addToSupReports subReport
}
report.save(flush: true)
redirect(action: "show", id: report.id)
}
}
class EventService {
LinkGenerator grailsLinkGenerator
List<EventJSONTemplate> getEventsForYear(MerchType merchType, String description) {
List<EventJSONTemplate> result = new ArrayList<>();
switch(merchType.repeat){
case Repeat.DAY_INTERVAL:
Date date = new Date().clearTime(); //TODO: fix this line
int nextyear = date.year + 1
while(date.year != nextyear) {
if(!merchType.daysInterval || merchType.daysInterval <= 0) break
result.add createEventJSONTemplate(merchType, date.time, description)
Лист
ЧДТУ. 222084.001 ПЗ
52
Змн. Лист № докум. Підпис Дата
date = date.plus(merchType.daysInterval)
}
break
case Repeat.MONTHLY:
if(merchType.dates.size() != 1) break
Date date = merchType.dates.iterator().next()
int nextyear = new Date().year + 1
while(date.year != nextyear) {
result.add createEventJSONTemplate(merchType, date.time, description)
date.month++
}
break
case Repeat.YEARLY:
if(merchType.dates.size() != 1) break
Date resultDate = merchType.dates.iterator().next()
resultDate.year = new Date().year
result.add createEventJSONTemplate(merchType, resultDate.time, description)
break
case Repeat.DATES:
merchType.dates.each {
result.add createEventJSONTemplate(merchType, it.time, description)
}
break
}
return result
}
private EventJSONTemplate createEventJSONTemplate(MerchType merchType, long date, String
description){
new EventJSONTemplate(
date: date,
title: merchType.name,
description: description,
url: grailsLinkGenerator.link(controller: 'merchType', action: 'show', id: merchType.id)
)
}
}
class EventJSONTemplate {
String date
String type = ""
Лист
ЧДТУ. 222084.001 ПЗ
53
Змн. Лист № докум. Підпис Дата
String title
String description
String url
}
class MerchTypeUtils {
static def stringToDateSet(String str) {
str.split(',').collect {new Date(it)}
}
}
modules = {
application {
resource url:'js/application.js'
}
}
class BootStrap {
def init = { servletContext ->
Role userRole = Role.findByAuthority("ROLE_USER")
if(!userRole) {
userRole = new Role(authority: "ROLE_USER").save(flush: true)
}
Role managerRole = Role.findByAuthority("ROLE_MANAGER")
if(!managerRole) {
managerRole = new Role(authority: "ROLE_MANAGER").save(flush: true)
}
User user = User.findByEmail("[email protected]")
if(!user) {
user = new User(
email: "[email protected]",
password: "test",
firstName: "John",
lastName: "Doe"
).save(flush: true)
}
UserRole.create(user, userRole, true)
MerchType merchType1 = MerchType.findByName("Клавіатура")
if(!merchType1) {
merchType1 = new MerchType(
name: "Клавіатура",
repeat: Repeat.DAY_INTERVAL,
daysInterval: 20
Лист
ЧДТУ. 222084.001 ПЗ
54
Змн. Лист № докум. Підпис Дата
).save(flush: true)
}
MerchType merchType2 = MerchType.findByName("Монітор")
if(!merchType2) {
merchType2 = new MerchType(
name: "Монітор",
repeat: Repeat.DAY_INTERVAL,
daysInterval: 10
).save(flush: true)
}
MerchType merchType3 = MerchType.findByName("Принтер")
if(!merchType3) {
merchType3 = new MerchType(
name: "Принтер",
repeat: Repeat.MONTHLY
)
merchType3.addToDates(new Date())
merchType3.save(flush: true)
}
Outlet outlet = Outlet.findByAddress("бул. Шевченка 77/2")
if(!outlet) {
outlet = new Outlet(
address: "бул. Шевченка 77/2",
phoneNumber: "123-45-67"
)
outlet.addToMerchTypes(merchType1)
outlet.addToMerchTypes(merchType2)
outlet.addToMerchTypes(merchType3)
outlet.save(flush: true)
}
}
def destroy = {
}
}
dataSource {
pooled = true
jmxExport = true
driverClassName = "org.h2.Driver"
username = "sa"
password = ""
}
hibernate {
cache.use_second_level_cache = true
Лист
ЧДТУ. 222084.001 ПЗ
55
Змн. Лист № докум. Підпис Дата
cache.use_query_cache = false
cache.region.factory_class = 'net.sf.ehcache.hibernate.EhCacheRegionFactory' // Hibernate 3
// cache.region.factory_class = 'org.hibernate.cache.ehcache.EhCacheRegionFactory' // Hibernate 4
singleSession = true // configure OSIV singleSession mode
}
// environment specific settings
environments {
development {
dataSource {
dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
url =
"jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
}
}
test {
dataSource {
dbCreate = "update"
url =
"jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
}
}
production {
dataSource {
dbCreate = "update"
url = "jdbc:h2:prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE"
properties {
// See http://grails.org/doc/latest/guide/conf.html#dataSource for documentation
jmxEnabled = true
initialSize = 5
maxActive = 50
minIdle = 5
maxIdle = 25
maxWait = 10000
maxAge = 10 * 60000
timeBetweenEvictionRunsMillis = 5000
minEvictableIdleTimeMillis = 60000
validationQuery = "SELECT 1"
validationQueryTimeout = 3
validationInterval = 15000
testOnBorrow = true
testWhileIdle = true
testOnReturn = false
jdbcInterceptors = "ConnectionState"
defaultTransactionIsolation = java.sql.Connection.TRANSACTION_READ_COMMITTED
}
}
Лист
ЧДТУ. 222084.001 ПЗ
56
Змн. Лист № докум. Підпис Дата
}
}
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/"(controller: "calendar", action: "index")
"500"(view:'/error')
}
}
2 Текст gsp-сторінок
index.gsp
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main"/>
<title>Welcome to Grails</title>
<style type="text/css" media="screen">
#status {
background-color: #eee;
border: .2em solid #fff;
margin: 2em 2em 1em;
padding: 1em;
width: 12em;
float: left;
-moz-box-shadow: 0px 0px 1.25em #ccc;
-webkit-box-shadow: 0px 0px 1.25em #ccc;
box-shadow: 0px 0px 1.25em #ccc;
-moz-border-radius: 0.6em;
-webkit-border-radius: 0.6em;
border-radius: 0.6em;
}
.ie6 #status {
display: inline; /* float double margin fix
http://www.positioniseverything.net/explorer/doubled-margin.html */
}
#status ul {
font-size: 0.9em;
Лист
ЧДТУ. 222084.001 ПЗ
57
Змн. Лист № докум. Підпис Дата
list-style-type: none;
margin-bottom: 0.6em;
padding: 0;
}
#status li {
line-height: 1.3;
}
#status h1 {
text-transform: uppercase;
font-size: 1.1em;
margin: 0 0 0.3em;
}
#page-body {
margin: 2em 1em 1.25em 18em;
}
h2 {
margin-top: 1em;
margin-bottom: 0.3em;
font-size: 1em;
}
p {
line-height: 1.5;
margin: 0.25em 0;
}
#controller-list ul {
list-style-position: inside;
}
#controller-list li {
line-height: 1.3;
list-style-position: inside;
margin: 0.25em 0;
}
@media screen and (max-width: 480px) {
#status {
display: none;
}
#page-body {
margin: 0 1em 1em;
Лист
ЧДТУ. 222084.001 ПЗ
58
Змн. Лист № докум. Підпис Дата
}
#page-body h1 {
margin-top: 0;
}
}
</style>
</head>
<body>
<a href="#page-body" class="skip"><g:message code="default.link.skip.label" default="Skip
to content…"/></a>
<div id="status" role="complementary">
<h1>Application Status</h1>
<ul>
<li>App version: <g:meta name="app.version"/></li>
<li>Grails version: <g:meta name="app.grails.version"/></li>
<li>Groovy version: ${GroovySystem.getVersion()}</li>
<li>JVM version: ${System.getProperty('java.version')}</li>
<li>Reloading active: ${grails.util.Environment.reloadingAgentEnabled}</li>
<li>Controllers: ${grailsApplication.controllerClasses.size()}</li>
<li>Domains: ${grailsApplication.domainClasses.size()}</li>
<li>Services: ${grailsApplication.serviceClasses.size()}</li>
<li>Tag Libraries: ${grailsApplication.tagLibClasses.size()}</li>
</ul>
<h1>Installed Plugins</h1>
<ul>
<g:each var="plugin"
in="${applicationContext.getBean('pluginManager').allPlugins}">
<li>${plugin.name} - ${plugin.version}</li>
</g:each>
</ul>
</div>
<div id="page-body" role="main">
<h1>Welcome to Grails</h1>
<p>Congratulations, you have successfully started your first Grails application! At the
moment
this is the default page, feel free to modify it to either redirect to a controller or
display whatever
content you may choose. Below is a list of controllers that are currently deployed in
this application,
click on each to execute its default action:</p>
<div id="controller-list" role="navigation">
<h2>Available Controllers:</h2>
<ul>
<g:each var="c" in="${grailsApplication.controllerClasses.sort {
it.fullName } }">
Лист
ЧДТУ. 222084.001 ПЗ
59
Змн. Лист № докум. Підпис Дата
<li class="controller"><g:link
controller="${c.logicalPropertyName}">${c.fullName}</g:link></li>
</g:each>
</ul>
</div>
</div>
</body>
</html>
calendar/index.gsp
<!DOCTYPE html>
<html>
<head>
<meta name="layout" content="main">
<title>Календар інвентарізації</title>
<link rel="stylesheet" href="${resource(dir: 'css', file: 'eventCalendar.css')}" type="text/css">
<link rel="stylesheet" href="${resource(dir: 'css', file: 'eventCalendar_theme_responsive.css')}"
type="text/css">
<g:javascript src="jquery.timeago.js"/>
<g:javascript src="jquery.eventCalendar.min.js"/>
<script type="text/javascript">
$(document).ready(function(){
drawCalendar();
});
function drawCalendar(){
var outletValues = $('input:checkbox:checked.outlet').map(function () {
return this.value;
}).get();
var merchTypeValues = $('input:checkbox:checked.merchType').map(function () {
return this.value;
}).get();
var jsonCheckboxValues = {
"outlet": outletValues,
"merchType": merchTypeValues
}
$.get('<g:createLink action="events" />', jsonCheckboxValues, function(jsonArray){
//clearing events and div
$('#calendar').off( "click", ".eventsCalendar-day a");
$('#calendar').off( "click", ".monthTitle");
$('#calendar').find('.eventsCalendar-list').off( "click", ".eventTitle");
$('#calendar').html('');
Лист
ЧДТУ. 222084.001 ПЗ
60
Змн. Лист № докум. Підпис Дата
$('#calendar').eventCalendar({
jsonData: jsonArray,
eventsLimit: 10,
openEventInNewWindow: true,
showDescription: true,
monthNames: [ "Січень", "Лютий", "Березень", "Квітень", "Травень", "Червень",
"Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень" ],
dayNames: [ 'Неділя','Понеділок','Вівторок','Середа','Четвер',
'П\'ятниця','Субота' ],
dayNamesShort: [ 'Вс','Пн','Вт','Ср','Чт', 'Пт','Сб' ],
txt_noEvents: "На даний період перевірки не були заплановано",
txt_SpecificEvents_prev: "",
txt_SpecificEvents_after: "події:",
txt_next: "наступнмй",
txt_prev: "попередній",
txt_NextEvents: "Майбутні події:",
txt_GoToEventUrl: "До події"
});
}); //TODO: add fail action
}
function changeSelection(checkboxClass, status){
$(checkboxClass).each(function() {
this.checked = status;
});
}
</script>
</head>
<body>
<h3 align="center">Графік інвентарізації на ${year} рік</h3>
<table class="table">
<tr>
<td width="50%">
<div id="calendar" align = "center"></div>
</td>
<td width="50%">
<table class="table">
<tr>
<td colspan="2">
<button type="button" class="btn btn-primary btn-lg btn-block"
onclick="drawCalendar()">
Оновити
</button>
</td>
</tr>
Лист
ЧДТУ. 222084.001 ПЗ
61
Змн. Лист № докум. Підпис Дата
<tr>
<td width="50%">
<h4>Торгові точки:</h4>
<g:each in="${outletList}" var="outlet">
<div class="checkbox">
<label for="outlet">${outlet.address}</label>
<g:checkBox name="outlet" class="outlet" value="${outlet.id}" checked="true"/>
</div>
</g:each>
<button type="button" class="btn btn-success" onclick="changeSelection('.outlet',
true)">Позначити</button>
<button type="button" class="btn btn-warning" onclick="changeSelection('.outlet',
false)">Відмінити</button>
</td>
<td width="50%">
<h4>Типи товарів:</h4>
<g:each in="${merchTypeList}" var="merchType">
<div class="checkbox">
<label for="merchType">${merchType.name}</label>
<g:checkBox name="merchType" class="merchType" value="${merchType.id}"
checked="true"/>
</div>
</g:each>
<button type="button" class="btn btn-success" onclick="changeSelection('.merchType',
true)">Позначити</button>
<button type="button" class="btn btn-warning" onclick="changeSelection('.merchType',
false)">Відмінити</button>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
Лист
ЧДТУ. 222084.001 ПЗ
62
Змн. Лист № докум. Підпис Дата
ДОДАТОК В
Інструкція користувача
Лист
ЧДТУ. 222084.001 ПЗ
63
Змн. Лист № докум. Підпис Дата
1 ПРИЗНАЧЕННЯ ПРОГРАМИ
Додаток для планування проведення інвентаризацій на торгівельному
підприємстві дає можливість фірмі, яка займається торгівлею, ефективно
організувати процес проведення інвентаризацій, забезпечивши систематичність і
контроль. Додаток складається з бази даних MySQL та веб-програми.
Програма дає можливість працівникові фірми:
– переглядати, додавати і редагувати види товарів (з календарем та
валідацією) і торговельні точкик, а також зв'язки між цими сутностями (додання
товарів до точок);
– формувати календар інвентаризацій за кожною групою товарів за
кожною торговельною точкою;
– формувати звіти за результатами інвентаризацій в заданому
вигляді.
Лист
ЧДТУ. 222084.001 ПЗ
64
Змн. Лист № докум. Підпис Дата
2 УМОВИ ЗАПУСКУ І ВИКОНАННЯ ПРОГРАМИ
Додаток складається з двох частин – скрипту створення бази даних
InventoryPlanning.sql та папки веб-програми InventoryPlanning.
Дана програма написана на мові Groovy з використанням фреймворку Grails, що дає
можливість запустити її на комп'ютерах з різними платформами. Для роботи вона потребує
наступного встановленого на комп'ютері програмного забезпечення:
– Grails 2.3.7;
– SQL-сервер MySQL версії не нижче 5.1;
– веб-сервер Tomcat 8.0 або аналогічний.
Для запуску програми потрібно виконати наступні дії:
створити MySQL базу даних, використовуючи скрипт
InventoryPlanning.sql;
– задеплоїти проект, яких поставляється у вигляді папки
InventoryPlanning, на сервер, зв'язавши його з сервером.
При виборі технічних характеристик для нормального функціонування проекту,
потрібно зауважити, що проект вимагає як мінімум такої конфігурації апаратних засобів,
що забезпечує функціонування 32 розрядного операційного середовища Windows.
Архітектура ПЕОМ повинна мати 512 Mb оперативної пам’яті. Для оптимальної роботи
процесор повинен бути з частотою 2000Гц або вище. Мінімальний розмір вільного
простору на твердому диску, необхідний для запуску системи – 64MB.
Доступ до програми користувачем здійснюється з використанням веб-браузера, в
якому користувач повинен набрати адресу сервера, на якому встановлено додаток та ім'я
програми InventoryPlanning.
Лист
ЧДТУ. 222084.001 ПЗ
65
Змн. Лист № докум. Підпис Дата
3 ІНСТРУКЦІЯ ПО РОБОТІ З ПРОГРАМОЮ
Для початку роботи з програмою після того, як програму задеплоєно на
сервері, потрібно завантажити браузер та набрати в рядку адреси адресу проекту,
наприклад, http://localhost:8080/InventoryPlanning. Відкривається стартова
сторінка, на якій будь-який користувач може увійти до системи або
зареєструватись у ній (рисунок В.1).
Рисунок В.1 – Стартова сторінка програми
Для того, щоб скористатися програмою, потрібно увійти в систему, увівши
правильний логін та пароль. Якщо користувач ще не має їх, то він повинен
зареєструватись у системі – при натисненні на кнопку реєстрація відбудеться
перехід на сторінку реєстрації (рисунок В.2).
Лист
ЧДТУ. 222084.001 ПЗ
66
Змн. Лист № докум. Підпис Дата
Рисунок В.2 – Реєстрація користувача у системі
Заповнивши відповідні дані, користувач повернеться на сторінку логіну і
зможе увійти до системи.
Після цього на екран виводиться стартова сторінка для роботи клієнта – в
лівій частині сторінки знаходиться календар, а в правій – можливість вибору
товарів та торговельних точок для перегляду призначених інвентаризацій
(рисунок В.3).
Графік інвентаризацій показується зразу до кінця року. Але є можливість
відфільтрувати дані – за торговельними точками, типами товарів та датами. Для
фільтрування за торговельними точками та датами потрібно у правій частині
вікна відмітити галочками лише потрібні пункти та натиснути кнопку "Оновити".
Будуть показані заплановані інвентаризації лише за тими торговельними точками
та тими товарами, які відмічені; крім того, на календарі в поточному місяці
будуть виділені ті дати, на які є хоч якась інвентаризація. Клікнувши на певній
виділеній даті на календарі, можна подивитись, які інвентаризації заплановані
саме на цю дату (рисунок В.4).
Лист
ЧДТУ. 222084.001 ПЗ
67
Змн. Лист № докум. Підпис Дата
Рисунок В.3 – Стартова сторінка роботи клієнта в системі
Рисунок В.4 – Перегляд запланованих інвентаризацій на певну дату
Можна додавати нові торговельні точки, а також редагувати та видаляти
існуючі, натиснувши пункт меню "Торгові точки" (рисунок В.5).
Лист
ЧДТУ. 222084.001 ПЗ
68
Змн. Лист № докум. Підпис Дата
Рисунок В.5 – Робота з торговими точками
Можна додавати нові типи товарів, а також редагувати та видаляти
існуючі, натиснувши пункт меню "Типи товарів" (рисунок В.6).
Рисунок В.6 – Робота з типами товарів
Вибравши пункт меню "Звіти", можна заповнити і сформувати звіт за
сьогоднішню дату (рисунок В.7).
Лист
ЧДТУ. 222084.001 ПЗ
69
Змн. Лист № докум. Підпис Дата
Рисунок В.7 – Стартова сторінка адміністратора
Натиснувши на пункт меню "Вийти", можна залишити систему – при
цьому відбувається перехід на сторінку логіну.
Лист
ЧДТУ. 222084.001 ПЗ
70
Змн. Лист № докум. Підпис Дата
ДОДАТОК Г
Графічні матеріали
Постановка задачі
Додаток повинен реалізувати наступні функції:
перегляд, додавання і редагування видів товарів (з календарем та
валідацією) і торгових точок, а також зв'язки між цими сутностями
(додання товарів до точок);
формування календаря інвентаризацій за кожною групою товарів за
кожною торговельною точкою;
формування звіту за результатами інвентаризацій в заданому вигляді.
Технології і засоби реалізації системи
◼ Cервер баз даних MySQL
◼ Мова програмування Groovy
◼ Фреймворк Grails
◼ Середовище розробки IntellijIDEA
◼ Web-сервер Apache Tomcat
◼ Плагін Spring Security для забезпечення аутентифікації та авторизації
Лист
ЧДТУ. 222084.001 ПЗ
71
Змн. Лист № докум. Підпис Дата
Структура бази даних
Структура програми
Розроблювані модулі
програми групуються в
двох папках – grails-app та
web-app.
В першій зосереджено
переважно groovy-файли –
конфігураційні у папці
conf, контролери у папці
controllers, моделі у папці
domain, сервіси у папці
services, утиліти у папці
utils, сторінки у форматі
gsp у папці views.
В другій зосереджено
файли, що стосуються
безпосередньо web, а саме
css, javascript, графічні
зображення, деякі
конфігураційні файли веб-
програми, шрифти та tld.
Лист
ЧДТУ. 222084.001 ПЗ
72
Змн. Лист № докум. Підпис Дата
Функцій програми: планування
Функцій програми: звіт
Лист
ЧДТУ. 222084.001 ПЗ
73
Змн. Лист № докум. Підпис Дата
Налаштування крісла "під себе", враховуючи усі індивідуальні
особливості будови тіла працівника і робочого місця
Лист
ЧДТУ. 222084.001 ПЗ
74
Змн. Лист № докум. Підпис Дата