(MVC) MVC (2013)

<< назад    CMS сайта продажи авиабилетов.



На этой страничке я расскажу об одном из самых сложных в моей жизни завершенных проектов, которые я поднял с нуля, от начала до конца. Который несколько лет успешно работал, а потом по непонятной причине был закрыт. Ну как бы под предлогом, что владельцу этого бизнеса яжело платить копеечную сумму за хостинг этого проекта. Что было на самом деле - я не знаю, возможно опять возрос рейтинг Солнцеликого Хуепутина, а как известно каждый процент роста рейтинга приводит к 10% обнищанию населения, и обнищавшее население просто перестало покупать авиабилеты для отпуска в жарких странах. Может появился рядом какой-то конкурент и владелец вообще решил свернуть свой бизнес. Непопнятно... Но я расскажу о своем - о проекте, над которым я долго ломал голову, и который работал очень успешно.

Во первых, у меня сохранился календарный план работы, который я составлял в марте 2012-го года, когда проект с одной стороны уже прекрасно работал, а с другой стороны было миллион желаний и у меня и у заказчика - развивать это проект дальше по множеству направлений.


Этот проект был примерно третий по сложности в моей жизни, поэтому я хотел бы просто для начала оценить объем кода только на формах. Это почти сто тысяч строк кода только непосредсвенно в проекте VS2010. Это 720 файлов, 5388 классов. Безусловно, тут есть какая-то часть автоматически сгенерированного кода, но видно что это не проект на три строчки. Количество форм этого проекта тоже немаленькое - вы можете увидеть их справа





Еще одна харакретистика этого проекта - это DBML (именованные кеши в памяти, предназначенные для обмена данными с SQL-сервером. Вот взгляните на них.





Кроме того, для этого проекта очень много кода было написано не на Бейсике, а на FLEX-AIR. Ниже вы можете увидеть пример служебной программы - парсера, который я написал на AIR.





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





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





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





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





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





Кроме того, билеты могут быть загружены вручную, ну например менеджер о чем-то с кем-то договорился, выкупил что-то, берет горячее направление и загружает свои 10 билетов в общую базу. Либо в пакете, экспортировав свой список из Excel, либо просто по одному билету.





Таким образом формируется общая база билетов.





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





Есть всякие контроли, например если запущенный парсер занес в базу билеты без цен (такое бывает у авиакомпаний). Такие билеты отбираются и менеджер должен определится с ценой.





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





Собственно с билетами все тоже не так просто. Есть билеты одиночные, есть двойные (туда-обратно). Цена по разному формируется всякий раз.



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





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





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





Есть база туристов.





И вот здесь, стоп. Самый важный аспект этого сайта. Это не одиночный сайт, а центр управления дилерскими агентсвами (кассами) и мелкими сайтами, которые продают билеты, выкупленные менеджерами этой фирмы. Подробнее о системе интеграции с диллерами можно посмотреть на страничке B2B-Сервисы с криптографическим залогиниванием (для клиентской и серверной интеграции).


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





Неожиданно сложным для программирования оказался компонент сайта, который бы позволял предложить клиентам билеты со сдвижкой по дате (+/- три дня).





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



   1:  Imports Microsoft.VisualBasic
   2:   
   3:  Public Class ReturnTicket
   4:   
   5:      'поиск обратного билета - на входе два рекордсета - прямые билеты и обратные
   6:      'Dim FromTicket As System.Collections.Generic.List(Of DB.GetTicketResult) = db1.GetTicket(SessionTicketRequest.FromCountry, SessionTicketRequest.FromCity, SessionTicketRequest.ToCountry, SessionTicketRequest.ToCity, FromDate_).ToList
   7:      'Dim ToTicket As System.Collections.Generic.List(Of DB.GetTicketResult) = db2.GetTicket(SessionTicketRequest.ToCountry, SessionTicketRequest.ToCity, SessionTicketRequest.FromCountry, SessionTicketRequest.FromCity, ToDate_).ToList
   8:      'предполагается что по странам и датам все уже подобрано (еще на этапе отбора из SQL)
   9:      '
  10:   
  11:      Public Function CheckReturnTicket(ByVal FromTicket As System.Collections.Generic.List(Of DB.GetTicketResult), ByVal ToTicket As System.Collections.Generic.List(Of DB.GetTicketResult)) As System.Collections.Generic.List(Of OneTicketWithReturn)
  12:          Dim ContinueSearch As Boolean = False
  13:          Dim _CheckReturnTicket = New System.Collections.Generic.List(Of OneTicketWithReturn)
  14:          'до первого шага - вдруг обратный билет УЖЕ пришел в параметрах и требуется не искать, а только зацепить билеты в блок
  15:          If ToTicket IsNot Nothing And FromTicket IsNot Nothing Then
  16:              If ToTicket.Count > 0 And FromTicket.Count > 0 Then
  17:                  If ToTicket.Count = 1 Then
  18:                      For i As Integer = 0 To FromTicket.Count - 1
  19:                          'альтернатив нет - добавляем единственное что есть
  20:                          _CheckReturnTicket.Add(New OneTicketWithReturn(FromTicket(i), ToTicket(0)))
  21:                      Next
  22:                      Return _CheckReturnTicket
  23:                  End If
  24:              End If
  25:          End If
  26:          'первый шаг - совпадает AviaCompanyCode, Supplier
  27:          For i As Integer = 0 To FromTicket.Count - 1
  28:              For j As Integer = 0 To ToTicket.Count - 1
  29:                  If FromTicket(i).AviaCompanyCode = ToTicket(j).AviaCompanyCode And
  30:                     FromTicket(i).Supplier = ToTicket(j).Supplier And
  31:                     FromTicket(i).FromDate <= ToTicket(j).FromDate Then
  32:                      'добавляем найденный обратный билет
  33:                      _CheckReturnTicket.Add(New OneTicketWithReturn(FromTicket(i), ToTicket(j)))
  34:                      GoTo Next1
  35:                  End If
  36:              Next
  37:              'добавили прямой без обратного
  38:              ContinueSearch = True
  39:              _CheckReturnTicket.Add(New OneTicketWithReturn(FromTicket(i)))
  40:  Next1:
  41:          Next
  42:          'второй шаг - совпадает AviaCompanyCode
  43:          If ContinueSearch Then
  44:              For i As Integer = 0 To FromTicket.Count - 1
  45:                  If _CheckReturnTicket(i).FromTicket IsNot Nothing And _CheckReturnTicket(i).Toticket Is Nothing Then
  46:                      For j As Integer = 0 To ToTicket.Count - 1
  47:                          If FromTicket(i).AviaCompanyCode = ToTicket(j).AviaCompanyCode And
  48:                             FromTicket(i).FromDate <= ToTicket(j).FromDate Then
  49:                              _CheckReturnTicket(i).ToTicket = ToTicket(j)
  50:                              GoTo Next2
  51:                          End If
  52:                      Next
  53:                  End If
  54:  Next2:
  55:              Next
  56:          End If
  57:          'третий шаг - совпадает Supplier
  58:          If ContinueSearch Then
  59:              For i As Integer = 0 To FromTicket.Count - 1
  60:                  If _CheckReturnTicket(i).FromTicket IsNot Nothing And _CheckReturnTicket(i).Toticket Is Nothing Then
  61:                      For j As Integer = 0 To ToTicket.Count - 1
  62:                          If FromTicket(i).Supplier = ToTicket(j).Supplier And
  63:                             FromTicket(i).FromDate <= ToTicket(j).FromDate Then
  64:                              _CheckReturnTicket(i).ToTicket = ToTicket(j)
  65:                              GoTo Next3
  66:                          End If
  67:                      Next
  68:                  End If
  69:  Next3:
  70:              Next
  71:          End If
  72:          'третий шаг - любой билет
  73:          If ContinueSearch Then
  74:              For i As Integer = 0 To FromTicket.Count - 1
  75:                  If _CheckReturnTicket(i).FromTicket IsNot Nothing And _CheckReturnTicket(i).Toticket Is Nothing Then
  76:                      For j As Integer = 0 To ToTicket.Count - 1
  77:                          If FromTicket(i).FromDate <= ToTicket(j).FromDate Then
  78:                              _CheckReturnTicket(i).ToTicket = ToTicket(j)
  79:                              GoTo Next4
  80:                          End If
  81:                      Next
  82:                  End If
  83:  Next4:
  84:              Next
  85:          End If
  86:          Return _CheckReturnTicket
  87:      End Function
  88:   
  89:   
  90:      Public Function CheckReturnTicketLESS(ByVal FromTicket As System.Collections.Generic.List(Of DB.GetTicketLESSResult), ByVal ToTicket As System.Collections.Generic.List(Of DB.GetTicketResult)) As System.Collections.Generic.List(Of OneLESSTicketWithReturn)
  91:          Dim ContinueSearch As Boolean = False
  92:          Dim _CheckReturnTicket = New System.Collections.Generic.List(Of OneLESSTicketWithReturn)
  93:          'до первого шага - вдруг обратный билет УЖЕ пришел в параметрах и требуется не искать, а только зацепить билеты в блок
  94:          If ToTicket IsNot Nothing And FromTicket IsNot Nothing Then
  95:              If ToTicket.Count > 0 And FromTicket.Count > 0 Then
  96:                  If ToTicket.Count = 1 Then
  97:                      For i As Integer = 0 To FromTicket.Count - 1
  98:                          'альтернатив нет - добавляем единственное что есть
  99:                          _CheckReturnTicket.Add(New OneLESSTicketWithReturn(FromTicket(i), ToTicket(0)))
 100:                      Next
 101:                      ContinueSearch = True
 102:                      Return _CheckReturnTicket
 103:                  End If
 104:              End If
 105:          End If
 106:          'первый шаг - совпадает AviaCompanyCode, Supplier
 107:          For i As Integer = 0 To FromTicket.Count - 1
 108:              For j As Integer = 0 To ToTicket.Count - 1
 109:                  If FromTicket(i).AviaCompanyCode = ToTicket(j).AviaCompanyCode And
 110:                     FromTicket(i).Supplier = ToTicket(j).Supplier And
 111:                     FromTicket(i).FromDate <= ToTicket(j).FromDate Then
 112:                      _CheckReturnTicket.Add(New OneLESSTicketWithReturn(FromTicket(i), ToTicket(j)))
 113:                      GoTo Next1
 114:                  End If
 115:              Next
 116:              'добавили прямой без обратного
 117:              ContinueSearch = True
 118:              _CheckReturnTicket.Add(New OneLESSTicketWithReturn(FromTicket(i)))
 119:  Next1:
 120:          Next
 121:          'второй шаг - совпадает AviaCompanyCode
 122:          If ContinueSearch Then
 123:              For i As Integer = 0 To FromTicket.Count - 1
 124:                  If _CheckReturnTicket(i).FromTicket IsNot Nothing And _CheckReturnTicket(i).ToTicket Is Nothing Then
 125:                      For j As Integer = 0 To ToTicket.Count - 1
 126:                          If FromTicket(i).AviaCompanyCode = ToTicket(j).AviaCompanyCode And
 127:                             FromTicket(i).FromDate <= ToTicket(j).FromDate Then
 128:                              _CheckReturnTicket(i).ToTicket = ToTicket(j)
 129:                              GoTo Next2
 130:                          End If
 131:                      Next
 132:                  End If
 133:  Next2:
 134:              Next
 135:          End If
 136:          'третий шаг - совпадает Supplier
 137:          If ContinueSearch Then
 138:              For i As Integer = 0 To FromTicket.Count - 1
 139:                  If _CheckReturnTicket(i).FromTicket IsNot Nothing And _CheckReturnTicket(i).ToTicket Is Nothing Then
 140:                      For j As Integer = 0 To ToTicket.Count - 1
 141:                          If FromTicket(i).Supplier = ToTicket(j).Supplier And
 142:                             FromTicket(i).FromDate <= ToTicket(j).FromDate Then
 143:                              _CheckReturnTicket(i).ToTicket = ToTicket(j)
 144:                              GoTo Next3
 145:                          End If
 146:                      Next
 147:                  End If
 148:  Next3:
 149:              Next
 150:          End If
 151:          'третий шаг - любой билет
 152:          If ContinueSearch Then
 153:              For i As Integer = 0 To FromTicket.Count - 1
 154:                  If _CheckReturnTicket(i).FromTicket IsNot Nothing And _CheckReturnTicket(i).ToTicket Is Nothing Then
 155:                      For j As Integer = 0 To ToTicket.Count - 1
 156:                          If FromTicket(i).FromDate <= ToTicket(j).FromDate Then
 157:                              _CheckReturnTicket(i).ToTicket = ToTicket(j)
 158:                              GoTo Next4
 159:                          End If
 160:                      Next
 161:                  End If
 162:  Next4:
 163:              Next
 164:          End If
 165:          Return _CheckReturnTicket
 166:      End Function
 167:   
 168:   
 169:      '
 170:      'В отличии от предыдущей функции - проходит только по тем билетам, у которых нет обратно и подтягивает новые билеты из базы
 171:      '
 172:      Public Function CheckReturnTicketLESS_1(ByVal TicketWithReturn As System.Collections.Generic.List(Of OneLESSTicketWithReturn)) As System.Collections.Generic.List(Of OneLESSTicketWithReturn)
 173:          'первый шаг - совпадает AviaCompanyCode, Supplier
 174:          Dim db1 = New DB.FlySeasonDataContext, RetTicket 'As System.Collections.Generic.IList(Of DB.GetTicketLESSResult)
 175:          For i As Integer = 0 To TicketWithReturn.Count - 1
 176:              If TicketWithReturn(i).ToTicket Is Nothing Then
 177:                  'у этого прямого билета нет обратного билета
 178:                  RetTicket = db1.GetTicketLESS(TicketWithReturn(i).FromTicket.ToCountry, TicketWithReturn(i).FromTicket.ToCity, TicketWithReturn(i).FromTicket.FromCountry, TicketWithReturn(i).FromTicket.FromCity, TicketWithReturn(i).FromTicket.FromDate).ToList()
 179:                  If RetTicket IsNot Nothing Then
 180:                      If RetTicket.Count > 0 Then
 181:                          If RetTicket(0).FromDate > TicketWithReturn(i).FromTicket.FromDate Then
 182:                              TicketWithReturn(i).SetToTicket(RetTicket(0))
 183:                          End If
 184:                      End If
 185:                  End If
 186:              End If
 187:          Next
 188:          Return TicketWithReturn
 189:      End Function
 190:   
 191:   
 192:      '
 193:      'В отличии от предыдущей функции - проходит только по тем билетам, у которых нет обратно и подтягивает новые билеты из базы
 194:      '
 195:      Public Function CheckReturnTicketLESS_2(ByVal FromTicket As System.Collections.Generic.List(Of DB.GetTicketLESSResult), ByVal ToDate As DateTime) As System.Collections.Generic.List(Of OneLESSTicketWithReturn)
 196:          Dim _CheckReturnTicket = New System.Collections.Generic.List(Of OneLESSTicketWithReturn)
 197:          Dim db1 = New DB.FlySeasonDataContext, RetTicket As System.Collections.Generic.List(Of DB.GetTicketLESSResult)
 198:          For i As Integer = 0 To FromTicket.Count - 1
 199:              'у этого прямого билета нет обратного билета
 200:              RetTicket = db1.GetTicketLESS(FromTicket(i).ToCountry, FromTicket(i).ToCity, FromTicket(i).FromCountry, FromTicket(i).FromCity, ToDate).ToList()
 201:              If RetTicket IsNot Nothing Then
 202:                  If RetTicket.Count > 0 Then
 203:                      _CheckReturnTicket.Add(New OneLESSTicketWithReturn(FromTicket(i), RetTicket(0)))
 204:                  Else
 205:                      _CheckReturnTicket.Add(New OneLESSTicketWithReturn(FromTicket(i)))
 206:                  End If
 207:              Else
 208:                  _CheckReturnTicket.Add(New OneLESSTicketWithReturn(FromTicket(i)))
 209:              End If
 210:          Next
 211:          Return _CheckReturnTicket
 212:      End Function
 213:   
 214:   
 215:      Public Function CheckReturnTicketMORE(ByVal FromTicket As System.Collections.Generic.List(Of DB.GetTicketMOREResult), ByVal ToTicket As System.Collections.Generic.List(Of DB.GetTicketResult)) As System.Collections.Generic.List(Of OneMORETicketWithReturn)
 216:          Dim ContinueSearch As Boolean = False
 217:          Dim _CheckReturnTicket = New System.Collections.Generic.List(Of OneMORETicketWithReturn)
 218:          'до первого шага - вдруг обратный билет УЖЕ пришел в параметрах и требуется не искать, а только зацепить билеты в блок
 219:          If ToTicket IsNot Nothing And FromTicket IsNot Nothing Then
 220:              If ToTicket.Count > 0 And FromTicket.Count > 0 Then
 221:                  If ToTicket.Count = 1 Then
 222:                      For i As Integer = 0 To FromTicket.Count - 1
 223:                          'альтернатив нет - добавляем единственное что есть
 224:                          _CheckReturnTicket.Add(New OneMORETicketWithReturn(FromTicket(i), ToTicket(0)))
 225:                      Next
 226:                      Return _CheckReturnTicket
 227:                  End If
 228:              End If
 229:          End If
 230:          'первый шаг - совпадает AviaCompanyCode, Supplier
 231:          For i As Integer = 0 To FromTicket.Count - 1
 232:              For j As Integer = 0 To ToTicket.Count - 1
 233:                  If FromTicket(i).AviaCompanyCode = ToTicket(j).AviaCompanyCode And
 234:                     FromTicket(i).Supplier = ToTicket(j).Supplier And
 235:                     FromTicket(i).FromDate <= ToTicket(j).FromDate Then
 236:                      _CheckReturnTicket.Add(New OneMORETicketWithReturn(FromTicket(i), ToTicket(j)))
 237:                      GoTo Next1
 238:                  End If
 239:              Next
 240:              'добавили прямой без обратного
 241:              ContinueSearch = True
 242:              _CheckReturnTicket.Add(New OneMORETicketWithReturn(FromTicket(i)))
 243:  Next1:
 244:          Next
 245:          'второй шаг - совпадает AviaCompanyCode
 246:          If ContinueSearch Then
 247:              For i As Integer = 0 To FromTicket.Count - 1
 248:                  If _CheckReturnTicket(i).FromTicket IsNot Nothing And _CheckReturnTicket(i).ToTicket Is Nothing Then
 249:                      For j As Integer = 0 To ToTicket.Count - 1
 250:                          If FromTicket(i).AviaCompanyCode = ToTicket(j).AviaCompanyCode And
 251:                             FromTicket(i).FromDate <= ToTicket(j).FromDate Then
 252:                              _CheckReturnTicket(i).ToTicket = ToTicket(j)
 253:                              GoTo Next2
 254:                          End If
 255:                      Next
 256:                  End If
 257:  Next2:
 258:              Next
 259:          End If
 260:          'третий шаг - совпадает Supplier
 261:          If ContinueSearch Then
 262:              For i As Integer = 0 To FromTicket.Count - 1
 263:                  If _CheckReturnTicket(i).FromTicket IsNot Nothing And _CheckReturnTicket(i).ToTicket Is Nothing Then
 264:                      For j As Integer = 0 To ToTicket.Count - 1
 265:   
 266:                          If FromTicket(i).Supplier = ToTicket(j).Supplier And
 267:                             FromTicket(i).FromDate <= ToTicket(j).FromDate Then
 268:                              _CheckReturnTicket(i).ToTicket = ToTicket(j)
 269:                              GoTo Next3
 270:                          End If
 271:                      Next
 272:                  End If
 273:  Next3:
 274:              Next
 275:          End If
 276:          'третий шаг - любой билет
 277:          If ContinueSearch Then
 278:              For i As Integer = 0 To FromTicket.Count - 1
 279:                  If _CheckReturnTicket(i).FromTicket IsNot Nothing And _CheckReturnTicket(i).ToTicket Is Nothing Then
 280:                      For j As Integer = 0 To ToTicket.Count - 1
 281:                          If FromTicket(i).FromDate <= ToTicket(j).FromDate Then
 282:                              _CheckReturnTicket(i).ToTicket = ToTicket(j)
 283:                              GoTo Next4
 284:                          End If
 285:                      Next
 286:                  End If
 287:  Next4:
 288:              Next
 289:          End If
 290:          Return _CheckReturnTicket
 291:      End Function
 292:   
 293:   
 294:      '
 295:      'В отличии от предыдущей функции - проходит только по тем билетам, у которых нет обратно и подтягивает новые билеты из базы
 296:      '
 297:      Public Function CheckReturnTicketMORE_1(ByVal TicketWithReturn As System.Collections.Generic.List(Of OneMORETicketWithReturn)) As System.Collections.Generic.List(Of OneMORETicketWithReturn)
 298:          'первый шаг - совпадает AviaCompanyCode, Supplier
 299:          Dim db1 = New DB.FlySeasonDataContext, RetTicket
 300:          For i As Integer = 0 To TicketWithReturn.Count - 1
 301:              If TicketWithReturn(i).ToTicket Is Nothing Then
 302:                  'у этого прямого билета нет обратного билета
 303:                  RetTicket = db1.GetTicketMORE(TicketWithReturn(i).FromTicket.ToCountry, TicketWithReturn(i).FromTicket.ToCity, TicketWithReturn(i).FromTicket.FromCountry, TicketWithReturn(i).FromTicket.FromCity, TicketWithReturn(i).FromTicket.FromDate).ToList()
 304:                  If RetTicket IsNot Nothing Then
 305:                      If RetTicket.Count > 0 Then
 306:                          If RetTicket(0).FromDate > TicketWithReturn(i).FromTicket.FromDate Then
 307:                              TicketWithReturn(i).SetToTicket(RetTicket(0))
 308:                          End If
 309:                      End If
 310:                  End If
 311:              End If
 312:          Next
 313:          Return TicketWithReturn
 314:      End Function
 315:   
 316:      '
 317:      'В отличии от предыдущей функции - проходит только по тем билетам, у которых нет обратно и подтягивает новые билеты из базы
 318:      '
 319:      Public Function CheckReturnTicketMORE_2(ByVal FromTicket As System.Collections.Generic.List(Of DB.GetTicketMOREResult), ByVal ToDate As DateTime) As System.Collections.Generic.List(Of OneMORETicketWithReturn)
 320:          Dim _CheckReturnTicket = New System.Collections.Generic.List(Of OneMORETicketWithReturn)
 321:          Dim db1 = New DB.FlySeasonDataContext, RetTicket As System.Collections.Generic.List(Of DB.GetTicketMOREResult)
 322:          For i As Integer = 0 To FromTicket.Count - 1
 323:              'у этого прямого билета нет обратного билета
 324:              RetTicket = db1.GetTicketMORE(FromTicket(i).ToCountry, FromTicket(i).ToCity, FromTicket(i).FromCountry, FromTicket(i).FromCity, ToDate).ToList()
 325:              If RetTicket IsNot Nothing Then
 326:                  If RetTicket.Count > 0 Then
 327:                      _CheckReturnTicket.Add(New OneMORETicketWithReturn(FromTicket(i), RetTicket(0)))
 328:                  Else
 329:                      _CheckReturnTicket.Add(New OneMORETicketWithReturn(FromTicket(i)))
 330:                  End If
 331:              Else
 332:                  _CheckReturnTicket.Add(New OneMORETicketWithReturn(FromTicket(i)))
 333:              End If
 334:          Next
 335:          Return _CheckReturnTicket
 336:      End Function
 337:   
 338:  End Class

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

Мне очень жалко, что я потратил столько сил и развивал такой сложный проект для какого-то барана, который в итоге просто отказался платить три копейки за хостинг и суппорт проекта. В итоге, такой большой мой труд прослужил всего лишь пару лет, в то время как другие мои проекты, например http://www.votpusk.ru/ служат уже 9 дет и, надеюсь, еще будут жить много-много лет.



Comments ( )
<00>  <01>  <02>  <03>  <04>  <05>  <06>  <07>  <08>  <09>  <10>  <11>  <12>  <13>  <14>  <15>  <16>  <17
Link to this page: http://www.vb-net.com/FlySeason/Index.htm
<SITEMAP>  <MVC>  <ASP>  <NET>  <DATA>  <KIOSK>  <FLEX>  <SQL>  <NOTES>  <LINUX>  <MONO>  <FREEWARE>  <DOCS>  <ENG>  <MAIL ME>  <ABOUT ME>  < THANKS ME>