Академический Документы
Профессиональный Документы
Культура Документы
ПОЯСНИТЕЛЬНАЯ ЗАПИСКА
к курсовому проекту по дисциплине
«Конструирование программ и языки программирования»
КП Т.795003.401
2020
Содержание
Введение 4
1 Объектно-ориентированный анализ и проектирование системы 6
1.1 Сущность задачи 6
1.2 Проектирование модели 7
2 Вычислительная система 12
2.1 Требования к аппаратным и операционным ресурсам 12
2.2 Инструменты разработки 12
3 Проектирование задачи 14
3.1 Требования к приложению 14
3.2 Концептуальный прототип 14
3.3 Организация данных 16
3.4 Функции: логическая и физическая организация 20
3.5 Проектирование справочной системы приложения 21
4 Описание программного средства 22
4.1 Общие сведения 22
4.2 Функциональное назначение 22
4.3 Входные и выходные данные 22
5 Методика испытаний 27
5.1 Технические требования 27
5.2 Функциональное тестирование 27
6 Применение 34
6.1 Назначение программы 34
6.2 Условия применения 34
6.3 Справочная система 34
Заключение 36
Список информационных источников 37
Приложение А Текст программы 39
Приложение Б Формы выходных документов 71
КП Т.795003.401
Изм. Лист № докум. Подпись Дата
Разраб. Божкова Е. Ю. Лит.
Провер. Михалевич В.Ю. Программное средство для у
Реценз. автоматизации рабочего
Н. Контр. места администратора
Утверд. кафе
4
Введение
5
1 Объектно-ориентированный анализ и проектирование системы
1.1Сущность задачи
6
Таблица 1.1 – Сроки хранения продуктов
Наименование Срок хранения, сут Наименование Срок хранения, сут
1.2Проектирование модели
7
Рисунок 1.1 Диаграмма «Сущность-связь»
9
Таблица 1.2 Классы, поля и методы
Название класса Поля класса Методы класса
10
выступать файлы, библиотеки, модули, исполняемые файлы, пакеты и т. п. Для данного проекта
выделены такие компоненты, как:
Controllers содержит такие контроллеры как:
CategoryController;
DishController;
DrinkController;
HomeController;
IngredientController;
OrderController;
StockController;
UnitController;
WaiterController.
Models содержит такие модели как:
Category;
Dish;
DishComposition;
DishOrderInfo;
Drink;
DrinkOrderInfo;
Ingredient;
Order;
Stock;
Units;
Waiter.
Данная диаграмма находится в графической части на листе 5.
11
2 Вычислительная система
2.2Инструменты разработки
12
использовать. Он содержит базу данных, специально предназначенную для встроенных и
небольших приложений.
StarUML это сложный программный моделлер, предназначенный для поддержки
гибкого и лаконичного моделирования. Написан на Delphi [20].
13
3 Проектирование задачи
3.2Концептуальный прототип
14
Форма «References system» содержит справочную систему для данного приложения.
Кнопка «Edit» будет редактировать выбранный элемент в базе данных.
Кнопка «Add» будет добавлять новый элемент в базу данных.
Кнопка «Delete» будет удалять элементы с базы данных.
Рисунок 3.1
Рисунок 3.2
Рисунок 3.3
Макет формы «Sign in» представлен на рисунке 3.3.
15
Рисунок 3.3
16
Таблица «Waiter» хранит информацию об официантах, структура которой приведена в
таблице 3.2.
18
Имя поля Тип поля Размер поля, байт Описание поля
19
3.4Функции: логическая и физическая организация
handleSubmit=(event)=>{
event.preventDefault();
axios.post(`https://localhost:44399/api/Order/create?${qs.stringify({
Date: event.target.date.value,
NumberTable: event.target.numberTable.value,
WaiterId: event.target.waiter.value,
TotalPrice: event.target.totalPrice.value
})}`)
.then(res=> {
console.log(res.data);
this.setState({snackBaropen: true, snackBarMessage: 'Added successfully'});
})
.catch(error=> {
console.log(error);
this.setState({snackBaropen: true, snackBarMessage: 'Failed added'});
});
}
handleSubmit(event){
event.preventDefault();
axios.put(`https://localhost:44399/api/Order/update?${qs.stringify({
Id: event.target.id.value,
Date: event.target.date.value,
NumberTable: event.target.numberTable.value,
WaiterId: event.target.waiter.value,
TotalPrice: event.target.totalPrice.value
})}`)
.then(res=> {
console.log(res.data);
this.setState({snackBaropen: true, snackBarMessage: 'Updated successfully'});
})
.catch(error=> {
console.log(error);
20
this.setState({snackBaropen: true, snackBarMessage: 'Failed to update'});
});
}
deleteOrder(orderId){
if(window.confirm('Are you sure?')){
axios.delete(`https://localhost:44399/api/Order/delete/${orderId}`)
.then(res=> {
console.log(res.data);
})
.catch(error=> {
console.log(error);
});
}
}
Справочная система в данном проекте будет реализована в правом верхнем углу панели
меню и содержать:
- основные цели данного приложения;
- описание кнопок и действий в данном приложении;
- список основных разделов приложения в панели меню:
- Home главная страница приложения. Приветствует пользователя.
- List of waiters страница для просмотра и работы со списком обслуживающего
персонала.
- Category страница для просмотра и работы со списком существующих
категорий блюд и напитков.
- Menu/Dishes страница для просмотра и работы со списком существующих
блюд.
- Menu/Drinks страница для просмотра и работы со списком существующих
напитков.
- Stock страница для просмотра и ведения учёта наличия ингредиентов.
- Order страница для просмотра и ведения учёта сделанных заказов.
- ? страница справочной системы.
Данная справочная система будет разработана средствами JavaScript-библиотеки React.
21
4 Описание программного средства
4.1Общие сведения
4.2Функциональное назначение
22
Рисунок 4.1
Рисунок 4.2
Рисунок 4.3
Рисунок 4.4
Рисунок 4.5
Рисунок 4.6
25
Входными данными при добавлении новой информации в сущность «Order» являются:
date;
number of table;
number of waiter;
price.
Форма «Adding order» представлен на рисунке 4.7.
Рисунок 4.7
26
5 Методика испытаний
28
Рисунок 5.4 Окно добавления блюда
29
Таблица 5.3 Тест функции изменение данных о блюде
№ Функция Шаги выполнения Результат
30
Четвёртый тест будет проведён также в форме «Menu/Dish».
31
Пятый тест будет проведён также в форме «Menu/Dish».
33
6 Применение
6.2Условия применения
34
Рисунок 6.1
35
Заключение
36
Список информационных источников
37
15. Учебник. Создание веб-API с помощью ASP.NET Core [Электронный ресурс] –
Microsoft, 2019 – Режим доступа: https://docs.microsoft.com/en-us/aspnet/core/tutorials/first-web-
api?view=aspnetcore-3.1&tabs=visual-studio Дата доступа: 11.05.2020
17. React JS. Подключение React в ASP.NET Core [Электронный ресурс] – Metanit –
Режим доступа: https://metanit.com/sharp/aspnet5/25.1.php Дата доступа: 11.05.2020
38
Приложение А
(обязательное)
Текст программы
//Cafe.sln
//Models
//ApplicationContext.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Cafe.Models.DBModels;
using Microsoft.EntityFrameworkCore;
namespace Cafe.Models
{
public class ApplicationContext : DbContext
{
public ApplicationContext()
{
//this.Database.EnsureDeleted();
this.Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("Data Source=.\\SQLEXPRESS;Initial
Catalog=kursach_db;Trusted_connection=True");
}
//ErrorViewModel.cs
using System;
namespace Cafe.Models
{
public class ErrorViewModel
{
39
public string RequestId { get; set; }
//Models/DBModels
//Category.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class Category
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[JsonIgnore]
public ICollection<Dish> Dishes { get; set; }
[JsonIgnore]
public ICollection<Drink> Drinks { get; set; }
}
}
//Dish.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class Dish
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public Category Category { get; set; }
public double Weight { get; set; }
public double FirstPrice { get; set; }
public double MarkUp { get; set; }
public double Price { get; set; }
[JsonIgnore]
40
public ICollection<DishComposition> DishCompositions { get; set; }
[JsonIgnore]
public ICollection<DishOrderInfo> DishOrderInfos { get; set; }
}
}
//DishComposition.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class DishComposition
{
public int Id { get; set; }
[ForeignKey("Dish")]
public int DishId { get; set; }
public Dish Dish { get; set; }
[ForeignKey("Ingredient")]
public int IngredientId { get; set; }
public Ingredient Ingredient { get; set; }
public int Amount { get; set; }
}
}
//DishOrderInfo.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class DishOrderInfo
{
public int Id { get; set; }
[ForeignKey("Dish")]
public int DishId { get; set; }
public Drink Drink { get; set; }
[ForeignKey("Order")]
public int OrderId { get; set; }
public Order Order { get; set; }
}
}
//Drink.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
41
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class Drink
{
public int Id { get; set; }
public string Name { get; set; }
[ForeignKey("Category")]
public int CategoryId { get; set; }
public Category Category { get; set; }
public double Volume { get; set; }
public double FirstPrice { get; set; }
public double MarkUp { get; set; }
public double Price { get; set; }
[JsonIgnore]
public ICollection<DrinkOrderInfo> DrinkOrderInfos { get; set; }
}
}
//DrinkOrderInfo.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class DrinkOrderInfo
{
public int Id { get; set; }
[ForeignKey("Drink")]
public int DrinkId { get; set; }
public Drink Drink { get; set; }
[ForeignKey("Order")]
public int OrderId { get; set; }
public Order Order { get; set; }
}
}
//Ingredient.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
42
{
public class Ingredient
{
public int Id { get; set; }
public string Name { get; set; }
public double Amount { get; set; }
[ForeignKey("Units")]
public int UnitId { get; set; }
public Units Units { get; set; }
public double FirstPrice { get; set; }
[JsonIgnore]
public ICollection<DishComposition> DishCompositions { get; set; }
[JsonIgnore]
public ICollection<Stock> Stocks { get; set; }
}
}
//Order.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class Order
{
public int Id { get; set; }
public DateTime? Date { get; set; }
public int NumberTable { get; set; }
[ForeignKey("Waiter")]
public int WaiterId { get; set; }
public Waiter Waiter { get; set; }
public double TotalPrice { get; set; }
}
}
//Stock.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class Stock
{
public int Id { get; set; }
[ForeignKey("Ingredient")]
public int IngredientId { get; set; }
43
public Ingredient Ingredient { get; set; }
public double TotalPrice { get; set; }
}
}
//Units.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class Units
{
public int Id { get; set; }
public string Name { get; set; }
[JsonIgnore]
public ICollection<Ingredient> Ingredients { get; set; }
}
}
//Waiter.cs
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Cafe.Models.DBModels
{
public class Waiter
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
public string Patronymic { get; set; }
[JsonIgnore]
public ICollection<Order> Orders { get; set; }
}
}
//Services/DBServices
//IDBService.cs
using System.Collections.Generic;
using Cafe.Models.DBModels;
namespace Cafe.Services.DBServices
{
public interface IDBService<T>
44
{
bool Create(T entity);
IList<T> GetAll();
T GetById(int id);
bool Remove(int id);
bool Update(T newEntity);
}
}
//DBOrderService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Cafe.Models;
using Cafe.Models.DBModels;
using Microsoft.EntityFrameworkCore;
namespace Cafe.Services.DBServices
{
public class DBOrderService : IDBService<Order>
{
public bool Create(Order entity)
{
if (entity == null)
{
return false;
}
using (var context = new ApplicationContext())
{
var state = context.Add(entity).State;
if (state != EntityState.Added)
{
return false;
}
try
{
context.SaveChanges();
}
catch
{
return false;
}
return true;
}
}
if (deleted == null)
{
return false;
}
if (result != EntityState.Deleted)
{
return false;
}
try
{
context.SaveChanges();
}
catch
{
return false;
}
return true;
}
}
if (prevEntity == null)
{
return false;
}
prevEntity.Date = newEntity.Date;
prevEntity.NumberTable = newEntity.NumberTable;
prevEntity.WaiterId = newEntity.WaiterId;
prevEntity.TotalPrice = newEntity.TotalPrice;
try
{
context.SaveChanges();
}
catch
{
return false;
}
return true;
}
}
}
}
//Controllers
//HomeController.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Cafe.Models;
namespace Cafe.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
//OrderController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Cafe.Models.DBModels;
using Cafe.Services.DBServices;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Office.Interop.Excel;
using System.IO;
namespace Cafe.Controllers
{
[Route("api/[controller]")]
[EnableCors("AllowMyOrigin")]
public class OrderController : Controller
{
private readonly DBOrderService service;
[HttpPost("create")]
public bool Create(Order order)
{
return service.Create(order);
}
[HttpPut("update")]
//[FromBody]
public bool Update(Order order)
{
return service.Update(order);
}
[HttpGet("getById/{id}")]
public Order GetById(int id)
{
return service.GetById(id);
}
48
[HttpDelete("delete/{id}")]
public bool Delete(int id)
{
return service.Remove(id);
}
[HttpGet("getAll")]
public IList<Order> GetAll()
{
return service.GetAll();
}
[HttpGet("excelDoc")]
public void WriteDataToExcel()
{
//string sheetName = "";
List<Order> orders = GetAll().ToList();
oSheet.Cells.ClearContents();
int i = 2;
foreach (Order order in orders)
{
oSheet.Cells[i, 1] = order.Id.ToString();
oSheet.Cells[i, 2] = order.Date.ToString();
oSheet.Cells[i, 3] = order.NumberTable.ToString();
oSheet.Cells[i, 4] = order.WaiterId.ToString();
oSheet.Cells[i, 5] = order.TotalPrice.ToString();
49
++i;
}
worKbooK.SaveAs("C:\\Report.xlsx");
if (worKbooK != null)
{
worKbooK.Close();
}
}
}
}
//Program.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace Cafe
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
//Startup.cs
using System;
using Cafe.Models;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Cafe.Services.DBServices;
using Microsoft.AspNetCore.Mvc.Cors.Internal;
namespace Cafe
{
public class Startup
50
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed
for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<ApplicationContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
services.AddSingleton(typeof(DBCategoryService));
services.AddSingleton(typeof(DBDishCompositionService));
services.AddSingleton(typeof(DBDishOrderInfoService));
services.AddSingleton(typeof(DBDishService));
services.AddSingleton(typeof(DBDrinkOrderInfoService));
services.AddSingleton(typeof(DBDrinkService));
services.AddSingleton(typeof(DBIngredientService));
services.AddSingleton(typeof(DBOrderService));
services.AddSingleton(typeof(DBStockService));
services.AddSingleton(typeof(DBUnitsService));
services.AddSingleton(typeof(DBWaiterService));
// This method gets called by the runtime. Use this method to configure the HTTP request
pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
51
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production
scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
//src
//index.css
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}
//index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render(
52
<App />,
document.getElementById('root')
);
serviceWorker.unregister();
//App.js
import React from 'react';
import './App.css';
import Home from './components/Home';
import Categories from './components/Category/Categories';
import Dishes from './components/Dish/Dishes';
import Drinks from './components/Drink/Drinks';
import {BrowserRouter, Route, Switch} from 'react-router-dom';
import Navigation from './components/Navigation';
import Waiters from './components/Waiter/Waiters';
import Reference from './components/ReferencesSystem/References';
import SignInModal from './components/SignInModal/SignInModal';
import Units from './components/Unit/Units';
import Stock from './components/Stock/Stock';
import Orders from './components/Order/Orders';
function App() {
return (
<BrowserRouter>
<div className="container">
<h1 className='m-3 d-flex justify-content-center'>Cafe</h1>
<Navigation/>
<Switch>
<Route path='/' component={SignInModal} exact/>
<Route path='/home' component={Home}/>
<Route path='/waiters' component={Waiters}/>
<Route path='/categories' component={Categories}/>
<Route path='/menu/dishes' component={Dishes}/>
<Route path='/menu/drinks' component={Drinks}/>
<Route path='/units' component={Units}/>
<Route path='/stock' component={Stock}/>
<Route path='/orders' component={Orders}/>
<Route path='/help' component={Reference}/>
</Switch>
</div>
</BrowserRouter>
);
}
export default App;
//App.css
.App {
text-align: center;
}
53
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
//src/components
//Home.js
import React, {Component} from 'react';
export default class Home extends Component{
render(){
return(
<div className='mt-5'>
<h1>Home</h1>
<h3>Welcome to the Cafe app</h3>
</div>
);
};
};
//Navigation.js
54
import React, {Component} from 'react';
import {NavLink} from 'react-router-dom';
import {Navbar, Nav, NavDropdown} from 'react-bootstrap';
import HelpOutlineIcon from '@material-ui/icons/HelpOutline';
export default class Navigation extends Component{
render(){
return(
<Navbar bg='dark' expand='sm'>
<Navbar.Toggle aria-controls='basic-navbar-nav'/>
<Navbar.Collapse id='basic-navbar-nav'>
<Nav className='col-sm-11'>
<NavLink className='d-inline p-2 bg-dark text-white badge-pill' to='/home'>
Home
</NavLink>
<NavLink className='d-inline p-2 bg-dark text-white badge-pill' to='/waiters'>
List of waiters
</NavLink>
<NavLink className='d-inline p-2 bg-dark text-white badge-pill' to='/categorie
s'>
Category
</NavLink>
<NavDropdown title="Menu" color='inherit'>
<NavDropdown.Item href='/menu/dishes'>Dishes</NavDropdown.Item>
<NavDropdown.Divider />
<NavDropdown.Item href='/menu/drinks'>Drinks</NavDropdown.Item>
</NavDropdown>
<NavLink className='d-inline p-2 bg-dark text-white badge-pill' to='/orders'>
List of orders
</NavLink>
<NavLink className='d-inline p-2 bg-dark text-white badge-pill' to='/units'>
Units
</NavLink>
<NavLink className='d-inline p-2 bg-dark text-white badge-pill' to='/stock'>
Stock
</NavLink>
</Nav>
<Nav>
<NavLink className='d-inline p-2 bg-dark text-white badge badge-secondary bad
ge-pill' to='/help'>
{<HelpOutlineIcon/>}
</NavLink>
</Nav>
</Navbar.Collapse>
</Navbar>
);
};
};
//src/components/Order
//AddOrderModal.js
import React, {Component} from 'react';
55
import {Modal, Row, Col, Form} from 'react-bootstrap';
import {Button} from 'react-bootstrap';
import SnackBar from '@material-ui/core/Snackbar';
import IconButton from "@material-ui/core/IconButton";
import Tooltip from '@material-ui/core/Tooltip';
import CloseIcon from '@material-ui/icons/Close';
import axios from 'axios';
import qs from 'querystring';
export default class AddOrderModal extends Component{
constructor(props){
super(props);
this.state = {waiters:[], snackBaropen: false, snackBarMessage: '',
number: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] };
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount(){
axios.get(`https://localhost:44399/api/Waiter/getAll`)
.then(res=> {
this.setState({waiters: res.data})
});
}
snackBarClose=(event)=>{
this.setState({snackBaropen: false});
}
handleSubmit=(event)=>{
event.preventDefault();
axios.post(`https://localhost:44399/api/Order/create?${qs.stringify({
Date: event.target.date.value,
NumberTable: event.target.numberTable.value,
WaiterId: event.target.waiter.value,
TotalPrice: event.target.totalPrice.value
})}`)
.then(res=> {
console.log(res.data);
this.setState({snackBaropen: true, snackBarMessage: 'Added successfully'});
})
.catch(error=> {
console.log(error);
this.setState({snackBaropen: true, snackBarMessage: 'Failed added'});
});
}
render(){
return(
<div className='container'>
<SnackBar
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
open={this.state.snackBaropen}
56
autoHideDuration={1000}
onClose={this.snackBarClose}
message={<span id='message-id'>{this.state.snackBarMessage}</span>}
action={[
<IconButton color="inherit" size="small"
onClick={this.snackBarClose}
><CloseIcon/></IconButton>
]}/>
<Modal
{...this.props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Adding order
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Row>
<Col sm={6}>
<Form onSubmit={this.handleSubmit}>
<Form.Group controlId="date">
<Form.Label>Order date</Form.Label>
<Form.Control
type="date"
name="date"
required
placeholder="Order date"/>
</Form.Group>
<Form.Group controlId="numberTable">
<Form.Label>Number table</Form.Label>
<Form.Control as="select">
{this.state.number.map(num=>
<option key={num}>{num}</option>
)}
</Form.Control>
</Form.Group>
<Form.Group controlId="waiter">
<Form.Label>Number of waiter</Form.Label>
<Form.Control as="select">
{this.state.waiters.map(waiter=>
<Tooltip key={waiter.id} title={waiter.name + ' ' + waiter.surname}
>
<option key={waiter.id}>{waiter.id}</option>
</Tooltip>
)}
</Form.Control>
</Form.Group>
<Form.Group controlId="totalPrice">
<Form.Label>Order total price</Form.Label>
<Form.Control
57
type="text"
name="totalPrice"
required
placeholder="Order total price"/>
</Form.Group>
<Form.Group>
<Button variant="primary" type="submit">
Add order
</Button>
</Form.Group>
</Form>
</Col>
</Row>
</Modal.Body>
<Modal.Footer>
<Button variant="primary" onClick={this.props.onHide}>
Close
</Button>
</Modal.Footer>
</Modal>
</div>
)
}
}
//EditOrderModal.js
import React, {Component} from 'react';
import {Modal, Row, Col, Form} from 'react-bootstrap';
import {Button} from 'react-bootstrap';
import SnackBar from '@material-ui/core/Snackbar';
import IconButton from "@material-ui/core/IconButton";
import Tooltip from '@material-ui/core/Tooltip';
import CloseIcon from '@material-ui/icons/Close';
import axios from 'axios';
import qs from 'querystring';
export default class EditOrderModal extends Component{
constructor(props){
super(props);
this.state = {waiters:[], snackBaropen: false, snackBarMessage: '',
number: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] };
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount(){
axios.get(`https://localhost:44399/api/Waiter/getAll`)
.then(res=> {
this.setState({waiters: res.data})
});
}
snackBarClose=(event)=>{
58
this.setState({snackBaropen: false});
}
handleSubmit(event){
event.preventDefault();
axios.put(`https://localhost:44399/api/Order/update?${qs.stringify({
Id: event.target.id.value,
Date: event.target.date.value,
NumberTable: event.target.numberTable.value,
WaiterId: event.target.waiter.value,
TotalPrice: event.target.totalPrice.value
})}`)
.then(res=> {
console.log(res.data);
this.setState({snackBaropen: true, snackBarMessage: 'Updated successfully'});
})
.catch(error=> {
console.log(error);
this.setState({snackBaropen: true, snackBarMessage: 'Failed to update'});
});
}
render(){
return(
<div className='container'>
<SnackBar
anchorOrigin={{vertical: 'bottom', horizontal: 'center'}}
open={this.state.snackBaropen}
autoHideDuration={1000}
onClose={this.snackBarClose}
message={<span id='message-id'>{this.state.snackBarMessage}</span>}
action={[
<IconButton color="inherit" size="small"
onClick={this.snackBarClose}
><CloseIcon/></IconButton>
]}/>
<Modal
{...this.props}
size="lg"
aria-labelledby="contained-modal-title-vcenter"
centered>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Editing order
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Row>
<Col sm={6}>
<Form onSubmit={this.handleSubmit}>
<Form.Group controlId="id">
<Form.Label>Order number</Form.Label>
59
<Form.Control
type="text"
name="id"
required
disabled
defaultValue={this.props.orderid}
placeholder="Order number"/>
</Form.Group>
<Form.Group controlId="date">
<Form.Label>Order date</Form.Label>
<Form.Control
type="date"
name="date"
required
defaultValue={this.props.orderdate}
placeholder="Order date"/>
</Form.Group>
<Form.Group controlId="numberTable">
<Form.Label>Number table</Form.Label>
<Form.Control as="select"
defaultValue={this.props.ordernt}>
{this.state.number.map(num=>
<option key={num}>{num}</option>
)}
</Form.Control>
</Form.Group>
<Form.Group controlId="waiter">
<Form.Label>Number of waiter</Form.Label>
<Form.Control as="select"
defaultValue={this.props.orderwaiter}>
{this.state.waiters.map(waiter=>
<Tooltip key={waiter.id} title={waiter.name + ' ' + waiter.surname}
>
<option key={waiter.id}>{waiter.id}</option>
</Tooltip>
)}
</Form.Control>
</Form.Group>
<Form.Group controlId="totalPrice">
<Form.Label>Order total price</Form.Label>
<Form.Control
type="text"
name="totalPrice"
required
defaultValue={this.props.ordertp}
placeholder="Order total price"/>
</Form.Group>
<Form.Group>
<Button variant="primary" type="submit">
Edit order
</Button>
</Form.Group>
</Form>
60
</Col>
</Row>
</Modal.Body>
<Modal.Footer>
<Button variant="primary" onClick={this.props.onHide}>
Close
</Button>
</Modal.Footer>
</Modal>
</div>
)
}
}
//Orders.js
import React, {Component} from 'react';
import {Table} from 'react-bootstrap';
import {Button, ButtonToolbar} from 'react-bootstrap';
import AddOrderModal from './AddOrderModal';
import EditOrderModal from './EditOrderModal';
import AddIcon from '@material-ui/icons/Add';
import EditIcon from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';
import ImportExportIcon from '@material-ui/icons/ImportExport';
import SnackBar from '@material-ui/core/Snackbar';
import CloseIcon from '@material-ui/icons/Close';
import IconButton from '@material-ui/core/IconButton';
import axios from 'axios';
export default class Orders extends Component{
constructor(props){
super(props);
this.state = {orders: [], waiters: [], snackBaropen: false, snackBarMessage: '',
addModalShow: false, editModalShow: false};
}
componentDidMount(){
axios.get(`https://localhost:44399/api/Waiter/getAll`)
.then(res=> {
this.setState({waiters: res.data})
});
this.refreshList();
}
deleteOrder(orderId){
if(window.confirm('Are you sure?')){
axios.delete(`https://localhost:44399/api/Order/delete/${orderId}`)
.then(res=> {
console.log(res.data);
61
})
.catch(error=> {
console.log(error);
});
}
}
refreshList(){
axios.get(`https://localhost:44399/api/Order/getAll`)
.then(res=> {
console.log(res.data);
this.setState({orders: res.data})
});
}
snackBarClose=(event)=>{
this.setState({snackBaropen: false});
}
export=(event)=>{
event.preventDefault();
axios.get(`https://localhost:44399/api/Order/excelDoc`)
.then(res=>{
this.setState({snackBaropen: true, snackBarMessage: `File is located ${res.data}`});
})
.catch(error=> {
console.log(error);
this.setState({snackBaropen: true, snackBarMessage: 'Failed export'});
});
}
componentDidUpdate(){
this.refreshList();
}
render(){
const {orders, waiters, orderId, orderDate, orderNumberTable, orderWaiter, orderTotalPri
ce} = this.state;
const addModalClose=()=>this.setState({addModalShow:false});
const editModalClose=()=>this.setState({editModalShow:false});
return(
<div>
<SnackBar
anchorOrigin={{ vertical: 'bottom', horizontal: 'center' }}
open={this.state.snackBaropen}
autoHideDuration={3000}
onClose={this.snackBarClose}
message={<span id='message-id'>{this.state.snackBarMessage}</span>}
action={[
<IconButton
color="inherit"
size="small"
onClick={this.snackBarClose}
62
>
<CloseIcon />
</IconButton>
]}/>
<Table className='mt-4' size='sm'>
<thead>
<tr>
<th>Order number</th>
<th>Order date</th>
<th>Number table</th>
<th>Waiter</th>
<th>Order total price</th>
<th>Options</th>
</tr>
</thead>
<tbody>
{orders.map(order=>
<tr key={order.id}>
<td>{order.id}</td>
<td>{new Date(order.date).toLocaleDateString('en-GB')}</td>
<td>{order.numberTable}</td>
<td>{waiters.map(w=>{if(w.id === order.waiterId){return w.name +' '+ w.su
rname}})}</td>
<td>{order.totalPrice}</td>
<td>
<ButtonToolbar>
<Button
variant="success"
onClick={()=>this.setState({
editModalShow: true,
orderId: order.id,
orderDate: order.date,
orderNumberTable: order.numberTable,
orderWaiter: order.waiter,
orderTotalPrice: order.totalPrice
})}>
{<EditIcon/>}
</Button>
<div className="mr-2"></div>
<Button className="mr-2"
variant="secondary"
onClick={()=>this.deleteOrder(order.id)}>
{<DeleteIcon/>}
</Button>
<EditOrderModal
show={this.state.editModalShow}
onHide={editModalClose}
orderid={orderId}
orderdate={orderDate}
63
ordernt={orderNumberTable}
orderwaiter={orderWaiter}
ordertp={orderTotalPrice}
/>
</ButtonToolbar>
</td>
</tr>
)}
</tbody>
</Table>
<ButtonToolbar>
<Button
variant="danger"
onClick={()=>this.setState({addModalShow: true})}>
{<AddIcon/>}
Add order
</Button>
<div className="mr-2"/>
<Button
className="mr-2"
variant='secondary'
type='submit'
onClick={this.export}>
{<ImportExportIcon/>}
Export all to Excel
</Button>
<AddOrderModal
show={this.state.addModalShow}
onHide={addModalClose}/>
</ButtonToolbar>
</div>
)
}
}
//src/components/ReferencesSystem
//references.css
.app-header {
width: 100vw;
margin-top: 3%;
}
h2 {
font-size: 1.2rem;
color: grey;
}
.span-style {
margin-left: 3%;
64
font-size: 1.2rem;
color: grey;
}
li {
margin-left: 3%;
font-size: 1.2rem;
color: grey;
}
//References.js
import React, {Component} from 'react';
import './references.css';
import AddIcon from '@material-ui/icons/Add';
import EditIcon from '@material-ui/icons/Edit';
import DeleteIcon from '@material-ui/icons/Delete';
import {Button, ButtonToolbar} from 'react-bootstrap';
import HelpOutlineIcon from '@material-ui/icons/HelpOutline';
import {Modal, Row, Col, Form} from 'react-bootstrap';
export default class References extends Component{
constructor(props){
super(props);
this.state = {addModalShow: false, editModalShow: false, deleteModalShow: false};
}
render(){
if(this.state.deleteModalShow){
window.confirm('Are you sure?')
}
const {addModalShow, editModalShow} = this.state;
const addModalClose=()=>this.setState({addModalShow:false});
const editModalClose=()=>this.setState({editModalShow:false});
return(
<div>
<h1>References system</h1>
<h2>Данное приложение разработано для
автоматизации работы администратора кафе(рестона). С помощью данного при
ложения
управляющий может с лёгкостью вести учёт своей работы.</h2>
<div>
<ButtonToolbar>
<div className='app-header'>
<Button onClick={()=>this.setState({addModalShow: true})}
variant="danger" >
{<AddIcon/>}
Add ...
</Button>
<span className='span-style'>Кнопка для функции добавления.
Нажав на неё отобразиться модель для добавления нового элемента в список.
</span>
<div>
65
<Modal
size="lg"
show={addModalShow}
onHide={addModalClose}
aria-labelledby="contained-modal-title-vcenter"
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Adding ...
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Row>
<Col sm={6}>
<Form onSubmit={this.handleSubmit}>
<Form.Group controlId="name">
<Form.Label>Label</Form.Label>
<Form.Control
type="text"
placeholder="Label"/>
</Form.Group>
<Form.Group>
<Button variant="primary">
Add ...
</Button>
</Form.Group>
</Form>
</Col>
</Row>
</Modal.Body>
<Modal.Footer>
<Button variant="primary" onClick={addModalClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</div>
</div>
<div className='app-header'>
<Button onClick={()=>this.setState({editModalShow: true})}
variant="success">
{<EditIcon/>}
</Button>
<span className='span-style'>Кнопка для функции редактирования.
Нажав на неё отобразиться модель для редактирования выбраного элемента в
списоке со старыми данными.</span>
<div>
<Modal
size="lg"
show={editModalShow}
66
onHide={editModalClose}
aria-labelledby="contained-modal-title-vcenter"
>
<Modal.Header closeButton>
<Modal.Title id="contained-modal-title-vcenter">
Editing ...
</Modal.Title>
</Modal.Header>
<Modal.Body>
<Row>
<Col sm={6}>
<Form onSubmit={this.handleSubmit}>
<Form.Group controlId="name">
<Form.Label>Label</Form.Label>
<Form.Control
type="text"
placeholder="Label"/>
</Form.Group>
<Form.Group>
<Button variant="primary">
Edit ...
</Button>
</Form.Group>
</Form>
</Col>
</Row>
</Modal.Body>
<Modal.Footer>
<Button variant="primary" onClick={editModalClose}>
Close
</Button>
</Modal.Footer>
</Modal>
</div>
</div>
<div className='app-header'>
<Button onClick={()=>this.setState({deleteModalShow: true})}
variant="secondary">
{<DeleteIcon/>}
</Button>
<span className='span-style'>Кнопка для функции удаления.
Нажав на неё отобразиться окно соглашения на удаление выбраного элемент
а из списка.</span>
</div>
</ButtonToolbar>
<div className='app-header'>
<h2>Панель меню:</h2>
<li>Home - главная страница приложения. Приветствует пользователя.</li>
<li>List of waiters - страница для просмотра и работы со списком обслуживаю
щего персонала.</li>
67
<li>Category - страница для просмотра и работы со списком существующих к
атегорий блюд и напитков.</li>
<li>Menu/Dishes - страница для просмотра и работы со списком существующ
их блюд.</li>
<li>Menu/Drinks - страница для просмотра и работы со списком существующ
их напитков.</li>
<li>Stock - страница для просмотра и ведения учёта наличия ингредиентов.</
li>
<li>Order - страница для просмотра и ведения учёта сделанных заказов.</li>
<li>{<HelpOutlineIcon/>} - страница справочной системы.</li>
</div>
</div>
</div>
);
}
};
//src/components/SearchPanel
//SearchPanel.js
import React, {Component} from 'react';
export default class SearchPanel extends Component{
constructor(props){
super(props);
this.state = {search: ''};
}
onLabelSearch=(event)=>{
const search = event.target.value;
this.setState({search});
this.props.onLabelSearch(search);
};
render(){
const {search} = this.state;
return(
<div>
<input type="text" className="form-control" placeholder='Search...' value={search}
onChange={this.onLabelSearch}/>
</div>
)
}
}
//src/components/SignInModal
//SignInModal.js
import React, {Component} from 'react';
import './signIn.css';
import {Modal, Row, Col, Form, Button} from 'react-bootstrap';
import { createBrowserHistory } from 'history';
export default class SignInModal extends Component{
68
constructor(props){
super(props);
this.state = { show: true};
}
handleSubmit(event){
event.preventDefault();
const customHistory = createBrowserHistory();
if((event.target.adminName.value === 'admin') && (event.target.password.value === 'ad
min')){
return customHistory.go(customHistory.push('/home'));
}
}
render(){
const {show} = this.state;
return(
<div>
<Modal show={show}
size='sm'
centered>
<Modal.Body>
<Row>
<Col>
<Form onSubmit={this.handleSubmit}>
<Form.Label className='h2 mb-3 font-weight-normal d-flex justify-
content-center'>Please sign in</Form.Label>
<Form.Group>
<Form.Control
type="text"
size='lg'
name='adminName'
required
autoFocus
placeholder="AdminName"/>
<Form.Control
type="text"
size='lg'
name="password"
required
placeholder="Password"/>
</Form.Group>
<Form.Group>
<Button
className='btn-block mb-3'
size='lg'
variant="primary"
type="submit">
Sign in
</Button>
</Form.Group>
</Form>
</Col>
</Row>
</Modal.Body>
69
<Modal.Footer>
<Form.Label>AdminName: admin</Form.Label>
<Form.Label>Password: admin</Form.Label>
</Modal.Footer>
</Modal>
</div>
)
}
}
70
Приложение Б
(справочное)
Формы выходных документов
Данный проект создает выходной документ Excel содержащий все оформленные заказы
в кафе, данный документ представлен на рисунке Б.1.
71
КП Т.795003 ГЧ
Программное средство
для автоматизации
рабочего места
администратора кафе
Диаграмма вариантов 72
использования
КП Т.795003 ГЧ
Программное средство
для автоматизации
рабочего места
администратора кафе
Диаграмма классов
73
КП Т.795003 ГЧ
Программное средство
для автоматизации
рабочего места
администратора кафе
74
КП Т.795003 ГЧ
Диаграмма деятельности
КП Т.795003.401 ГЧ
Лит.
Масса
Масштаб
Программное средство
для автоматизации
рабочего места
администратора кафе
Диаграмма 75
последовательности
КП Т.795003 ГЧ
Программное средство
для автоматизации
рабочего места
администратора кафе
Диаграмма компонентов
76