Показаны сообщения с ярлыком my project. Показать все сообщения
Показаны сообщения с ярлыком my project. Показать все сообщения

воскресенье, 29 августа 2010 г.

Разработка многопользовательской автоматизированной системы управления железнодорожным вокзалом

Сначала опишем FDS системы.

1. Введение

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

1.1 Назначение

Б.Д. в первую очередь предназначена для: кассиров вокзала, операторов вокзала и потенциальных закасчиков, для облегчения покупки/продажи железнодорожного билета.

1.2 Обзор

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

1.3 Определения и принятые сокращения

В настоящем документе приняты следующие определения и сокращения:

Сокращение

Определение

Б.д.

Базы данных

Слово “должен” определяет необходимое требование к продукту. Слова “может”, “предполагает”, “способен” определяют направление работ, которое подлежит дальнейшему уточнению.


2. Общее описание

2.1 Функции продукта

2.1.1 Учет вагонов, поездов и составов.
2.1.2 Формирование пути следования составов.
2.1.3 Составление расписания движения составов.
2.1.4 Учет проданных билетов.
2.1.5 Функция продажи билетов.
2.1.6 Поиск рейсов для заданных станций отправления и прибытия и заданного диапазона дат отправления.
2.1.7 Получение информации о наличии билетов с разбивкой по классам для заданного рейса.
2.1.8 Хранение информации об составах, поездах, станциях….

2.2 Характеристика пользователей

2.2.1 Пользователь должен иметь навыки работы с РС .

2.3 Общие требования и ограничения

2.3.1 Разработка осуществляется с использованием средств MS SQL Server.

2.3.2 Для функционирования продукта требуется ОС Win32 (Windows95/98/Me/NT/2000/XP), аппаратные средства, обеспечивающие работу данной ОС, и MS SQL Server.

* Процессор Pentium на 133 МГц или более мощный (P5 или совместимый). На которой може работать система Windows 2000 Professional .

* Рекомендуется иметь не менее 64 мегабайт (Мбайт) ОЗУ. Минимально возможный объем ОЗУ - 32Мбайт. Максимальный объем ОЗУ - 4Гбайт.

* Жесткий диск емкостью 2Гбайт, имеющий не менее 650Мбайт свободного места. При установке по сети требуется больший объем свободного места на жестком диске.

* Монитор VGA или с более высоким разрешением.

* Клавиатура.

* Мышь Microsoft Mouse или совместимое указывающее устройство (необязательно).


3. Специфические требования

3.1 Ограничения на данные

Категория данных

Данные

Ограничения

Билет

номер билета

Только цифры

Дата отправления

Только цифры

Дата прибытия

Только цифры

Стоимость

Только цифры

ФИО

Только буквы,до 30 символов

Вагон

Модель вагона

Только буквы,до 6 символов

ID тип вагона

Только цифры

ID класс вагона

Только цифры

ID категория вагона

Только цифры

ID владелец станции

Только цифры

Категории вагона

ID

Только цифры

Название категории

буквы, до 15 символов

Классы вагона

ID

Только цифры

Название класса

буквы, до 15 символов

Место

ID

Только цифры

Модель вагона

буквы, до 6 символов

Номер места

Только цифры

Тип места

буквы, до 4 символов

Поезд

Номер поезда

буквы, до 6 символов

Название поезда

буквы, до 30 символов

Дата начала следования

цифры,11 символов

Дата окончания следования

цифры,11 символов

Расписание

ID

Только цифры

Путь ID

Только цифры

Дата

цифры,11 символов

Состав

ID

Только цифры

Номер поезда

буквы, 6 символов

Номер вагона

буквы, 6 символов

Номер вагона в составе

Только цифры

От станции ID

Только цифры

До станции ID

Только цифры

Станция

Название

цифры, 3 символа

Страна

буквы, 15 символов

Область

буквы, 30 символов

ID

буквы, 15 символов

Типы вагонов

ID

буквы, 30 символов

Название типа

буквы, 20 символов

3.2 Функции пользователей

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

3.2.2.

3.2.2 Функции кассира
А) функция продажи билетов

Б) поиск рейсов для заданных станций отправления и прибытия и заданного

диапазона дат отправления.

Г) получение информации о наличии билетов с разбивкой по классам

для заданного рейса..

3.2.3 Функции оператора

А) учет вагонов, поездов и составов

Б формирование пути следования составов.

В) составление расписания движения составов

Г) учет проданных билетов

3.2.4 Функции покупателя

А) поиск рейсов для заданных станций отправления и прибытия и заданного

диапазона дат отправления.

Б) получение информации о наличии билетов с разбивкой по классам

для заданного рейса..

Конкретная реализация б.д. разрабатывается только для работы на локальной машине.

Перейдём к описанию реализации.

HLD

1. Описание структуры проекта

1.1. Структура приложения

clip_image001

1.2. Структура данных

clip_image003


2. Описание взаимосвязей модулей и интерфейсного взаимодействия

2.1. Окно выбора пользователя

Данное окно содержит выпадающий список пользователей (ListBox) и поле ввода пароля. Также на форме присутствует кнопка OK. При неправильном вводе пароля выводится сообщение: «Password incorrect! При корректном выборе имени пользователя и пароля, появляется одна из форм: форма пользователя; форма кассира; форма оператора.

2.2. Читатель

Форма пользователя выполнена в виде диалогового окна, где присутствуют элементы, позволяющие производить поиск по станции отправления, прибытия , и промежутку дат.

На форме присутствуют следующие элементы: поля для ввода станции отправления, станции прибытия,. Календарь для указания диапазона дат. Кнопки «Find»,”About train”,”About ticket” и «Booking».

Результат поиска выводится в виде таблицы: название поезда и, номер поезда, дата отправления/приьытия. При однократном щелчке мыши по кнопке “ About train”– можно посмотреть полный путь следования выбранного поезда. При однократном щелчке мыши по кнопке “ About ticket”-можно посмотреть информацию о налилии.

2.3. Кассир

Форма пользователя выполнена в виде диалогового окна, где присутствуют элементы, позволяющие производить поиск по станции отправления, прибытия , и промежутку дат.

На форме присутствуют следующие элементы: поля для ввода станции отправления, станции прибытия,. Календарь для указания диапазона дат. Кнопки «Find»,”About train”,”About ticket” и «Booking».

Результат поиска выводится в виде таблицы: название поезда и, номер поезда, дата отправления/приьытия. При однократном щелчке мыши по кнопке “ About train”– можно посмотреть полный путь следования выбранного поезда. При однократном щелчке мыши по кнопке “ About ticket”-можно посмотреть информацию о налилии.

При однократном щелчке мыши по кнопке “Booking”-мы видим окно продаи билета. В пустое поле нужно ввести фамилию покупателья и нажать на кнопку “Booking”- произойдёт продажа ьилета.

2.4. Оператор

При нажатии на кнопку “Snanion” оператор попадает в окно редактирования станций.Здесь реализоваа возможность добавления новой станции и удаление ненужных станций.Для добавления нужно нажать кнопку “Add”, азатем заполнить все необходимые поля.Затем нажать “Update”. Для удаления необходимо нажать на кнопку “Delete”, будет удалена выделенная курсором станция.

При нажатии н кнопку “Ticket”, оператор может видеть отчёт о вскх купленных билетах.

 

Журнал тестирования

1 Назначение

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

2. Процедурные шаги

[1] Включить компьютер.

[2] Старт блока.

[3] Запустить программу.

[4] Выбрать в поле Login пользователя «User» ввести пароль «111» и нажать кнопку «Enter». Убедиться, что появилось окно поиска поезда.

[5] Ввести в поле «First station» название нужной станци и проверить нахождение ее в базе данных.

[6] Ввести в поле «First station» название нужной станци и проверить нахождение ее в базе данных.

[7] Выбрать нужный диапазон дат

[8] Нажать на “Find train”.

[9] Убедиться что происходит поиск поездов.

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

[11] Нажать на “About Train”,проверить возможность просмотра информации о поезде.

[12] Вернуться к меню выбора пользователя, нажав кнопку «Cancel».

[13] Выбрать в поле Login пользователя «Cassier», ввести пароль «333» и нажать кнопку «Enter». Проверить выдачу сообщения об ошибке при вводе неправильного пароля. Убедиться, что появилось окно «кассира».

[14] Проверить работоспособность и корректное отображение инвормации “About Train” и “About Ticket”

[15] Выбрать нужный билет и нажать “Booking”.

[16] Проверить корректна ли информация о билете.

[17] Ввести Фамилию.

[18] Проверить контроль ошибок при вводе ложных данных.

[19] Выбрать в поле Login пользователя «Operator», ввести пароль «222» и нажать кнопку «Enter». Проверить выдачу сообщения об ошибке при вводе неправильного пароля. Убедиться, что появилось окно «оператора».

[20] Проверить работоспособность окна “Station”.

[21] Протестировать корректность добавления новой станции, введя все необходимые поля и нажав соответствующую кнопку.

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

[23] Протестировать корректность удаления станции.

[24] Нажать на кнопку“Ticket”

[25] Проверить информацию о всех купленных билетах.

[26] Вернуться к меню выбора пользователя, нажав кнопку «Cancel».

[27] Протестировать корректный выход из приложения.

Разработка многопользовательской автоматизированной системы управления организацией. – Часть 2 (HLD)

1. Введение

1.1 Назначение

Цель данного проекта – разработать автоматизированную систему управления организацией. Область применения – Телефонная станция. Система должна упростить работу сотрудников по управлению организацией, тем самым позволяя сосредоточить свое внимание на основной работе.

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

1.2 Реализация

Проект реализуется при помощи MS SQL Server 2000 & MS Visual Studio .NET 2003.

Клиентская часть пишется на C#.

Для доступа к данным будет использована технология ADO.NET.

1.3 Определения и принятые сокращения

В настоящем документе приняты следующие определения и сокращения:

Сокращение

Определение

БД

База Данных

ОС

Операционная Система


2. Описание структуры и взаимосвязей

2.1 Структура базы данных:

Структура связей:

clip_image002

Текст на SQL для создания базы данных:

/********************* Создание таблиц *********************/

CREATE TABLE Service(

ServiceID int NOT NULL IDENTITY(1,1),

AccessType int NOT NULL,

[Description] char(100) NOT NULL,

CONSTRAINT ServiceID_PK

PRIMARY KEY (ServiceID)

);

CREATE TABLE DiscontType(

DiscontTypeID int NOT NULL IDENTITY(1,1),

Rate int NOT NULL,

[Description] char(100) NOT NULL,

CONSTRAINT DiscontTypeID_PK

PRIMARY KEY (DiscontTypeID)

);

CREATE TABLE City(

CityID int NOT NULL IDENTITY(1,1),

City char(50) NOT NULL,

CityCode char(50) NOT NULL,

Cost money NOT NULL,

CONSTRAINT CityID_PK

PRIMARY KEY (CityID)

);

CREATE TABLE CrashType(

CrashTypeID int NOT NULL IDENTITY(1,1),

[Description] char(100) NOT NULL,

CONSTRAINT CrashTypeID_PK

PRIMARY KEY (CrashTypeID)

);

CREATE TABLE AbonentType(

AbonentTypeID int NOT NULL IDENTITY(1,1),

DiscontTypeID int NOT NULL,

Cost money NOT NULL,

CONSTRAINT AbonentTypeID_PK

PRIMARY KEY (AbonentTypeID),

CONSTRAINT DiscontType_FK

FOREIGN KEY (DiscontTypeID)

REFERENCES DiscontType(DiscontTypeID)

);

CREATE TABLE Abonent(

AbonentID int NOT NULL IDENTITY(1,1),

FName char(50) NOT NULL,

LName char(50) NOT NULL,

Company char(50) NULL,

AbonentTypeID int NOT NULL,

State bit NOT NULL,

CONSTRAINT AbonentID_PK

PRIMARY KEY (AbonentID),

CONSTRAINT AbonentType_FK

FOREIGN KEY (AbonentTypeID)

REFERENCES AbonentType(AbonentTypeID)

);

CREATE TABLE Receipt(

ReceiptID int NOT NULL IDENTITY(1,1),

AbonentID int NOT NULL,

LocalCost money NOT NULL,

TrunkCallCost money NOT NULL,

State bit NOT NULL,

[Date] smalldatetime NOT NULL,

PayDate smalldatetime NULL,

CONSTRAINT ReceiptID_PK

PRIMARY KEY (ReceiptID),

CONSTRAINT AbonentID_FK

FOREIGN KEY (AbonentID)

REFERENCES Abonent(AbonentID)

ON UPDATE CASCADE

ON DELETE CASCADE

);

CREATE TABLE [User](

UserID int NOT NULL IDENTITY(1,1),

FName char(50) NOT NULL,

LName char(50) NOT NULL,

ServiceID int NOT NULL,

UserName char(50) NOT NULL,

[Password] char(50) NULL,

CONSTRAINT UserID_PK

PRIMARY KEY (UserID),

CONSTRAINT UserName_AK

UNIQUE (UserName),

CONSTRAINT ServiceID_FK

FOREIGN KEY (ServiceID)

REFERENCES Service(ServiceID)

ON UPDATE CASCADE

ON DELETE CASCADE

);

CREATE TABLE Phone(

PhoneID int NOT NULL IDENTITY(1,1),

AbonentID int NOT NULL,

Number char(50) NOT NULL,

State bit NOT NULL,

CONSTRAINT PhoneID_PK

PRIMARY KEY (PhoneID),

CONSTRAINT Number_AK

UNIQUE (Number),

CONSTRAINT AbonentID2_FK

FOREIGN KEY (AbonentID)

REFERENCES Abonent(AbonentID)

ON UPDATE CASCADE

ON DELETE CASCADE

);

CREATE TABLE Crash(

CrashID int NOT NULL IDENTITY(1,1),

CrashTypeID int NOT NULL,

PhoneID int NOT NULL,

RegDate smalldatetime NOT NULL,

FixDate smalldatetime NOT NULL,

UserID int NOT NULL,

FixReal smalldatetime NULL,

CONSTRAINT CrashID_PK

PRIMARY KEY (CrashID),

CONSTRAINT UserID_FK

FOREIGN KEY (UserID)

REFERENCES [User](UserID)

ON UPDATE CASCADE

ON DELETE CASCADE,

CONSTRAINT CrashTypeID_FK

FOREIGN KEY (CrashTypeID)

REFERENCES CrashType(CrashTypeID)

ON UPDATE CASCADE

ON DELETE CASCADE,

CONSTRAINT PhoneID_FK

FOREIGN KEY (PhoneID)

REFERENCES Phone(PhoneID)

ON UPDATE CASCADE

ON DELETE CASCADE

);

CREATE TABLE CallLog(

CallLogID int NOT NULL IDENTITY(1,1),

PhoneID int NOT NULL,

CallDate smalldatetime NOT NULL,

LongTime int NOT NULL,

LocalCall bit NOT NULL,

CityID int NULL,

ReceiptState bit NULL,

CONSTRAINT CallLogID_PK

PRIMARY KEY (CallLogID),

CONSTRAINT CityID_FK

FOREIGN KEY (CityID)

REFERENCES City(CityID)

ON UPDATE CASCADE

ON DELETE CASCADE,

CONSTRAINT PhoneID2_FK

FOREIGN KEY (PhoneID)

REFERENCES Phone(PhoneID)

ON UPDATE CASCADE

ON DELETE CASCADE,

);

CREATE TABLE Archive(

AbonentID int NOT NULL,

FName char(50) NOT NULL,

LName char(50) NOT NULL,

Company char(50) NULL,

State bit NOT NULL,

Cost money NOT NULL,

Rate int NOT NULL,

CONSTRAINT Archive_PK

PRIMARY KEY (AbonentID),

);

/********************* Триггеры *********************/

IF EXISTS (SELECT name

FROM sysobjects

WHERE name = N'Tri_Del_Abonent'

AND type = 'TR')

DROP TRIGGER Tri_Del_Abonent

GO

-- При удалении данных из таблицы Abonent переносит все дданные об абоненте в таблицу Archive

CREATE TRIGGER Tri_Del_Abonent

ON Abonent

FOR DELETE

AS

INSERT Archive (AbonentID, FName, LName, Company, State, Cost, Rate) SELECT AbonentID, FName, LName, Company, State, AbonentType.Cost, DiscontType.Rate

FROM (Deleted INNER JOIN AbonentType ON Deleted.AbonentTypeID=AbonentType.AbonentTypeID)

INNER JOIN DiscontType ON DiscontType.DiscontTypeID=AbonentType.DiscontTypeID

ORDER BY Deleted.LName

GO

IF EXISTS (SELECT name

FROM sysobjects

WHERE name = N'Tri_Del_AbonentType'

AND type = 'TR')

DROP TRIGGER Tri_Del_AbonentType

GO

-- Перед удалением типа абонента вызывает Tri_Del_Abonent

CREATE TRIGGER Tri_Del_AbonentType

ON AbonentType

INSTEAD OF DELETE

AS

DELETE FROM Abonent WHERE AbonentTypeID IN (SELECT AbonentTypeID FROM Deleted)

GO

IF EXISTS (SELECT name

FROM sysobjects

WHERE name = N'Tri_Ins_Abonent'

AND type = 'TR')

DROP TRIGGER Tri_Ins_Abonent

GO

-- Проверяет имя и фамилию абонента на наличие чисел

CREATE TRIGGER Tri_Ins_Abonent

ON Abonent

FOR INSERT, UPDATE

AS

DECLARE @nCount int

SELECT @nCount = COUNT(Inserted.AbonentID) FROM Abonent, Inserted

WHERE (Abonent.AbonentID = Inserted.AbonentID) AND

((Inserted.LName LIKE '%[0-9]%') OR (Inserted.FName LIKE '%[0-9]%'))

IF @nCount <> 0

BEGIN

ROLLBACK TRAN

RAISERROR('Имя и фамилия не должны содержать числа!', 16, 10)

END

GO

IF EXISTS (SELECT name

FROM sysobjects

WHERE name = N'Tri_Ins_Abonent'

AND type = 'TR')

DROP TRIGGER Tri_Ins_Abonent

GO

-- Проверяет имя и фамилию пользователя БД на наличие чисел

CREATE TRIGGER Tri_Ins_User

ON [User]

FOR INSERT, UPDATE

AS

DECLARE @nCount int

SELECT @nCount = COUNT(Inserted.UserID) FROM [User], Inserted

WHERE ([User].UserID = Inserted.UserID) AND

((Inserted.LName LIKE '%[0-9]%') OR (Inserted.FName LIKE '%[0-9]%'))

IF @nCount <> 0

BEGIN

ROLLBACK TRAN

RAISERROR('Имя и фамилия не должны содержать числа!', 16, 10)

END

GO

IF EXISTS (SELECT name

FROM sysobjects

WHERE name = N'Tri_Del_DiscontType'

AND type = 'TR')

DROP TRIGGER Tri_Del_DiscontType

GO

-- Не позволяет удалять данные из таблицы DiscontType если существуют типы абоненты, имеющие данный тип скидки

CREATE TRIGGER Tri_Del_DiscontType

ON DiscontType

INSTEAD OF DELETE

AS

IF @@ROWCOUNT > 1

BEGIN

ROLLBACK TRAN

RAISERROR('Из этой таблицы можно удалять данные только по одной записи!', 16, 10)

END

DECLARE @iDiscontType int

SELECT @iDiscontType = Deleted.DiscontTypeID FROM DiscontType, Deleted

WHERE Deleted.DiscontTypeID = DiscontType.DiscontTypeID

IF EXISTS (SELECT * FROM AbonentType WHERE DiscontTypeID = @iDiscontType)

BEGIN

ROLLBACK TRAN

RAISERROR('Невозможно удалить запись т.к. существуют типы абоненты, имеющие данный тип скидки', 16, 10)

END

GO

/********************* Хранимые процедуры *********************/

IF EXISTS (SELECT name

FROM sysobjects

WHERE name = 'MDFOM'

AND type = 'P')

DROP PROCEDURE MDFOM

GO

-- Возвращает кол-во дней по номеру месяца

CREATE PROC MDFOM

@month int,

@maxday int OUTPUT

AS

IF((@month = 4) OR (@month = 6) OR (@month = 9) OR (@month = 11)) SET @maxday = 30

ELSE IF (@month = 2) SET @maxday = 28

ELSE SET @maxday = 31

GO

IF EXISTS (SELECT name

FROM sysobjects

WHERE name = 'DateTimeRandGenerator'

AND type = 'P')

DROP PROCEDURE DateTimeRandGenerator

GO

-- Генерирует случайную дату в заданном диапазоне

CREATE PROC DateTimeRandGenerator

@DTStart smalldatetime,

@DTStop smalldatetime,

@NewDate smalldatetime OUTPUT

AS

SET @NewDate = '01/01/1900 00:00:00'

DECLARE @dy int

DECLARE @dm int

DECLARE @dd int

DECLARE @dh int

DECLARE @dmin int

DECLARE @ds int

DECLARE @ny int

DECLARE @nm int

DECLARE @nd int

DECLARE @nh int

DECLARE @nmin int

DECLARE @ns int

DECLARE @maxday int

SET @dy = DATEPART(year, @DTStop) - DATEPART(year, @DTStart)

IF(@dy = 0)

BEGIN

SET @ny = DATEPART(year, @DTStop)

SET @dm = DATEPART(month, @DTStop) - DATEPART(month, @DTStart)

IF(@dm = 0)

BEGIN

SET @nm = DATEPART(month, @DTStop)

SET @dd = DATEPART(day, @DTStop) - DATEPART(day, @DTStart)

IF(@dd = 0) SET @nd = DATEPART(day, @DTStop)

ELSE SET @nd = DATEPART(day, @DTStart) + ROUND((RAND() * @dd),0)

END

ELSE

BEGIN

SET @nm = DATEPART(month, @DTStart) + ROUND(RAND() * @dm,0)

EXEC MDFOM @nm, @maxday OUTPUT

IF(@nm = DATEPART(month, @DTStart))

SET @nd = DATEPART(day, @DTStart) + ROUND(RAND() * (@maxday - DATEPART(day, @DTStart)),0)

ELSE IF(@nm = DATEPART(day, @DTStop))

SET @nd = 1 + ROUND(RAND() * (DATEPART(day, @DTStop) - 1),0)

ELSE

SET @nd = 1 + ROUND(RAND() * (@maxday - 1), 0)

END

END

ELSE

BEGIN

SET @ny = DATEPART(year, @DTStart) + ROUND(RAND() * @dy,0)

IF(@ny = DATEPART(year, @DTStart))

BEGIN

SET @nm = DATEPART(month, @DTStart) + ROUND(RAND() * (12 - DATEPART(month, @DTStart)),0)

EXEC MDFOM @nm, @maxday OUTPUT

IF(@nm = DATEPART(month, @DTStart))

SET @nd = DATEPART(day, @DTStart) + ROUND(RAND() * (@maxday - DATEPART(day, @DTStart)),0)

ELSE

SET @nd = 1 + ROUND(RAND() * (@maxday - 1), 0)

END

ELSE IF(@ny = DATEPART(year, @DTStop))

BEGIN

SET @nm = 1 + ROUND(RAND() * (DATEPART(month, @DTStop) - 1),0)

EXEC MDFOM @nm, @maxday OUTPUT

IF(@nm = DATEPART(day, @DTStop))

SET @nd = 1 + ROUND(RAND() * (DATEPART(day, @DTStop) - 1),0)

ELSE

SET @nd = 1 + ROUND(RAND() * (@maxday - 1), 0)

END

ELSE

BEGIN

SET @nm = 1 + ROUND(RAND() * 11, 0)

EXEC MDFOM @nm, @maxday OUTPUT

SET @nd = 1 + ROUND(RAND() * (@maxday - 1), 0)

END

END

SET @nh = ROUND(RAND() * 23, 0)

SET @nmin = ROUND(RAND() * 59, 0)

SET @ns = ROUND(RAND() * 59, 0)

SET @NewDate = DATEADD(year, @ny - 1900, @NewDate)

SET @NewDate = DATEADD(month, @nm - 1, @NewDate)

SET @NewDate = DATEADD(day, @nd - 1, @NewDate)

SET @NewDate = DATEADD(hour, @nh, @NewDate)

SET @NewDate = DATEADD(minute, @nmin, @NewDate)

SET @NewDate = DATEADD(second, @ns, @NewDate)

GO

IF EXISTS (SELECT name

FROM sysobjects

WHERE name = 'CallGenerator'

AND type = 'P')

DROP PROCEDURE CallGenerator

GO

-- Генератор звонков - заполняет таблицу CallLog

CREATE PROC CallGenerator

@DTStart smalldatetime, -- Дата начала звонков

@DTStop smalldatetime, -- Дата окончания звонков

@LStart int, -- Минимальное время разговора

@LStop int, -- Максимальное время разговора

@LocalStopCycle int, -- Количество локальных звонков

@CityStopCycle int -- Количество междугородних звонков

AS

DECLARE @StopCycle int

DECLARE @PhoneID int

DECLARE @CallDate smalldatetime

DECLARE @LongTime int

DECLARE @LocalCall bit

DECLARE @CityID int

DECLARE @CountPhoneID int

DECLARE @CountCityID int

DECLARE @CountCycle int

DECLARE @MaxCycle int

SET @CountCycle = 0

SET @StopCycle = 0

DECLARE curPhone CURSOR LOCAL SCROLL KEYSET READ_ONLY

FOR SELECT PhoneID FROM Phone

DECLARE curCity CURSOR LOCAL SCROLL KEYSET READ_ONLY

FOR SELECT CityID FROM City

SET @StopCycle = @LocalStopCycle

SET @LocalCall = 1

SET @MaxCycle = 0

SET @CityID = NULL

CREATE TABLE #TempCallLog(

PhoneID int NOT NULL,

CallDate smalldatetime NOT NULL,

LongTime int NOT NULL,

LocalCall bit NOT NULL,

CityID int NULL,

ReceiptState bit NULL,

);

BEGIN TRAN

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

WHILE (@MaxCycle < 2)

BEGIN

SET @CountCycle = 0

WHILE (@CountCycle < @StopCycle)

BEGIN

-- Открываем курсор

OPEN curPhone

-- Инкрементируем счётчик цикла

SET @CountCycle = @CountCycle + 1

IF(@@CURSOR_ROWS = 0)

BEGIN

RAISERROR('Невозможно чтение из таблицы Phone', 16, 10)

ROLLBACK TRAN

END

-- Случайиым образом выбираем телефон

SET @CountPhoneID = 1 + ROUND(RAND() * (@@CURSOR_ROWS - 1), 0)

FETCH ABSOLUTE @CountPhoneID FROM curPhone INTO @PhoneID

-- Генерируем случайную дату в заданном диапазоне

EXECUTE DateTimeRandGenerator @DTStart, @DTStop, @CallDate OUTPUT

-- Генерируем случайное значение времени разговора в заданном диапазоне

SET @LongTime = @LStart + ROUND(RAND() * (@LStop - @LStart), 0)

-- Если межгород

IF(@LocalCall = 0)

BEGIN

OPEN curCity

IF(@@CURSOR_ROWS = 0)

BEGIN

RAISERROR('Невозможно чтение из таблицы City', 16, 11)

ROLLBACK TRAN

END

-- Случайно выбираем город

SET @CountCityID = 1 + ROUND(RAND() * (@@CURSOR_ROWS - 1), 0)

FETCH ABSOLUTE @CountCityID FROM curCity INTO @CityID

CLOSE curCity

END

INSERT INTO #TempCallLog (PhoneID, CallDate, LongTime, LocalCall, CityID)

VALUES (@PhoneID, @CallDate, @LongTime, @LocalCall, @CityID)

CLOSE curPhone

END

SET @LocalCall = 0

SET @MaxCycle = @MaxCycle + 1

SET @StopCycle = @CityStopCycle

END

COMMIT TRAN

BEGIN TRAN

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ

INSERT INTO CallLog (PhoneID, CallDate, LongTime, LocalCall, CityID)

SELECT PhoneID, CallDate, LongTime, LocalCall, CityID FROM #TempCallLog ORDER BY CallDate

COMMIT TRAN

DEALLOCATE curCity

DEALLOCATE curPhone

GO

IF EXISTS (SELECT TABLE_NAME

FROM INFORMATION_SCHEMA.VIEWS

WHERE TABLE_NAME = N'AbonentInfo')

DROP VIEW AbonentInfo

GO

CREATE VIEW AbonentInfo

AS

SELECT AbonentID, FName, LName, Company, State, AbonentType.Cost, DiscontType.Rate

FROM (Abonent INNER JOIN AbonentType ON Abonent.AbonentTypeID=AbonentType.AbonentTypeID)

INNER JOIN DiscontType ON DiscontType.DiscontTypeID=AbonentType.DiscontTypeID

GO

IF EXISTS (SELECT TABLE_NAME

FROM INFORMATION_SCHEMA.VIEWS

WHERE TABLE_NAME = N'PhoneInfo')

DROP VIEW PhoneInfo

GO

CREATE VIEW PhoneInfo

AS

SELECT Phone.PhoneID, Phone.Number, Phone.State, AbonentInfo.FName, AbonentInfo.LName, AbonentInfo.Company, AbonentInfo.Cost, AbonentInfo.Rate

FROM (Phone INNER JOIN AbonentInfo ON AbonentInfo.AbonentID=Phone.AbonentID)

GO


2.2 Структура клиентского приложения:

Назначение классов:

Имя класса

Назначение

AbonentManagement

Добавление, удаление, подключение и отключение абонентов.

Изменение данных абонента.

Admin

Используется для выполнения запросов на SQL

BookKeeping

Генерирует квитанции на заданный месяц. Заполняет таблицу Receipt.

CallGenerator

Эмулятор телефонной сети.

Connect

Класс отвечает за подключение к базе и определение прав доступа.

Crash

Регистрация поломок

CrashFix

Отображает список неустранённых поломок сети и позволяет их устранять

FillComponent

Содержит статические методы для работы с базой.

MainForm

Основная форма, содержит меню, изменяющееся в зависимости от прав доступа.

Pay

Позволяет отметить квитанцию как оплаченную.

PhoneManagement

Добавление, удаление, подключение и отключение телефонных номеров.

Переназначение номеров.

StatForm

Универсальная форма для отображения статистики с выборкой по одному параметру.

TableForm

Универсальная форма для работы с таблицами.

Рассмотрим подробнее некоторые классы:

Главное окно приложения представляет собой MDI-форму, содержащую меню, которое изменяется в зависимости от прав доступа (типа пользователя).

Подключение к серверу и авторизацию пользователя обеспечивает класс Connect, экземпляр которого создаётся сразу после запуска приложения. Формат конструктора: Connect(MainForm _main) – в объект передаётся ссылка на основную форму приложения, что сделано для предоставления возможности конфигурирования меню основного окна в соответствии с правами пользователя.

Тип пользователя определяется по таблице Service.

Работу с таблицами обеспечивает класс TableForm.

При создании экземпляра TableForm ему необходимо передать название таблицы, подключение к БД типа SqlConnection и элемент меню, при помощи которого было инициировано создание этого экземпляра. Формат конструктора:

TableForm(SqlConnection _sqlConn, string _tableName, MenuItem menuItem). Указанная строка меню отключается, чтобы избежать повторного открытия формы. Сразу после инициализации будет отображена форма с элементом типа DataGrid, содержащим полную выборку из таблицы. Шаблоны для команд INSERT, UPDATE & DELETE формируются на основе метаданных полученной таблицы при помощи метода CreateCommand(). Сохранение данных происходит при помощи метода Save(), вызов которого происходит по нажатию кнопки «Save» или при закрытии окна (т.е. при вызове Dispose()).

Классы AbonentManagement, BookKeeping, CallGenerator, Crash, CrashFix, Pay, PhoneManagement предназначены для ввода и модификации информации в БД про помощи различных форм. Все они имеют одинаковый набор параметров конструктора, в который передаются SqlConnection _sqlConnection и MenuItem menuItem.

Классы AbonentManagement и PhoneManagement обеспечивают работу с абонентами и телефонными номерами соответственно. Их структура очень похожа:

  • имеются функции UpdCombo() и ResetList(), которые обновляют содержимое таблиц и списков, находящихся на форме;
  • набор обработчиков нажатий на кнопки, использующих статические методы класса FillComponent для доступа к данным.

Между этими классами нет принципиальных различий, но есть существенные различия в реализации некоторых методов.

Класс Crash отображает форму для регистрации поломки в сети, подобен классам AbonentManagement и PhoneManagement.

Класс BookKeeping формирует квитанции (записи в Receipt) на основе истории звонков (записи в CallLog) для указанного месяца.

CallGenerator эмулирует работу сети (пишет звонки в CallLog). Входные параметры для генератора:

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

Генерация происходит в обработчике нажатия кнопки «Генерировать».

Класс ComboItem предназначен для заполнения экземпляров ComboBox.

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

StatForm представляет собой универсальную форму для отображения статистики с выборкой по одному параметру. Основной запрос и запрос на параметр передаются в конструкторе: StatForm(SqlConnection _sqlConnection, string _tableName, MenuItem menuItem, string _strSelect, string _strCombo, int _param1Combo, int _param2Combo). _param1Combo и _param2Combo – индексы выборки в поля str и str2 экземпляров класса ComboItem, которыми заполняется экземпляр ComboBox, предназначенный для выбора конкретного значения параметра.

FillComponent – предоставляет статические простые методы для доступа к данным:

· static void FillList(ListView list, string strSelect, SqlConnection sqlConnection, int index ) – заполняет list данными, полученными при помощи запроса strSelect, index – количество не заполняемых столбцов;

· static void FillCombo(ComboBox combo, string strSelect, SqlConnection sqlConnection, int Index, int Index2) – заполняет combo данными, полученными при помощи запроса strSelect. Index – номер поля, значение которого записывается в str экземпляра ComboItem. Index2 – номер поля, значение которого записывается в str2 экземпляра ComboItem.;

· static void FillCombo(ComboBox combo, string strSelect, SqlConnection sqlConnection, int Index) – в str2 пишется пустая строка;

· static int Add(string strIns, SqlConnection sqlConnection) – запись в БД по запросу strIns;

· static int Update(string strUpd, SqlConnection sqlConnection) – обновление записей в БД по запросу strUpd;

· static void Scalar(ref string strResult, string strSelect, SqlConnection sqlConnection) – возвращает в strResult последнюю строку результата запроса strSelect.

clip_image003


3. Описание интерфейсного взаимодействия

3.1 Интерфейс «БД – Клиентское ПО»

  • Для доступа к данным используется технология ADO.NET
  • Все запросы к базе пишутся на языке Transact-SQL

3.2 Интерфейс «Клиентское ПО - Пользователь»

· Вход в систему: обеспечивает подключение к серверу и вход в базу с правами доступа, зависящими от типа пользователя
· Главное окно: содержит меню, которое изменяется в зависимости от прав доступа (типа пользователя)
· Работа с таблицами: таблицы доступны для прямого редактирования из меню «Таблицы».
· Работа с абонентами: форма позволяет производить добавление, удаление, подключение и отключение абонентов, а также изменение данных абонента.
· Работа с телефонными номерами: форма позволяет производить добавление, удаление, подключение, отключение и переназначение телефонных номеров.
· Регистрация и устранение неисправностей: регистрация производится при помощи формы «Регистрация поломки». Для устранения поломки используется форма «Отметка о ремонте».
· Работа с квитанциями: формирование квитанций производится при помощи формы «Обработка квитанций», а их оплата – через форму «Оплата квитанций»
· Запросы различного типа можно выполнить из меню «Запросы». Администратор может сом формировать запросы на языке SQL.

· Эмуляция работы сети и регистрация звонков производится эмулятором сети.

· Внешний вид приложения:

clip_image005

Разработка многопользовательской автоматизированной системы управления организацией. – Часть 1 (FDS)

В данной статье мы опишем разработку проекта по автоматизации управления телефонной станцией.

1. Введение

1.1 Назначение

Цель данного проекта – разработать автоматизированную систему управления организацией. Область применения – Телефонная станция. Система должна упростить работу сотрудников по управлению организацией, тем самым позволяя сосредоточить свое внимание на основной работе.

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

1.2 Релизация

Проект реализуется при помощи MS SQL Server 2000 & MS Visual Studio .NET 2003.

Клиентская часть пишется на C#.

Для доступа к данным будет использована технология ADO.NET.

1.3 Определения и принятые сокращения

В настоящем документе приняты следующие определения и сокращения:

Сокращение

Определение

БД

База Данных

ОС

Операционная Система

2. Общее описание

Поселок городского типа имеет свою телефонную станцию. На данном этапе станция имеет 20 каналов связи и не может обслуживать одновременно более 340 телефонных номеров. Абонентами могут быть как физические, так и юридические лица. Юридическое лицо (организация) в отличие от физического может являться владельцем нескольких телефонных номеров. Зато физические лица могут получать льготы по абонентной плате.

Телефонная станция осуществляет связь как внутри города, так и с другими городами. Все разговоры с другими городами оплачиваются повременно в зависимости от удаленности объекта. Внутригородские разговоры частично оплачиваются за счет абонентной платы (10 минут ежедневно), а частично – повременно (все, что сверх 10 минут). Абонентная плата установлена 30 руб. ежемесячно для физических лиц и 120 руб – для юридических лиц.

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

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

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

2.1 Функции продукта

В функции ремонтной службы входит:

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

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

В функции работника бухгалтерии входит:

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

В функции планово-статистической и управляющей службы входит:

· Сбор статистики о звонках

· Введение в строй новых телефонных номеров и подключение новых абонентов.

· Принятие решений об отключении телефона при неправильной его эксплуатации абонентом и за неуплату.

· Формирование штата сотрудников.

· Формирование справочных таблиц.

2.2 Характеристика пользователей и требования по выпуску

· Пользователь должен свободно владеть компьютером.

· Пользователь должен хорошо знать ту организацию, для которой создана БД.

· Администратор системы должен иметь навыки работы с MS SQL Server 2000 и знать язык Transact-SQL.

· Для работы клиентской части необходим .NetFrameWork версии 1.1(или выше).

· Необходимо учесть системные требования MS SQL Server 2000.

2.3 Общие требования и ограничения

· Разработка должна представлять законченный продукт, предназначенный для испытаний и продажи.

· БД должна быть удобна и максимально проста в использовании.


3. Специфические требования

3.1 Регистрация звонков:

  • Запись о звонке добавляется в таблицу CallLog;
  • Все поля таблицы являются обязательными;
  • Запись в таблицу производит блок моделирования звонков;
  • Для блока моделирования указывается диапазон дат и количество звонков;

3.2 Прием заявок от абонентов в случае неисправности:

  • Запись о заявке добавляется в таблицу Crash;
  • Все заявки имеют уникальный идентификатор;
  • Указываются:

1. номер абонента;

2. дата заявки;

3. тип неисправности (из списка по таблице CrashType);

4. срок устранения неисправности;

5. кто устранил неполадку (из списка по таблице User);

  • Фиксируется факт устранения;
  • Все поля, кроме даты устранения, являются обязательными.

3.3 Сбор статистических данных о неисправностях:

  • Составляется запрос по таблицам Crash и CrashType;
  • Возможно получение списка неисправностей одного типа;
  • Результаты запроса отображаются на экране в виде таблицы.

3.4 Ежемесячное формирование квитанций:

  • Запись о квитанции добавляется в таблицу Receipt;
  • Запись формируется на основе данных из таблицы CallLog
  • После оплаты флаг Receipt .State = true

3.5 Принятие решений об отключении телефона:

  • Телефон отключается путём установки в false флага Phone.State
  • Возможно отключение абонента путём установки в false флага Abonent.State

3.6 Формирование списка скидок:

  • Запись добавляется в таблицу DiscountType;
  • Все записи имеют уникальный идентификатор;
  • Все поля таблицы являются обязательными;
  • При удалении скидки все записи о ней из таблицы AbonentType удаляются.

3.7 Формирование списка городов:

  • Запись добавляется в таблицу City;
  • Все записи имеют уникальный идентификатор;
  • Все поля таблицы являются обязательными;
  • При удалении города все записи о нём из таблицы CallLog удаляются.

3.8 Формирование списка типов абонентов:

  • Запись добавляется в таблицу AbonentType;
  • Все записи имеют уникальный идентификатор;
  • Все поля таблицы являются обязательными;
  • При удалении типа удаляются все записи с его использованием из таблицы Abonent (при удалении абонента все записи о нём из таблиц CallLog, PayLog, Receipt, Phone, Crash удаляются).

3.9 Формирование списка служб:

  • Запись добавляется в таблицу Service;
  • Все записи имеют уникальный идентификатор;
  • Все поля таблицы являются обязательными;
  • При удалении службы все записи о ней из таблиц User, Crash удаляются.

3.10 Формирование списка типов неисправностей:

  • Запись добавляется в таблицу CrashType;
  • Все записи имеют уникальный идентификатор;
  • Все поля таблицы являются обязательными;
  • При удалении типа удаляются все записи с его использованием из таблицы Crash.

3.11 Формирование списка абонентов:

  • Запись добавляется в таблицу Abonent;
  • Все записи имеют уникальный идентификатор;
  • Все поля таблицы являются обязательными.
  • При удалении абонента все записи о нём из таблиц CallLog, PayLog, Receipt, Phone, Crash удаляются.

3.12 Формирование штата сотрудников:

  • Запись добавляется в таблицу User;
  • Все записи имеют уникальный идентификатор;
  • Все поля таблицы являются обязательными.
  • При удалении сотрудника все записи о нём из таблицы Crash удаляются.


4. Требования к данным

4.1 Типы данных:

<><></> </>

Таблица

Поле

Тип

Обязательность

Service

ServiceID

int

да

AccessType

tinyint

да

Description

text

да

User

UserID

int

да

FName

varchar

да

LName

varchar

да

ServiceID

int

да

UserName

varchar

да

Password

varchar

нет

Abonent

AbonentID

int

да

FName

varchar

да

LName

varchar

да

Company

varchar

нет

AbonentTypeID

bit

да

State

bit

да

AbonentType

AbonentTypeID

int

да

DiscountTypeID

int

да

Cost

money

да

Phone

PhoneID

int

да

AbonentID

int

да

Number

varchar

да

State

bit

да

Crash

CrashID

int

да

CrashTypeID

int

да

PhoneID

int

да

RegDate

smalldatetime

да

FixDate

smalldatetime

нет

UserID

int

да

State

bit

да

CrashType

CrashTypeID

int

да

Description

text

да

CallLog

CallLogID

int

да

PhoneID

int

да

CallDate

smalldatetime

да

LongTime

smalldatetime

да

CityID

int

да

ReceiptState

bit

нет

DiscountType

DiscountTypeID

int

да

Rate

tinyint

да

Description

text

да

City

CityID

int

да

City

varchar

да

CityCode

varchar

да

Cost

money

да

Receipt

ReceiptID

int

да

AbonentID

int

да

LocalCost

money

да

TrunkCallCost

money

да

State

bit

да

Date

smalldatetime

нет

PayDate

smalldatetime

да

Archive

AbonentID

int

да

FName

varchar

да

LName

varchar

да

Company

varchar

нет

State

bit

да

Cost

money

да

Rate

tinyint

да

4.2 Требования по защите данных:

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