From f29133438457849ee75818948119f46686f28630 Mon Sep 17 00:00:00 2001 From: Nikolay Ushmodin Date: Fri, 16 Sep 2016 16:55:38 +0700 Subject: [PATCH] init --- .gitignore | 8 + avs5rs.md | 857 +++++++++++++++++++++ build.gradle | 15 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes gradle/wrapper/gradle-wrapper.properties | 6 + gradlew | 160 ++++ gradlew.bat | 90 +++ settings.gradle | 2 + src/main/java/com/artmark/avs5rs/SaleService.java | 144 ++++ src/main/java/com/artmark/avs5rs/model/Agent.java | 44 ++ .../com/artmark/avs5rs/model/BookOrderRequest.java | 64 ++ .../artmark/avs5rs/model/BookOrderResponse.java | 28 + .../artmark/avs5rs/model/CancelTicketRequest.java | 35 + .../artmark/avs5rs/model/CancelTicketResponse.java | 26 + .../artmark/avs5rs/model/ConfirmOrderRequest.java | 35 + .../artmark/avs5rs/model/ConfirmOrderResponse.java | 37 + .../java/com/artmark/avs5rs/model/DateAdapter.java | 28 + .../com/artmark/avs5rs/model/DocumentType.java | 38 + .../java/com/artmark/avs5rs/model/EchoRequest.java | 27 + .../com/artmark/avs5rs/model/EchoResponse.java | 26 + src/main/java/com/artmark/avs5rs/model/Gender.java | 10 + .../avs5rs/model/GetArrivalStationsRequest.java | 27 + .../avs5rs/model/GetArrivalStationsResponse.java | 27 + .../avs5rs/model/GetDispatchStationsRequest.java | 15 + .../avs5rs/model/GetDispatchStationsResponse.java | 27 + .../avs5rs/model/GetDocumentTypesRequest.java | 43 ++ .../avs5rs/model/GetDocumentTypesResponse.java | 28 + .../artmark/avs5rs/model/GetFreeSeatsRequest.java | 52 ++ .../artmark/avs5rs/model/GetFreeSeatsResponse.java | 27 + .../com/artmark/avs5rs/model/GetOrderRequest.java | 24 + .../com/artmark/avs5rs/model/GetOrderResponse.java | 37 + .../avs5rs/model/GetTicketTypesRequest.java | 42 + .../avs5rs/model/GetTicketTypesResponse.java | 28 + .../artmark/avs5rs/model/GetTripStopsRequest.java | 28 + .../artmark/avs5rs/model/GetTripStopsResponse.java | 27 + .../java/com/artmark/avs5rs/model/Passenger.java | 149 ++++ .../java/com/artmark/avs5rs/model/Response.java | 82 ++ .../artmark/avs5rs/model/ReturnTicketRequest.java | 35 + .../artmark/avs5rs/model/ReturnTicketResponse.java | 26 + src/main/java/com/artmark/avs5rs/model/Sale.java | 44 ++ .../artmark/avs5rs/model/SearchTripsRequest.java | 54 ++ .../artmark/avs5rs/model/SearchTripsResponse.java | 30 + src/main/java/com/artmark/avs5rs/model/Seat.java | 51 ++ .../java/com/artmark/avs5rs/model/Station.java | 64 ++ src/main/java/com/artmark/avs5rs/model/Stop.java | 125 +++ src/main/java/com/artmark/avs5rs/model/Ticket.java | 413 ++++++++++ .../com/artmark/avs5rs/model/TicketClassCode.java | 17 + .../com/artmark/avs5rs/model/TicketStatusCode.java | 29 + .../java/com/artmark/avs5rs/model/TicketType.java | 65 ++ .../com/artmark/avs5rs/model/TimestampAdapter.java | 26 + src/main/java/com/artmark/avs5rs/model/Trip.java | 262 +++++++ .../com/artmark/avs5rs/model/TripStatusCode.java | 25 + .../com/artmark/avs5rs/model/TripTypeCode.java | 43 ++ .../artmark/avs5rs/model/UpdateTicketRequest.java | 44 ++ .../artmark/avs5rs/model/UpdateTicketResponse.java | 25 + 55 files changed, 3721 insertions(+) create mode 100644 .gitignore create mode 100644 avs5rs.md create mode 100644 build.gradle create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle create mode 100644 src/main/java/com/artmark/avs5rs/SaleService.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Agent.java create mode 100644 src/main/java/com/artmark/avs5rs/model/BookOrderRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/BookOrderResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/CancelTicketRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/CancelTicketResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/ConfirmOrderRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/ConfirmOrderResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/DateAdapter.java create mode 100644 src/main/java/com/artmark/avs5rs/model/DocumentType.java create mode 100644 src/main/java/com/artmark/avs5rs/model/EchoRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/EchoResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Gender.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetArrivalStationsRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetArrivalStationsResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetDispatchStationsRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetDispatchStationsResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetDocumentTypesRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetDocumentTypesResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetFreeSeatsRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetFreeSeatsResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetOrderRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetOrderResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetTicketTypesRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetTicketTypesResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetTripStopsRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/GetTripStopsResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Passenger.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Response.java create mode 100644 src/main/java/com/artmark/avs5rs/model/ReturnTicketRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/ReturnTicketResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Sale.java create mode 100644 src/main/java/com/artmark/avs5rs/model/SearchTripsRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/SearchTripsResponse.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Seat.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Station.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Stop.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Ticket.java create mode 100644 src/main/java/com/artmark/avs5rs/model/TicketClassCode.java create mode 100644 src/main/java/com/artmark/avs5rs/model/TicketStatusCode.java create mode 100644 src/main/java/com/artmark/avs5rs/model/TicketType.java create mode 100644 src/main/java/com/artmark/avs5rs/model/TimestampAdapter.java create mode 100644 src/main/java/com/artmark/avs5rs/model/Trip.java create mode 100644 src/main/java/com/artmark/avs5rs/model/TripStatusCode.java create mode 100644 src/main/java/com/artmark/avs5rs/model/TripTypeCode.java create mode 100644 src/main/java/com/artmark/avs5rs/model/UpdateTicketRequest.java create mode 100644 src/main/java/com/artmark/avs5rs/model/UpdateTicketResponse.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..45c399d --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +.idea/ +out/ +bin/ +*.log +web/WEB-INF/config/ +.gradle/ +ext/ +build/ \ No newline at end of file diff --git a/avs5rs.md b/avs5rs.md new file mode 100644 index 0000000..1f8dbdd --- /dev/null +++ b/avs5rs.md @@ -0,0 +1,857 @@ +# Введение + +**Версия документа: 1.2** +**Дата изменения: 16.09.2016** + +Для возможности продажи с использованием протокола AVS5RS необходимо реализовать сервис с использованием протокола HTTP. Все запросы оправляются методом POST. +Методы включают в себя справочные методы и методы продажи. Продажа состоит из двух этапов резервирование и подтверждение продажи. +Протокол должен быть защищен авторизацией через логин и пароль. Так же необходимо чтобы трафик передавался по защищенному каналу связи с использованием SSL или VPN. + +## Методы сервиса + +Все запросы должны передаваться по протоколу HTTP методом пост. В теле POST запроса и ответа передается XML фиксированного формата. +Каждый метод имеет отдельный URL. Через HTTP заголовок Content-Type передается значение `application/xml; charset=UTF-8`. +Этот заголовок указывает на тип содержимого запроса и его кодировку. Необходимо использовать только кодировку UTF-8. + +### Формат ответа + +Корневой тег XML ответа Response. У него есть обязательный атрибут success, который указывает корректно выполнился запрос или нет, значения true - корректно, false - нет. +Если ответ корректный, то данные ответа содержатся во вложенном теге Body. Если ответ не корректный, тег Body будет проигнорирован, а информация об ошибке должна +находиться во вложенном теге Error. Который состоит из кода ошибки и описания. Коды ошибок не регламентируются. Описание это произвольные тест, поясняющий причину ошибки. +Регистр названий тегов и атрибутов должен совпадать с регистром из примеров. +Все ответы должны приходить с HTTP кодом 200. Все XML ответы должны начинаться с объявления `` в котором указана кодировка содержимого. +Формат даты `yyyy-MM-dd`, формат даты и времени `yyyy-MM-dd'T'HH:mm:ss`, пример 2016-09-07T13:10:00 (символ T латинский, обязательный) (секунды обязательны). +Время указано в часовом поясе сервера который предоставляет контент. +Все идентификаторы сущностей (id) это строки, произвольного формата, длинной до 36 символов. + +Корректный ответ: + +```xml + + + + Test + + +``` + +Не корректный ответ: + +```xml + + + + ERROR + Место 5 занято + + +``` + +### echo + +Метод принимает в параметра произвольную строку и возвращает её в теле ответа. Не выполняет ни какой логики. Необходим для проверки доступен ли сервис. + +**URL: /sales/echo** + +Запрос: + +```xml + + + + Test + +``` + +Ответ: + +```xml + + + + + Test + + +``` + +### getDispatchStations + +Метод получения станций отправления. +Продажа происходит от станции отправления до станции назначения, поэтому метод должен вернуть хотя бы один элемент. +Обычно станциями отправления являются автовокзалы или автоматизированные остановочные пункты с функцией продажи билетов. + +**URL: /sales/getDispatchStations** + +Запрос: + +```xml + + + +``` + +Ответ: + +```xml + + + + + + + 983 + + ВДНХ АС + + Москва + + 45000000000 + + + 853 + Варшавская АС + Москва + 45000000000 + + + 6 + Красногвардейская АС + Москва + 45000000000 + + + +``` + +### getArrivalStations + +Метод получения станций назначения от станции отправления. В параметра принимает идентификатор станции отправления. +Станциями назначения могут быть любые остановочные пункты до которых есть хотя бы один рейс. +Если станций назначения нет вернуть пустой список. + +**URL: /sales/getArrivalStations** + +Запрос: + +```xml + + + + 983 + +``` + +Ответ: + +```xml + + + + + 1069 + Рыбинск + Ярославская область + 78415000000 + + + 1018 + Сергиев Посад + Московская область + 46215501000 + + + 1084 + Углич + Ярославская область + 78420000000 + + + 1078 + Утена + Литва + + + +``` + +### searchTrips + +Метод возвращает список рейсов от станции отправления до станции назначения на заданную дату. +В параметрах передается идентификатор станции отправления, идентификатор станции назначения и дата. + +**URL: /sales/searchTrips** + +Запрос: + +```xml + + + + 983 + + 678 + + 2016-07-12 + +``` + +Ответ: + +```xml + + + + + + + 570104 + + 000 + + ВДНХ АС - Пенза + + 2016-07-13T19:30:00 + + 2016-07-14T05:30:00 + + 983 + + ВДНХ АС + + 744 + + Пенза + + 1391 + + ИП Ерашова Валентина Анатольевна + + ИНН 582700056092 + + 49 Мест Категория ТС "М3" + + true + + INTERREGIONAL + + ON_SALE + + 49 + + 49 + + + 570105 + 000 + ВДНХ АС - Пенза + 2016-07-13T21:30:00 + 2016-07-14T07:30:00 + 983 + ВДНХ АС + 744 + Пенза + 1391 + ИП Ерашова Валентина Анатольевна + ИНН 582700056092 + 49 Мест Категория ТС "М3" + true + INTERREGIONAL + ON_SALE + 49 + 49 + + + +``` + +### getFreeSeats + +Получение списка свободных мест для рейса. +В параметра принимает идентификатор рейса, идентификтор станции отправления и идентификатор станции назначения. + +**URL: /sales/getFreeSeats** + +Запрос: + +```xml + + + + 570101 + + 983 + + 1080 + +``` + +Ответ: + +```xml + + + + + + + 17926 + + Место 1 + + Сидячее + + + 17927 + Место 2 + Сидячее + + + 17928 + Место 3 + Сидячее + + + +``` + +### getTicketTypes + +Получение списка типов билетов, доступных для продажи. +В параметра принимает идентификатор рейса, идентификатор станции отправления и идентификатор станции назначения. + +**URL: /sales/getTicketTypes** + +Запрос: + +```xml + + + + 570101 + + 983 + + 1080 +/GetTicketTypesRequest> +``` + +Ответ: + +```xml + + + + + + 1#1#0 + + Полный + + 1391 + + PASSENGER + + + 38#6#0 + Детский + 696 + PASSENGER + + + 0#0#0 + Багажный + 40 + BAGGAGE + + + +``` + +### getDocumentTypes + +Получение списка типов документов, допустимых при оформлении билетов. Система должна предоставить хотя бы один тип документа. +Рекомендуется использовать документы из (приказа)[http://base.garant.ru/70229008/] в Таблице 1. +В параметра принимает идентификатор рейса, идентификатор станции отправления и идентификатор станции назначения. + +**URL: /sales/getDocumentTypes** + +Запрос: + +```xml + + + + 570101 + + 983 + + 1080 + +``` + +Ответ: + +```xml + + + + + + 1 + + Паспорт РФ + + + 52 + Паспорт иностранного гражданина + + + 40 + Удостоверение (Казахстан) + + + 2 + Свидетельство о рождении + + + 4 + Удостоверение личности военнослужащего + + + 55 + Временное удостоверение ОВД + + + +``` + +### getTripStops + +Метод возвращает список остановочных пунктов для рейса. +В параметра принимает идентификатор рейса. +Метод информационный. + +**URL: /sales/getTripStops** + +Запрос: + +```xml + + + + 569839 + +``` + +Ответ: + +```xml + + + + + + 1011 + + Скопин (трасса) + + Рязанская область + + 2016-07-14T16:20:00 + + 2016-07-13T21:00:00 + + 10 + + 260 + + 1177 + + + 1010 + Мичуринск (трасса) + Тамбовская область + 2016-07-14T16:20:00 + 2016-07-13T21:00:00 + 10 + 385 + 1177 + + + 818 + Тамбов (трасса) + Тамбовская область + 2016-07-14T16:20:00 + 2016-07-13T21:00:00 + 10 + 455 + 1177 + + + +``` + +### bookOrder + +Бронирование заказа. Бронь сохраняется в течение ограниченного времени, от 20 до 60 минут. Если в указанный +период времени не поступает подтверждение оплаты через метод confirmOrder(), то бронирование автоматически +отменяется. Метод должен выполнить все возможные проверки корректности переданных данных. В случае ошибки +заказ не должен быть создан. Допускается бронирование нескольких билетов в рамках одного заказа. +В параметра принимает идентификатор рейса, идентификатор станции отправления, идентификатор станции назначения, +информацию о бронируемых билетах, информацию об агенте совершивший эту операцию. Информации о бронируемых билетах +включает в себя идентификатор типа билета, идентификатор места и информацию о пассажире. Информация об +агенте включает в себя наименование и ИНН агента. + +**URL: /sales/bookOrder** + +Запрос: + +```xml + + + + 570101 + + 983 + + 1080 + + + + 25862 + + 1#1#0 + + + + goxUEpWCud + + sKZXIloHFn + + pCaEgXgfWO + + jwcmdIrmcc + + iFAElsnFHn + + 1 + + 1986-01-01 + + RU + + MALE + + + + + + ИП Твои билеты + + 2225555777 + + +``` + +Ответ: + +```xml + + + + + 9828350 + + 30 + + +``` + +### getOrder + +Получение информации о заказе. В параметрах принимает идентификатор заказа, полученный в результате bookOrder. +Метод должен вернуть такое же количество билетов сколько было передано при вызове bookOrder. +Метод должен работать на любом этапе жизни заказа т.е. после создания, подтверждения, отмены, возврата. + +**URL: /sales/getOrder** + +Запрос: + +```xml + + + + 9828350 + +``` + +Ответ: + +```xml + + + + + 9828350 + + + + 12435438 + + + + + + 2016-07-13T05:48:15 + + + + RESERVED + + PASSENGER + + 1#1#0 + + 000 + + ВДНХ АС - Рыбинск + + 19 Мест Категория ТС "М3" + + ООО "ВВМЛ" + + ИНН 7610074937 + + Перрон 11 + + 2016-07-13T12:20:00 + + ВДНХ АС + + пл.Шарля де Голля напротив Космонавтов2А, + + 2016-07-13T16:20:00 + + Углич + + Место 1 + + + Ckayuukvgn + Bgkzxffotu + Isdikvryin + PUPrvbqlgU + fRHEoBHVbG + 1 + 1985-01-01 + RU + MALE + + + 0 + + 0 + + 0 + + 0 + + 0 + + 0 + + СТРАХОВЩИК: ПАО "Росстрах"; 119991; г. Москва; ул. Большая Ордынка; д. 40; стр. + + + +``` + +### confirmOrder + +Подтверждение оплаты заказа. Данный метод должен вызываться только после того как заказ действительно был +оплачен покупателем. Метод не должен делать проверок корректности заказа. Все проверки должны делать в bookOrder +или updateTicket. Вызов этого метода означает, все данные заполнены правильно и деньги от покупателя получены. +В параметрах принимает идентификатор заказа, полученный в результате bookOrder и информацию об агенте который +совершил операцию + +**URL: /sales/confirmOrder** + +Запрос: + +```xml + + + 9828585 + + + + ИП Твои билеты + + 2225555777 + + +``` + +Ответ: + +Ответ аналогичен ответу на запрос getOrder + + +### cancelTicket + +Отмена билета. Техническая операция, выполняет полный возврат билета без удержаний. +Необходима при нештатных ситуациях например в случае сбоев ККМ или ошибки выбора рейса. +В параметрах принимает идентификатор билета и информацию об агенте который совершил операцию. +Можно выполнять после создания заказа и в течении 5-30 минут после подтверждения заказа. + +**URL: /sales/cancelTicket** + +Запрос: + +```xml + + + 12435434 + + + + ИП Твои билеты + + 2225555777 + + +``` + +Ответ: + +Ответ аналогичен ответу на запрос getOrder + +### returnTicket + +Возврат билета. При возврате возможны удержания. В параметрах принимает идентификатор билета и информацию +об агенте который совершил операцию. Билет можно вернуть только после подтверждения confirmOrder. + +**URL: /sales/returnTicket** + +Запрос: + +```xml + + + 12435435 + + + + ИП Твои билеты + + 2225555777 + + +``` + +Ответ: + +Ответ аналогичен ответу на запрос getOrder + +### updateTicket + +Изменение персональных данных пассажира в забронированном или проданном билете. +В параметрах принимает идентификатор билета, информацию о пассажире и информацию +об агенте который совершил операцию. + +**URL: /sales/updateTicket** + +Запрос: + +```xml + + + + 12435438 + + + goxUEpWCud + + sKZXIloHFn + + pCaEgXgfWO + + jwcmdIrmcc + + iFAElsnFHn + + 1 + + 1986-01-01 + + RU + + FEMALE + + + + + ИП Твои билеты + + 2225555777 + + +``` + +Ответ: + +```xml + + +/Response> +``` + + diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..3bb4dc2 --- /dev/null +++ b/build.gradle @@ -0,0 +1,15 @@ +group 'com.artmark' +version '1.0-SNAPSHOT' + +apply plugin: 'java' + +sourceCompatibility = 1.6 + +repositories { + mavenCentral() +} + +dependencies { + compile group: 'javax.ws.rs', name: 'javax.ws.rs-api', version: '2.0.1' + testCompile group: 'junit', name: 'junit', version: '4.11' +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..941144813d241db74e1bf25b6804c679fbe7f0a3 GIT binary patch literal 53636 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 DXC5Z7 literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..668d390 --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Sep 16 16:48:38 KRAT 2016 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-all.zip diff --git a/gradlew b/gradlew new file mode 100755 index 0000000..9d82f78 --- /dev/null +++ b/gradlew @@ -0,0 +1,160 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..8a0b282 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..99c04ac --- /dev/null +++ b/settings.gradle @@ -0,0 +1,2 @@ +rootProject.name = 'avs5rs' + diff --git a/src/main/java/com/artmark/avs5rs/SaleService.java b/src/main/java/com/artmark/avs5rs/SaleService.java new file mode 100644 index 0000000..782e713 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/SaleService.java @@ -0,0 +1,144 @@ +package com.artmark.avs5rs; + +import com.artmark.avs5rs.model.*; + +import javax.ws.rs.POST; +import javax.ws.rs.Path; + +/** + * Сервис продажи билетов. + * @author Ushmodin N. + * @since 07.07.2016 10:06 + */ + +@Path("/sales") +public interface SaleService { + + /** + * Метод примает в параметра произвольную строку и возвращает её в теле ответа. + * Не выпольняет ни какой логики. Необходим для проверки доступен ли сервис. + */ + @Path("/echo") + @POST + Response echo(EchoRequest request); + + /** + * Метод получения станций отправления. + * Продажа происходит от станции отправления до станции назначения, поэтому метод должен вернуть хотябы один элемент. + * Обычно станциями отправления являются автовокзалы или автоматизированные остановочные пункты с фунцией продажи билетов. + */ + @Path("/getDispatchStations") + @POST + Response getDispatchStations(GetDispatchStationsRequest request); + + /** + * Метод получения станций назначения от станции отправления. В параметра принимает идентификато станции отправления. + * Станциями назначения могут быть любые остановочные пункты до которых есть хотябы один рейс + */ + @Path("/getArrivalStations") + @POST + Response getArrivalStations(GetArrivalStationsRequest request); + + /** + * Метод возвращает список рейсов от станции отправления до станции назначения на заданную дату. + * В параметрах передается идентификатор станции отправления, идентификатор станции назначения и дата. + */ + @Path("/searchTrips") + @POST + Response searchTrips(SearchTripsRequest request); + + /** + * Метод возвращает список остановочных пунктов для рейса. + * В параметра принимает идентификатор рейса. + * Метод информационный. + */ + @Path("/getTripStops") + @POST + Response getTripStops(GetTripStopsRequest request); + + /** + * Получение списка свободных мест для рейса. + * В параметра принимает идентификатор рейса, идентификтор станции отправления и идентификатор станции назначения. + */ + @Path("/getFreeSeats") + @POST + Response getFreeSeats(GetFreeSeatsRequest request); + + /** + * Получение списка типов билетов, доступных для продажи. + * В параметра принимает идентификатор рейса, идентификтор станции отправления и идентификатор станции назначения. + */ + @Path("/getTicketTypes") + @POST + Response getTicketTypes(GetTicketTypesRequest request); + + /** + * Получение списка типов документов, допустимых при оформлении билетов. Система должна предоставить хотя бы один тип документа. + * Рекомендуется использовать документы из (приказа)[http://base.garant.ru/70229008/] в Таблице 1. + * В параметра принимает идентификатор рейса, идентификатор станции отправления и идентификатор станции назначения. + */ + @Path("/getDocumentTypes") + @POST + Response getDocumentTypes(GetDocumentTypesRequest request); + + + /** + * Бронирование заказа. Бронь сохраняется в течение ограниченного времени, от 20 до 60 минут. Если в указанный + * период времени не поступает подтверждение оплаты через метод confirmOrder(), то бронирование автоматически + * отменяется. Метод должен выполнить все возможные проверки корректности переданных данных. В случае ошибки + * заказ не должен быть создан. + * В параметра принимает идентификатор рейса, идентификтор станции отправления, идентификатор станции назначения, + * информацию о бронируемых билетах, информацию об агенте совершивший эту операцию. Информаци о бронируемых билетах + * включает в себя идентификатор типа билета, идентификато места и информацию о пассажире. Информация об + * агенте включает в себя наименование и ИНН агента. + */ + @Path("/bookOrder") + @POST + Response bookOrder(BookOrderRequest request); + + /** + * Получение информации о заказе. В пареметрах принимает идентификатор заказа, полученный в результате bookOrder + * Метод должен работать на любом этапе жизни заказа т.е. после создания, подтверждения, отмены, возврата. + */ + @Path("/getOrder") + @POST + Response getOrder(GetOrderRequest request); + + /** + * Подтверждение оплаты заказа. Данный метод должен вызываться только после того как заказ действительно был + * оплачен покупателем. Метод не должен делать проверок корректности заказа. Все проверки должны делать в bookOrder + * или updateTicket. Вызов этого метода означает, все данные заполнены правильно и деньги от покупателя получены. + * В пареметрах принимает идентификатор заказа, полученный в результате bookOrder и информацию об агенте который + * совершил операцию + */ + @Path("/confirmOrder") + @POST + Response confirmOrder(ConfirmOrderRequest request); + + /** + * Возврат билета. При возврате возможны удержания. В пареметрах принимает идентификатор билета и информацию + * об агенте который совершил операцию. Билет можно вернуть только после подтверждения confirmOrder. + */ + @Path("/returnTicket") + @POST + Response returnTicket(ReturnTicketRequest request); + + /** + * Отмена билета. Техническая операция, выполняет полный возврат билета без удержаний. + * Необходима при нештатных ситуациях например в случае сбоев ККМ или ошибки выбора рейса. + * В пареметрах принимает идентификатор билета и информацию об агенте который совершил операцию. + * Можно выполнять после создания заказа и в течении 5-30 минут после подтвержения заказа. + */ + @Path("/cancelTicket") + @POST + Response cancelTicket(CancelTicketRequest request); + + /** + * Изменение персональных данных пассажира в забронированном или проданном билете. + * В пареметрах принимает идентификатор билета, информацию о пассажире и информацию + * об агенте который совершил операцию. + */ + @Path("/updateTicket") + @POST + Response updateTicket(UpdateTicketRequest request); +} diff --git a/src/main/java/com/artmark/avs5rs/model/Agent.java b/src/main/java/com/artmark/avs5rs/model/Agent.java new file mode 100644 index 0000000..12b3cfe --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Agent.java @@ -0,0 +1,44 @@ +package com.artmark.avs5rs.model; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + +/** + * Информация об агенте + * + * @author V.Skorykh + * @since 30.05.2016 13:42 + * @since 5.2 + */ +@XmlType +@XmlAccessorType(XmlAccessType.FIELD) +public class Agent { + + /** + * ИНН агента + */ + private String inn; + + /** + * Имя агента (название организации) + */ + private String name; + + public String getInn() { + return inn; + } + + public void setInn(String inn) { + this.inn = inn; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/BookOrderRequest.java b/src/main/java/com/artmark/avs5rs/model/BookOrderRequest.java new file mode 100644 index 0000000..2b3574f --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/BookOrderRequest.java @@ -0,0 +1,64 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:04 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "BookOrderRequest") +public class BookOrderRequest { + private String tripId; + private String dispatchStationId; + private String arrivalStationId; + @XmlElement(name = "Sale") + private List sales; + @XmlElement(name = "Agent") + private Agent agent; + + public String getTripId() { + return tripId; + } + + public void setTripId(String tripId) { + this.tripId = tripId; + } + + public String getDispatchStationId() { + return dispatchStationId; + } + + public void setDispatchStationId(String dispatchStationId) { + this.dispatchStationId = dispatchStationId; + } + + public String getArrivalStationId() { + return arrivalStationId; + } + + public void setArrivalStationId(String arrivalStationId) { + this.arrivalStationId = arrivalStationId; + } + + public List getSales() { + return sales; + } + + public void setSales(List sales) { + this.sales = sales; + } + + public Agent getAgent() { + return agent; + } + + public void setAgent(Agent agent) { + this.agent = agent; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/BookOrderResponse.java b/src/main/java/com/artmark/avs5rs/model/BookOrderResponse.java new file mode 100644 index 0000000..3be681c --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/BookOrderResponse.java @@ -0,0 +1,28 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:09 + */ + + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "BookOrderResponse") +public class BookOrderResponse { + /** + * Идентификато договора + */ + private String orderId; + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/CancelTicketRequest.java b/src/main/java/com/artmark/avs5rs/model/CancelTicketRequest.java new file mode 100644 index 0000000..d640df9 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/CancelTicketRequest.java @@ -0,0 +1,35 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:23 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "CancelTicketRequest") +public class CancelTicketRequest { + private String ticketId; + @XmlElement(name = "Agent") + private Agent agent; + + public String getTicketId() { + return ticketId; + } + + public void setTicketId(String ticketId) { + this.ticketId = ticketId; + } + + public Agent getAgent() { + return agent; + } + + public void setAgent(Agent agent) { + this.agent = agent; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/CancelTicketResponse.java b/src/main/java/com/artmark/avs5rs/model/CancelTicketResponse.java new file mode 100644 index 0000000..f9f9193 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/CancelTicketResponse.java @@ -0,0 +1,26 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:23 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "CancelTicketResponse") +public class CancelTicketResponse { + @XmlElement(name = "Ticket") + private Ticket ticket; + + public Ticket getTicket() { + return ticket; + } + + public void setTicket(Ticket ticket) { + this.ticket = ticket; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/ConfirmOrderRequest.java b/src/main/java/com/artmark/avs5rs/model/ConfirmOrderRequest.java new file mode 100644 index 0000000..9e2d4d5 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/ConfirmOrderRequest.java @@ -0,0 +1,35 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:18 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "ConfirmOrderRequest") +public class ConfirmOrderRequest { + private String orderId; + @XmlElement(name = "Agent") + private Agent agent; + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public Agent getAgent() { + return agent; + } + + public void setAgent(Agent agent) { + this.agent = agent; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/ConfirmOrderResponse.java b/src/main/java/com/artmark/avs5rs/model/ConfirmOrderResponse.java new file mode 100644 index 0000000..3012a55 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/ConfirmOrderResponse.java @@ -0,0 +1,37 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:18 + */ + + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ConfirmOrderResponse") +public class ConfirmOrderResponse { + private String orderId; + @XmlElement(name = "Ticket") + private List tickets; + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public List getTickets() { + return tickets; + } + + public void setTickets(List tickets) { + this.tickets = tickets; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/DateAdapter.java b/src/main/java/com/artmark/avs5rs/model/DateAdapter.java new file mode 100644 index 0000000..f9c3c5b --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/DateAdapter.java @@ -0,0 +1,28 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.adapters.XmlAdapter; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author Ushmodin N. + * @since 07.07.2016 14:34 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +public class DateAdapter extends XmlAdapter { + + private static final String FORMAT = "yyyy-MM-dd"; + + @Override + public Date unmarshal(String s) throws Exception { + return new SimpleDateFormat(FORMAT).parse(s); + } + + @Override + public String marshal(Date date) throws Exception { + return new SimpleDateFormat(FORMAT).format(date); + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/DocumentType.java b/src/main/java/com/artmark/avs5rs/model/DocumentType.java new file mode 100644 index 0000000..4b3ee95 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/DocumentType.java @@ -0,0 +1,38 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; + +/** + * @author Ushmodin N. + * @since 07.07.2016 12:36 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +public class DocumentType { + /** + * ID типа документа. Обязателен. Может совпадать с названием. + */ + protected String id; + + /** + * Название типа документа. Обязателен. + */ + protected String name; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/EchoRequest.java b/src/main/java/com/artmark/avs5rs/model/EchoRequest.java new file mode 100644 index 0000000..01e3332 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/EchoRequest.java @@ -0,0 +1,27 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:25 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "EchoRequest") +public class EchoRequest { + /** + * Сообщение которое будет возвращено в ответ + */ + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/EchoResponse.java b/src/main/java/com/artmark/avs5rs/model/EchoResponse.java new file mode 100644 index 0000000..d3f47fa --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/EchoResponse.java @@ -0,0 +1,26 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:25 + */ +@XmlType(name = "EchoResponse") +@XmlAccessorType(XmlAccessType.FIELD) +public class EchoResponse { + /** + * Сообщение переданное в запросе + */ + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/Gender.java b/src/main/java/com/artmark/avs5rs/model/Gender.java new file mode 100644 index 0000000..ffd9cc5 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Gender.java @@ -0,0 +1,10 @@ +package com.artmark.avs5rs.model; + +/** + * @author Ushmodin N. + * @since 07.07.2016 12:27 + */ + +public enum Gender { + MALE, FEMALE +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetArrivalStationsRequest.java b/src/main/java/com/artmark/avs5rs/model/GetArrivalStationsRequest.java new file mode 100644 index 0000000..50d9de7 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetArrivalStationsRequest.java @@ -0,0 +1,27 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:27 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "GetArrivalStationsRequest") +public class GetArrivalStationsRequest { + /** + * Идентификатор станции отправления. Обязательно. + */ + private String dispatchStationId; + + public String getDispatchStationId() { + return dispatchStationId; + } + + public void setDispatchStationId(String dispatchStationId) { + this.dispatchStationId = dispatchStationId; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetArrivalStationsResponse.java b/src/main/java/com/artmark/avs5rs/model/GetArrivalStationsResponse.java new file mode 100644 index 0000000..55b9fb2 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetArrivalStationsResponse.java @@ -0,0 +1,27 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:30 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "GetArrivalStationsResponse") +public class GetArrivalStationsResponse { + @XmlElement(name = "Station") + private List stations; + + public List getStations() { + return stations; + } + + public void setStations(List stations) { + this.stations = stations; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetDispatchStationsRequest.java b/src/main/java/com/artmark/avs5rs/model/GetDispatchStationsRequest.java new file mode 100644 index 0000000..944cbb4 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetDispatchStationsRequest.java @@ -0,0 +1,15 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 08.07.2016 09:08 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "GetDispatchStationsRequest") +public class GetDispatchStationsRequest { +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetDispatchStationsResponse.java b/src/main/java/com/artmark/avs5rs/model/GetDispatchStationsResponse.java new file mode 100644 index 0000000..e17ce3d --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetDispatchStationsResponse.java @@ -0,0 +1,27 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:27 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "GetDispatchStationsResponse") +public class GetDispatchStationsResponse { + @XmlElement(name = "Station") + private List station; + + public List getStation() { + return station; + } + + public void setStation(List station) { + this.station = station; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetDocumentTypesRequest.java b/src/main/java/com/artmark/avs5rs/model/GetDocumentTypesRequest.java new file mode 100644 index 0000000..2c834ba --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetDocumentTypesRequest.java @@ -0,0 +1,43 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:59 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "GetDocumentTypesRequest") +public class GetDocumentTypesRequest { + private String tripId; + private String dispatchStationId; + private String arrivalStationId; + + public String getTripId() { + return tripId; + } + + public void setTripId(String tripId) { + this.tripId = tripId; + } + + public String getDispatchStationId() { + return dispatchStationId; + } + + public void setDispatchStationId(String dispatchStationId) { + this.dispatchStationId = dispatchStationId; + } + + public String getArrivalStationId() { + return arrivalStationId; + } + + public void setArrivalStationId(String arrivalStationId) { + this.arrivalStationId = arrivalStationId; + } + +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetDocumentTypesResponse.java b/src/main/java/com/artmark/avs5rs/model/GetDocumentTypesResponse.java new file mode 100644 index 0000000..83717bb --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetDocumentTypesResponse.java @@ -0,0 +1,28 @@ +package com.artmark.avs5rs.model; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:59 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "GetDocumentTypesResponse") +public class GetDocumentTypesResponse { + @XmlElement(name = "DocumentType") + private List documentTypes; + + public List getDocumentTypes() { + return documentTypes; + } + + public void setDocumentTypes(List documentTypes) { + this.documentTypes = documentTypes; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetFreeSeatsRequest.java b/src/main/java/com/artmark/avs5rs/model/GetFreeSeatsRequest.java new file mode 100644 index 0000000..41e00b9 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetFreeSeatsRequest.java @@ -0,0 +1,52 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:53 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "GetFreeSeatsRequest") +public class GetFreeSeatsRequest { + + /** + * Идентификатор рейса. Обязательный. + */ + private String tripId; + /** + * Идентификатор станции отправления. Обязательный. + */ + private String dispatchStationId; + /** + * Идентификатор станции назначения. Обязательный. + */ + private String arrivalStationId; + + public String getTripId() { + return tripId; + } + + public void setTripId(String tripId) { + this.tripId = tripId; + } + + public String getDispatchStationId() { + return dispatchStationId; + } + + public void setDispatchStationId(String dispatchStationId) { + this.dispatchStationId = dispatchStationId; + } + + public String getArrivalStationId() { + return arrivalStationId; + } + + public void setArrivalStationId(String arrivalStationId) { + this.arrivalStationId = arrivalStationId; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetFreeSeatsResponse.java b/src/main/java/com/artmark/avs5rs/model/GetFreeSeatsResponse.java new file mode 100644 index 0000000..70be382 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetFreeSeatsResponse.java @@ -0,0 +1,27 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:54 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "GetFreeSeatsResponse") +public class GetFreeSeatsResponse { + @XmlElement(name = "Seat") + private List seats; + + public List getSeats() { + return seats; + } + + public void setSeats(List seats) { + this.seats = seats; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetOrderRequest.java b/src/main/java/com/artmark/avs5rs/model/GetOrderRequest.java new file mode 100644 index 0000000..508526a --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetOrderRequest.java @@ -0,0 +1,24 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:15 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "GetOrderRequest") +public class GetOrderRequest { + private String orderId; + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetOrderResponse.java b/src/main/java/com/artmark/avs5rs/model/GetOrderResponse.java new file mode 100644 index 0000000..6833007 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetOrderResponse.java @@ -0,0 +1,37 @@ +package com.artmark.avs5rs.model; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:15 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "GetOrderResponse") +public class GetOrderResponse { + private String orderId; + @XmlElement(name = "Ticket") + private List tickets; + + public String getOrderId() { + return orderId; + } + + public void setOrderId(String orderId) { + this.orderId = orderId; + } + + public List getTickets() { + return tickets; + } + + public void setTickets(List tickets) { + this.tickets = tickets; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetTicketTypesRequest.java b/src/main/java/com/artmark/avs5rs/model/GetTicketTypesRequest.java new file mode 100644 index 0000000..5c6dd56 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetTicketTypesRequest.java @@ -0,0 +1,42 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:55 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "GetTicketTypesRequest") +public class GetTicketTypesRequest { + private String tripId; + private String dispatchStationId; + private String arrivalStationId; + + public String getTripId() { + return tripId; + } + + public void setTripId(String tripId) { + this.tripId = tripId; + } + + public String getDispatchStationId() { + return dispatchStationId; + } + + public void setDispatchStationId(String dispatchStationId) { + this.dispatchStationId = dispatchStationId; + } + + public String getArrivalStationId() { + return arrivalStationId; + } + + public void setArrivalStationId(String arrivalStationId) { + this.arrivalStationId = arrivalStationId; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetTicketTypesResponse.java b/src/main/java/com/artmark/avs5rs/model/GetTicketTypesResponse.java new file mode 100644 index 0000000..71fc931 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetTicketTypesResponse.java @@ -0,0 +1,28 @@ +package com.artmark.avs5rs.model; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:58 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "GetTicketTypesResponse") +public class GetTicketTypesResponse { + @XmlElement(name = "TicketType") + private List ticketTypes; + + public List getTicketTypes() { + return ticketTypes; + } + + public void setTicketTypes(List ticketTypes) { + this.ticketTypes = ticketTypes; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetTripStopsRequest.java b/src/main/java/com/artmark/avs5rs/model/GetTripStopsRequest.java new file mode 100644 index 0000000..75a1c5f --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetTripStopsRequest.java @@ -0,0 +1,28 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:49 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "GetTripStopsRequest") +public class GetTripStopsRequest { + + /** + * Идентификатор рейса. Обязательно. + */ + private String tripId; + + public String getTripId() { + return tripId; + } + + public void setTripId(String tripId) { + this.tripId = tripId; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/GetTripStopsResponse.java b/src/main/java/com/artmark/avs5rs/model/GetTripStopsResponse.java new file mode 100644 index 0000000..8b5bb7d --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/GetTripStopsResponse.java @@ -0,0 +1,27 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:49 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "GetTripStopsResponse") +public class GetTripStopsResponse { + @XmlElement(name = "Stop") + private List stops; + + public List getStops() { + return stops; + } + + public void setStops(List stops) { + this.stops = stops; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/Passenger.java b/src/main/java/com/artmark/avs5rs/model/Passenger.java new file mode 100644 index 0000000..aad78c2 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Passenger.java @@ -0,0 +1,149 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Date; + +/** + * Пассажир + * + * @author V.Skorykh + * @since 31.01.2008 21:36:36 + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Passenger") +public class Passenger { + + /** + * Фамилия. Лимит: 64 символа. + */ + protected String lastName; + + /** + * Имя. Лимит: 64 символа. + */ + protected String firstName; + + /** + * Отчество. Заполняется для международных рейсов. Лимит: 64 символа. + */ + protected String middleName; + + /** + * Номер документа. Лимит: 16 символов. + */ + protected String docNum; + + /** + * Серия документа. Лимит: 16 символов. + */ + protected String docSeries; + + /** + * ID типа документа + */ + protected String docTypeId; + + /** + * Телефон пассажира. Может использоваться для экстренной связи с пассажиром + */ + protected String phone; + + /** + * Дата рождения. Заполняется для международных рейсов. + */ + @XmlJavaTypeAdapter(DateAdapter.class) + protected Date birthday; + + /** + * Гражданство. Лимит: 32 символа. Начиная с версии 5.2.2 можно подавать не название страны, а двузначный код страны + */ + protected String citizenshipISO2; + + /** + * Пол. См. константы GENDER_MALE и GENDER_FEMALE + */ + protected Gender gender; + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getMiddleName() { + return middleName; + } + + public void setMiddleName(String middleName) { + this.middleName = middleName; + } + + public String getDocNum() { + return docNum; + } + + public void setDocNum(String docNum) { + this.docNum = docNum; + } + + public String getDocSeries() { + return docSeries; + } + + public void setDocSeries(String docSeries) { + this.docSeries = docSeries; + } + + public String getDocTypeId() { + return docTypeId; + } + + public void setDocTypeId(String docTypeId) { + this.docTypeId = docTypeId; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + public String getCitizenshipISO2() { + return citizenshipISO2; + } + + public void setCitizenshipISO2(String citizenshipISO2) { + this.citizenshipISO2 = citizenshipISO2; + } + + public Gender getGender() { + return gender; + } + + public void setGender(Gender gender) { + this.gender = gender; + } +} \ No newline at end of file diff --git a/src/main/java/com/artmark/avs5rs/model/Response.java b/src/main/java/com/artmark/avs5rs/model/Response.java new file mode 100644 index 0000000..754ef45 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Response.java @@ -0,0 +1,82 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.*; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:10 + */ + +@XmlRootElement(name = "Response") +@XmlAccessorType(XmlAccessType.FIELD) +public class Response { + @XmlAttribute + private boolean success; + @XmlElement(name = "Body") + private T body; + @XmlElement(name = "Error") + private ResponseError error; + + public static Response ok(T body) { + Response result = new Response(); + result.success = true; + result.body = body; + return result; + } + + public static Response error(String code, String message) { + Response result = new Response(); + result.success = false; + result.error = new ResponseError(); + result.error.code = code; + result.error.message = message; + return result; + } + + + public boolean isSuccess() { + return success; + } + + public T getBody() { + return body; + } + + public ResponseError getError() { + return error; + } + + public void setSuccess(boolean success) { + this.success = success; + } + + public void setBody(T body) { + this.body = body; + } + + public void setError(ResponseError error) { + this.error = error; + } + + @XmlType(name = "ResponseError") + public static class ResponseError { + private String code; + private String message; + + public String getCode() { + return code; + } + + public String getMessage() { + return message; + } + + public void setCode(String code) { + this.code = code; + } + + public void setMessage(String message) { + this.message = message; + } + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/ReturnTicketRequest.java b/src/main/java/com/artmark/avs5rs/model/ReturnTicketRequest.java new file mode 100644 index 0000000..45a9cd3 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/ReturnTicketRequest.java @@ -0,0 +1,35 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:21 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "ReturnTicketRequest") +public class ReturnTicketRequest { + private String ticketId; + @XmlElement(name = "Agent") + private Agent agent; + + public String getTicketId() { + return ticketId; + } + + public void setTicketId(String ticketId) { + this.ticketId = ticketId; + } + + public Agent getAgent() { + return agent; + } + + public void setAgent(Agent agent) { + this.agent = agent; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/ReturnTicketResponse.java b/src/main/java/com/artmark/avs5rs/model/ReturnTicketResponse.java new file mode 100644 index 0000000..3b5704f --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/ReturnTicketResponse.java @@ -0,0 +1,26 @@ +package com.artmark.avs5rs.model; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:21 + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "ReturnTicketResponse") +public class ReturnTicketResponse { + @XmlElement(name = "Ticket") + private Ticket ticket; + + public Ticket getTicket() { + return ticket; + } + + public void setTicket(Ticket ticket) { + this.ticket = ticket; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/Sale.java b/src/main/java/com/artmark/avs5rs/model/Sale.java new file mode 100644 index 0000000..113e894 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Sale.java @@ -0,0 +1,44 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +/** + * @author Ushmodin N. + * @since 07.07.2016 12:29 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Sale") +public class Sale { + private String seatId; + private String ticketTypeId; + @XmlElement(name = "Passenger") + private Passenger passenger; + + public String getSeatId() { + return seatId; + } + + public void setSeatId(String seatId) { + this.seatId = seatId; + } + + public String getTicketTypeId() { + return ticketTypeId; + } + + public void setTicketTypeId(String ticketTypeId) { + this.ticketTypeId = ticketTypeId; + } + + public Passenger getPassenger() { + return passenger; + } + + public void setPassenger(Passenger passenger) { + this.passenger = passenger; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/SearchTripsRequest.java b/src/main/java/com/artmark/avs5rs/model/SearchTripsRequest.java new file mode 100644 index 0000000..c0314cb --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/SearchTripsRequest.java @@ -0,0 +1,54 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.util.Date; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:33 + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "SearchTripsRequest") +public class SearchTripsRequest { + + /** + * Идентификатор станции отправления + */ + private String dispatchStationId; + /** + * Идентификатор станции назначения + */ + private String arrivalStationId; + /** + * Дата на которую выполняется поиск рейса + */ + @XmlJavaTypeAdapter(DateAdapter.class) + private Date date; + + public String getDispatchStationId() { + return dispatchStationId; + } + + public void setDispatchStationId(String dispatchStationId) { + this.dispatchStationId = dispatchStationId; + } + + public String getArrivalStationId() { + return arrivalStationId; + } + + public void setArrivalStationId(String arrivalStationId) { + this.arrivalStationId = arrivalStationId; + } + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/SearchTripsResponse.java b/src/main/java/com/artmark/avs5rs/model/SearchTripsResponse.java new file mode 100644 index 0000000..d7ab664 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/SearchTripsResponse.java @@ -0,0 +1,30 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import java.util.List; + +/** + * @author Ushmodin N. + * @since 07.07.2016 10:32 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "SearchTripsResponse") +public class SearchTripsResponse { + /** + * Список рейсов + */ + @XmlElement(name = "Trip") + private List trips; + + public List getTrips() { + return trips; + } + + public void setTrips(List trips) { + this.trips = trips; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/Seat.java b/src/main/java/com/artmark/avs5rs/model/Seat.java new file mode 100644 index 0000000..4afd395 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Seat.java @@ -0,0 +1,51 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + +/** + * @author Ushmodin N. + * @since 07.07.2016 12:35 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Seat") +public class Seat { + /** + * Идентификатор места. Обязателен. Может сопадать с названием. + */ + private String id; + /** + * Название места. Обязателен. Отображается в интерфейсе пользователя. + */ + private String name; + /** + * Тип места. Не обязателен + */ + private String type; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/Station.java b/src/main/java/com/artmark/avs5rs/model/Station.java new file mode 100644 index 0000000..fb0ef2a --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Station.java @@ -0,0 +1,64 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:38 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Station") +public class Station { + /** + * Идентификатор станции. Обязателен. + */ + private String id; + /** + * Наименование станции. Обязателен. Использется для отображения в интерфейсе пользователя + */ + private String name; + /** + * Название региона станции. Не обязателен. Использется для отображения в интерфейсе пользователя + */ + private String region; + /** + * ОКАТО станции. Не обязателен. Использется для поиска одинковых станций и отображения в интерфейсе пользователя + * TODO: обязателен или нет? + */ + private String okato; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getOkato() { + return okato; + } + + public void setOkato(String okato) { + this.okato = okato; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/Stop.java b/src/main/java/com/artmark/avs5rs/model/Stop.java new file mode 100644 index 0000000..4b112b6 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Stop.java @@ -0,0 +1,125 @@ +package com.artmark.avs5rs.model; + + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.math.BigDecimal; +import java.util.Date; + +/** + * Остановка рейса + * + * @author V.Skorykh + * @since 28.08.2014 14:46 + */ +@XmlAccessorType(XmlAccessType.FIELD) +public class Stop { + + /** + * ID остановки. Совпадает с ID станции. Обязателен. + */ + private String id; + + /** + * Название остановки. Совпадает с названием станции. Обязателен. + */ + private String name; + + /** + * Район расположения остановки. Не обязателен. + */ + private String regionName; + + /** + * Дата-время прибытия на остановку. Обязателен. + */ + @XmlJavaTypeAdapter(TimestampAdapter.class) + private Date arrivalDate; + + /** + * Дата-время отправления с остановки. Обязателен. + */ + @XmlJavaTypeAdapter(TimestampAdapter.class) + private Date dispatchDate; + + /** + * Время стоянки в минутах. Не Обязателен. + */ + private Integer stopTime; + + /** + * Расстояние от пункта отправления до остановки в км. Не Обязателен. + */ + private Integer distance; + + /** + * Цена полного билета. Обязателен. + */ + private BigDecimal price; + + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getRegionName() { + return regionName; + } + + public void setRegionName(String regionName) { + this.regionName = regionName; + } + + public Date getArrivalDate() { + return arrivalDate; + } + + public void setArrivalDate(Date arrivalDate) { + this.arrivalDate = arrivalDate; + } + + public Date getDispatchDate() { + return dispatchDate; + } + + public void setDispatchDate(Date dispatchDate) { + this.dispatchDate = dispatchDate; + } + + public Integer getStopTime() { + return stopTime; + } + + public void setStopTime(Integer stopTime) { + this.stopTime = stopTime; + } + + public Integer getDistance() { + return distance; + } + + public void setDistance(Integer distance) { + this.distance = distance; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/Ticket.java b/src/main/java/com/artmark/avs5rs/model/Ticket.java new file mode 100644 index 0000000..f7a4069 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Ticket.java @@ -0,0 +1,413 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.math.BigDecimal; +import java.util.Date; + +/** + * @author Ushmodin N. + * @since 07.07.2016 12:38 + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Ticket") +public class Ticket { + /** + * Идентификатор квитанции билета. Обязателен. + */ + protected String id; + + /** + * Серия билета. Не Обязателен. + */ + protected String series; + + /** + * Номер билета. Обязателен. + */ + protected String number; + + /** + * Дата и время продажи билета. Обязателен. + */ + @XmlJavaTypeAdapter(TimestampAdapter.class) + protected Date created; + + /** + * Дата и время возврата билета. Заполняется после возврата или отмены билета. + */ + @XmlJavaTypeAdapter(TimestampAdapter.class) + protected Date returned; + + /** + * ID статуса билета. Обязателен + */ + protected TicketStatusCode status; + + /** + * класс билета. Обязателен. + */ + protected TicketClassCode ticketClass; + + /** + * ID типа билета. Обязателен. + */ + protected String typeId; + + /** + * Номер маршрута. Не Обязателен. + */ + protected String routeNum; + + /** + * Название маршрута. Обязателен. + */ + protected String routeName; + + /** + * Описание рейса. Не Обязателен. + */ + protected String description; + + /** + * Описание автобуса. Обязателен. + */ + protected String busInfo; + + /** + * Перевозчик. Обязателен. + */ + protected String carrierName; + + /** + * ИНН перевозчика. Обязателен. + */ + protected String carrierInn; + + /** + * Платформа. Не Обязателен. + */ + protected String platform; + + /** + * Дата отправления рейса. Обязателен. + */ + @XmlJavaTypeAdapter(TimestampAdapter.class) + protected Date dispatchDate; + + /** + * Станция отправления. Обязателен. + */ + protected String dispatchStation; + + /** + * Адрес отправления. Не Обязателен. + */ + protected String dispatchAddress; + + /** + * Дата и время прибытия на станцию. Обязателен. + */ + @XmlJavaTypeAdapter(TimestampAdapter.class) + protected Date arrivalDate; + + /** + * Станция назначения. Обязателен. + */ + protected String arrivalStation; + + /** + * Адрес станции прибытия. Не Обязателен. + */ + protected String arrivalAddress; + + /** + * Место. Обязателен. + */ + protected String seatName; + + + /** + * Информация о пассажире. Обязателен. + */ + @XmlElement(name = "Passenger") + protected Passenger passenger; + + /** + * Тариф (руб). Обязателен. + */ + protected BigDecimal fare; + + /** + * Cборы (руб). Обязателен. Если нет то 0. + */ + protected BigDecimal fees; + + /** + * Удержано Тариф (руб). Заполняется в случает возврата или отмены. + */ + protected BigDecimal chargeFare; + + /** + * Удержано Остальные сборы (руб). Заполняется в случает возврата или отмены. + */ + protected BigDecimal chargeOthers; + + /** + * Возврат Тариф (руб). Заполняется в случает возврата или отмены. + */ + protected BigDecimal repaymentFare; + + /** + * Возврат Остальные сборы (руб). Заполняется в случает возврата или отмены. + */ + protected BigDecimal repaymentOthers; + + /** + * Информация о страховании. Обязательно. Неоходим при печати билета. + */ + protected String insuranceInfo; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getSeries() { + return series; + } + + public void setSeries(String series) { + this.series = series; + } + + public String getNumber() { + return number; + } + + public void setNumber(String number) { + this.number = number; + } + + public Date getCreated() { + return created; + } + + public void setCreated(Date created) { + this.created = created; + } + + public Date getReturned() { + return returned; + } + + public void setReturned(Date returned) { + this.returned = returned; + } + + public TicketStatusCode getStatus() { + return status; + } + + public void setStatus(TicketStatusCode status) { + this.status = status; + } + + public TicketClassCode getTicketClass() { + return ticketClass; + } + + public void setTicketClass(TicketClassCode ticketClass) { + this.ticketClass = ticketClass; + } + + public String getTypeId() { + return typeId; + } + + public void setTypeId(String typeId) { + this.typeId = typeId; + } + + public String getRouteNum() { + return routeNum; + } + + public void setRouteNum(String routeNum) { + this.routeNum = routeNum; + } + + public String getRouteName() { + return routeName; + } + + public void setRouteName(String routeName) { + this.routeName = routeName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getBusInfo() { + return busInfo; + } + + public void setBusInfo(String busInfo) { + this.busInfo = busInfo; + } + + public String getCarrierName() { + return carrierName; + } + + public void setCarrierName(String carrierName) { + this.carrierName = carrierName; + } + + public String getCarrierInn() { + return carrierInn; + } + + public void setCarrierInn(String carrierInn) { + this.carrierInn = carrierInn; + } + + public String getPlatform() { + return platform; + } + + public void setPlatform(String platform) { + this.platform = platform; + } + + public Date getDispatchDate() { + return dispatchDate; + } + + public void setDispatchDate(Date dispatchDate) { + this.dispatchDate = dispatchDate; + } + + public String getDispatchStation() { + return dispatchStation; + } + + public void setDispatchStation(String dispatchStation) { + this.dispatchStation = dispatchStation; + } + + public String getDispatchAddress() { + return dispatchAddress; + } + + public void setDispatchAddress(String dispatchAddress) { + this.dispatchAddress = dispatchAddress; + } + + public Date getArrivalDate() { + return arrivalDate; + } + + public void setArrivalDate(Date arrivalDate) { + this.arrivalDate = arrivalDate; + } + + public String getArrivalStation() { + return arrivalStation; + } + + public void setArrivalStation(String arrivalStation) { + this.arrivalStation = arrivalStation; + } + + public String getArrivalAddress() { + return arrivalAddress; + } + + public void setArrivalAddress(String arrivalAddress) { + this.arrivalAddress = arrivalAddress; + } + + public String getSeatName() { + return seatName; + } + + public void setSeatName(String seatName) { + this.seatName = seatName; + } + + public Passenger getPassenger() { + return passenger; + } + + public void setPassenger(Passenger passenger) { + this.passenger = passenger; + } + + public BigDecimal getFare() { + return fare; + } + + public void setFare(BigDecimal fare) { + this.fare = fare; + } + + public BigDecimal getFees() { + return fees; + } + + public void setFees(BigDecimal fees) { + this.fees = fees; + } + + public BigDecimal getChargeFare() { + return chargeFare; + } + + public void setChargeFare(BigDecimal chargeFare) { + this.chargeFare = chargeFare; + } + + public BigDecimal getChargeOthers() { + return chargeOthers; + } + + public void setChargeOthers(BigDecimal chargeOthers) { + this.chargeOthers = chargeOthers; + } + + public BigDecimal getRepaymentFare() { + return repaymentFare; + } + + public void setRepaymentFare(BigDecimal repaymentFare) { + this.repaymentFare = repaymentFare; + } + + public BigDecimal getRepaymentOthers() { + return repaymentOthers; + } + + public void setRepaymentOthers(BigDecimal repaymentOthers) { + this.repaymentOthers = repaymentOthers; + } + + public String getInsuranceInfo() { + return insuranceInfo; + } + + public void setInsuranceInfo(String insuranceInfo) { + this.insuranceInfo = insuranceInfo; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/TicketClassCode.java b/src/main/java/com/artmark/avs5rs/model/TicketClassCode.java new file mode 100644 index 0000000..b698ee8 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/TicketClassCode.java @@ -0,0 +1,17 @@ +package com.artmark.avs5rs.model; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:36 + */ + +public enum TicketClassCode { + /** + * Пассажирский билет, с выделением места + */ + PASSENGER, + /** + * Багажный билет, без выделения места + */ + BAGGAGE +} diff --git a/src/main/java/com/artmark/avs5rs/model/TicketStatusCode.java b/src/main/java/com/artmark/avs5rs/model/TicketStatusCode.java new file mode 100644 index 0000000..4a9c3bc --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/TicketStatusCode.java @@ -0,0 +1,29 @@ +package com.artmark.avs5rs.model; + +/** + * @author Ushmodin N. + * @since 07.07.2016 12:45 + */ + +public enum TicketStatusCode { + /** + * Забронирован. Данный статус билет получает после бронирования. bookOrder + */ + RESERVED, + + /** + * Продан. Данный статус билет получает после операции продажи. confirmOrder + */ + SOLD, + + + /** + * Отмена билета. Данный статус билет получает после отмены билета. cancelTicket + */ + CANCELED, + + /** + * Выполнен возврат билета. Данный статус билет получает после возрата билета. returnTicket + */ + RETURNED +} diff --git a/src/main/java/com/artmark/avs5rs/model/TicketType.java b/src/main/java/com/artmark/avs5rs/model/TicketType.java new file mode 100644 index 0000000..8890eef --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/TicketType.java @@ -0,0 +1,65 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; +import java.math.BigDecimal; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:34 + */ + +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "TicketType") +public class TicketType { + /** + * Идентификатор типа билета. Обязателен. Может совпадать с названием. + */ + private String id; + /** + * Название типа билета. Обязателен. + */ + private String name; + /** + * Цена для заданного типа билета (со сборами). + */ + private BigDecimal price; + /** + * Класс билета + */ + private TicketClassCode ticketClass; + + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public TicketClassCode getTicketClass() { + return ticketClass; + } + + public void setTicketClass(TicketClassCode ticketClass) { + this.ticketClass = ticketClass; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/TimestampAdapter.java b/src/main/java/com/artmark/avs5rs/model/TimestampAdapter.java new file mode 100644 index 0000000..7f86e89 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/TimestampAdapter.java @@ -0,0 +1,26 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.adapters.XmlAdapter; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * @author Ushmodin N. + * @since 07.07.2016 14:36 + */ + +public class TimestampAdapter extends XmlAdapter { + + private static final String FORMAT = "yyyy-MM-dd'T'HH:mm:ss"; + + @Override + public Date unmarshal(String s) throws Exception { + return new SimpleDateFormat(FORMAT).parse(s); + } + + @Override + public String marshal(Date date) throws Exception { + return new SimpleDateFormat(FORMAT).format(date); + } +} + diff --git a/src/main/java/com/artmark/avs5rs/model/Trip.java b/src/main/java/com/artmark/avs5rs/model/Trip.java new file mode 100644 index 0000000..f4ae87e --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/Trip.java @@ -0,0 +1,262 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlType; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; +import java.math.BigDecimal; +import java.util.Date; + +/** + * @author Ushmodin N. + * @since 07.07.2016 11:42 + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlType(name = "Trip") +public class Trip { + /** + * ID рейса. Обязателен. + */ + private String id; + + /** + * Номер маршрута. Не обязателен. + */ + private String num; + + /** + * Название маршрута. Обязателен. + */ + private String name; + + /** + * Дата и время отправления. Обязателен. + */ + @XmlJavaTypeAdapter(TimestampAdapter.class) + private Date dispatchDate; + + /** + * Дата и время прибытия. Обязателен. + */ + @XmlJavaTypeAdapter(TimestampAdapter.class) + private Date arrivalDate; + + /** + * ID станции отправления. Обязателен. + */ + private String dispatchStationId; + + /** + * Станция отправления рейса. Обязателен. + */ + private String dispatchStationName; + + /** + * ID станции назначения. Обязателен. + */ + private String arrivalStationId; + + /** + * Станция назначения рейса. Обязателен. + */ + private String arrivalStationName; + + /** + * Цена полного проездного билета (включая сборы). Обязателен. + */ + private BigDecimal price; + + /** + * Название перевозчика. Не Обязателен. + */ + private String carrierName; + + /** + * ИНН перевозчика. Обязателен. + */ + private String carrierInn; + + /** + * Описание автобуса. Обязателен. + */ + private String busInfo; + + /** + * Флаг обязательности ввода дополнительных персональных данных покупателя. + * Основые персональные данные: Имя, Фамилия, Тип документа, Номер документа. + * Дополнительные персональные данные: Отчество, Пол, Дата рождения, Гражданство. + * Ввод дополнительных данных требуется во исполнение статьи 11 закона "О транспортной безопасности" + * (с изменениями на 3 февраля 2014 года). + *

+ * См. http://docs.cntd.ru/document/902027326 + * + * Обязателен. Система не поддерживает, возвращать всегда true. + */ + private Boolean extDataRequired; + + /** + * тип рейса. Обязателен. + */ + private TripTypeCode type; + + + /** + * статус рейса. Обязателен. + */ + private TripStatusCode status; + + + /** + * Количество мест в автобусе. Обязателен. + */ + private Integer seatCount; + + /** + * Кол-во мест, доступных для продажи. Обязателен. + */ + private Integer freeSeatCount; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getNum() { + return num; + } + + public void setNum(String num) { + this.num = num; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getDispatchDate() { + return dispatchDate; + } + + public void setDispatchDate(Date dispatchDate) { + this.dispatchDate = dispatchDate; + } + + public Date getArrivalDate() { + return arrivalDate; + } + + public void setArrivalDate(Date arrivalDate) { + this.arrivalDate = arrivalDate; + } + + public String getDispatchStationId() { + return dispatchStationId; + } + + public void setDispatchStationId(String dispatchStationId) { + this.dispatchStationId = dispatchStationId; + } + + public String getDispatchStationName() { + return dispatchStationName; + } + + public void setDispatchStationName(String dispatchStationName) { + this.dispatchStationName = dispatchStationName; + } + + public String getArrivalStationId() { + return arrivalStationId; + } + + public void setArrivalStationId(String arrivalStationId) { + this.arrivalStationId = arrivalStationId; + } + + public String getArrivalStationName() { + return arrivalStationName; + } + + public void setArrivalStationName(String arrivalStationName) { + this.arrivalStationName = arrivalStationName; + } + + public BigDecimal getPrice() { + return price; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + + public String getCarrierName() { + return carrierName; + } + + public void setCarrierName(String carrierName) { + this.carrierName = carrierName; + } + + public String getCarrierInn() { + return carrierInn; + } + + public void setCarrierInn(String carrierInn) { + this.carrierInn = carrierInn; + } + + public String getBusInfo() { + return busInfo; + } + + public void setBusInfo(String busInfo) { + this.busInfo = busInfo; + } + + public Boolean getExtDataRequired() { + return extDataRequired; + } + + public void setExtDataRequired(Boolean extDataRequired) { + this.extDataRequired = extDataRequired; + } + + public TripTypeCode getType() { + return type; + } + + public void setType(TripTypeCode type) { + this.type = type; + } + + public TripStatusCode getStatus() { + return status; + } + + public void setStatus(TripStatusCode status) { + this.status = status; + } + + public Integer getSeatCount() { + return seatCount; + } + + public void setSeatCount(Integer seatCount) { + this.seatCount = seatCount; + } + + public Integer getFreeSeatCount() { + return freeSeatCount; + } + + public void setFreeSeatCount(Integer freeSeatCount) { + this.freeSeatCount = freeSeatCount; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/TripStatusCode.java b/src/main/java/com/artmark/avs5rs/model/TripStatusCode.java new file mode 100644 index 0000000..e5aedfa --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/TripStatusCode.java @@ -0,0 +1,25 @@ +package com.artmark.avs5rs.model; + +/** + * @author Ushmodin N. + * @since 07.07.2016 12:24 + */ + +public enum TripStatusCode { + /** + * В продаже. На рейса доступны все опрерации. + */ + ON_SALE, + /** + * Приостановка остановка продажи. Рейс не доступен для продажи. + */ + SUSPENDED, + /** + * Рейс отменен. Рейс не доступен для продажи. + */ + CANCELED, + /** + * Неопределенный статус. Рейс не доступен для продажи. + */ + UNKNOWN +} diff --git a/src/main/java/com/artmark/avs5rs/model/TripTypeCode.java b/src/main/java/com/artmark/avs5rs/model/TripTypeCode.java new file mode 100644 index 0000000..e8412b9 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/TripTypeCode.java @@ -0,0 +1,43 @@ +package com.artmark.avs5rs.model; + +/** + * @author Ushmodin N. + * @since 07.07.2016 12:23 + */ +public enum TripTypeCode { + /** + * Типа рейса - Междугородный + */ + INTERURBAN, + + /** + * Типа рейса - Пригородный + */ + SUBURBAN, + + /** + * Типа рейса - Международный + */ + INTERNATIONAL, + + /** + * Типа рейса - Внутриобластной + */ + INTRAREGIONAL, + + /** + * Типа рейса - Межобластной + */ + INTERREGIONAL, + + /** + * Типа рейса - Межреспубликанский + */ + INTERREPUBLICAN, + + /** + * Типа рейса - Внутрирайонный + */ + INTRADISTRICT, + +} diff --git a/src/main/java/com/artmark/avs5rs/model/UpdateTicketRequest.java b/src/main/java/com/artmark/avs5rs/model/UpdateTicketRequest.java new file mode 100644 index 0000000..ade5d11 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/UpdateTicketRequest.java @@ -0,0 +1,44 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * @author Ushmodin N. + * @since 12.07.2016 12:14 + */ +@XmlRootElement(name = "UpdateTicketRequest") +@XmlAccessorType(XmlAccessType.FIELD) +public class UpdateTicketRequest { + private String ticketId; + @XmlElement(name = "Passenger") + private Passenger passenger; + @XmlElement(name = "Agent") + private Agent agent; + + public String getTicketId() { + return ticketId; + } + + public void setTicketId(String ticketId) { + this.ticketId = ticketId; + } + + public Passenger getPassenger() { + return passenger; + } + + public void setPassenger(Passenger passenger) { + this.passenger = passenger; + } + + public Agent getAgent() { + return agent; + } + + public void setAgent(Agent agent) { + this.agent = agent; + } +} diff --git a/src/main/java/com/artmark/avs5rs/model/UpdateTicketResponse.java b/src/main/java/com/artmark/avs5rs/model/UpdateTicketResponse.java new file mode 100644 index 0000000..4cba132 --- /dev/null +++ b/src/main/java/com/artmark/avs5rs/model/UpdateTicketResponse.java @@ -0,0 +1,25 @@ +package com.artmark.avs5rs.model; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlType; + +/** + * @author Ushmodin N. + * @since 12.07.2016 12:13 + */ +@XmlType(name = "UpdateTicketResponse") +@XmlAccessorType(XmlAccessType.FIELD) +public class UpdateTicketResponse { + @XmlElement(name = "Ticket") + private Ticket ticket; + + public Ticket getTicket() { + return ticket; + } + + public void setTicket(Ticket ticket) { + this.ticket = ticket; + } +}