Hi everyone

i have a list of records of reservations for a hotel room: 

1., dateStart1, dateEnd1

2., dateStart2, dateEnd2

n., dateStartn, dateEndn

i want to create a new reservation. for that, i have to check that the room is empty. 

i thought to compare previous.dateEnd <= current.dateStart  and 

                                  current.dateEnd <= next.dateStart.

something like 

for (int i =1; i<list.length-1; i++)

   {  if(dateEnd[i-1]<=dateStart[i] && dateEnd[i]<=dateStart[i+1])

              { save reservation

              }

   }

...but in foreach loop there's only the current record available... so ,how should i proceed? 

thx 


Hi Alex, 

The test is very simple. 

If you find any reservation for the room whose start date is prior to the desired end date and at the same time the reservation end date is after the desired start date, this room can't be used for the new reservation. 

If you have the reservations stored in database, it is easier to fetch from database if the room can be reserved, instead of fetching all reservations, using appropriated query, than iterate through the list of reservations. 

If you really need to go through the list, pass the list to a ForEach, and inside the ForEach, on every step, the Current of the list will point to the actual record. 

Cheers 

I agree with Eduardo, if you think you need a For Each to filter data, first think whether you can't solve it with an Aggregate (or if you already have one, in the Aggregate), and if you really can't, to use one of the List Actions like ListFilter.

However, to reply to your specific question, you can also index Lists, although you have to make sure not to use illegal indexes. The syntax is as can be expected: instead of MyList.Current.MyAttribute, you use MyList[index].MyAttribute. If you are itterating using a For Each, and you need e.g. the next element, use MyList[MyList.CurrentRowNumber + 1].MyAttribute. This can be a little unwieldly, especially when having nested iterations, but it works. But like I said, be sure to not use invalid indexes, so e.g. in the case of the previous example, Don't use MyList.CurrentRowNumber + 1 if you're already at the last element, so you'd need to check whether MyList.CurrentRowNumber isn't equal to MyList.Length - 1 (as the last element has a CurrentRowNumber of Length - 1).


If you can't use an Aggregate as Kilian and Eduardo suggested, you'll just need to reverse the logic you put in your original post so you're looking for the exception .  You could handle the logic and also provide feedback to the user by throwing an exception.


I would actually offer that if you cannot use an aggregate, you could avoid the iteration entirely by just using a ListFilter action from the System module. If you are using the .NET version of OutSystems, this action implements C#s LINQ beneath the covers. This would be an easily maintainable and performant solution to your problem without using a loop at all. 

All that being said, you should see if you can use an aggregate for this since it will be optimized and your check can then be done in a single step.

Solution

Grayson Udstrand wrote:

I would actually offer that if you cannot use an aggregate, you could avoid the iteration entirely by just using a ListFilter action from the System module. If you are using the .NET version of OutSystems, this action implements C#s LINQ beneath the covers. This would be an easily maintainable and performant solution to your problem without using a loop at all. 

All that being said, you should see if you can use an aggregate for this since it will be optimized and your check can then be done in a single step.

That's a great idea.  Or back to Kilian's suggestion of ListIndex.  Either do the ListFilter and throw an error if the list isn't empty, or the ListIndex and throw the error if the index is > -1.  Either way, it's much simpler than my solution above.  

Set the Condition property of ListIndexOf to:

(Reservation.StartDate > StartDate and Reservation.StartDate < EndDate)
or
(Reservation.EndDate > StartDate and Reservation.EndDate < EndDate) 



Solution

thank you all, I managed to fetch an invalid list, having the filter set to startDate<formEndDate&&formStartDate<endDate. if the list is empty, reservation ok.