"Prosty" scheduler w asp.net mvc

0

Chce zrobić coś w rodzaju planu rezerwacji:
na górnej osi będą godziny danego dnia (czyli: 10, 11, 12, 13...)
na bocznej osi będą pokoje.
i na przecięciach się odpowiednich miejsc będzie coś w rodzaju textboxa w którym będzie info o osobie która dokonała rezerwacji.

Widziałem gotowe rozwiazanie z np. DayPilot czy Telerik (Kendo), jednak wszystkie są płatne i to sporo.
Chciałbym coś takiego prostego samemu zrobić. Możecie mi pomóc, poradzić jak to zrobić?

0

Zadaj pytanie, z czym masz problem

0

Mój model (na początek prosty):

 public class Booking
    {
        public string Room { get; set; }
        public int Time { get; set; }

    }

w kontrolerze robie liste Bookings i przekazuje do widoku.
Chce mieć w widoku tabelę:
w pierwszym rzędzie będą wyświetlone cyferki od 1 do 10, natomiast w pierwszej kolumnie chce miec literki powiedzmy od A do D. I teraz jeżeli będę miał obiekt Booking w którym Room = A oraz Time = 2, no to komórka o takich współrzędnych ma być zakolorowana.

0
 
@model IEnumerable<IGrouping<int, MvcApplication1.Models.Table>>

hello! :)


table:
<br />



<table border="1">
    <thead>
        <tr>
            <th></th>
           
                @foreach (var ck in Model.First())
                {
                    <th>
                        @ck.Time

                    </th>
                }
            
        </tr>
    </thead>
    <tbody>





        @{
           
            foreach (var i in Model)
            {
                <tr>
                    <th>
                        @i.Key
                    </th>

                    @foreach (var k in i)
                    {
                        <td style="height: 40px; width:80px">
                            @if (k.Booking != null)
                            {
                                <text>asdassda</text>
                            }
                        </td>
                    }







                </tr>
            }

        }

    </tbody>
</table>


<hr/>
<br/>


dziękuję dobranoc.

0

Tak jak napisałem w komentarzu, wrzucam cały kod odpowiedzialny za generowanie takiego prostego scheduler'a. W pierwszej kolumnie po lewej stronie będziemy mieć listę pokoi. W pierwszym rzędzie będziemy mieć godziny (od otwarcia do zamknięcia, np. 9, 10, 11, 12 ....). Następnie generuje siatkę, każda komórka jest obiektem TableCell.

BookingHelper.cs:

 public class BookingHelper
    {
        public string CustomerName { get; set; }
        public string CustomerSurname { get; set; }
        public int Id { get; set; }
        public int RoomId { get; set; }
        public int Time { get; set; }
    } 

Następnie TableCell.cs:

 public class TableCell
    {
        public string RoomName { get; set; }
        public int RoomId { get; set; }
        public int Time { get; set; }
        public List<BookingHelper> Bookings { get; set; }  // używamy listy, ponieważ rezerwacja może być na np. 2 godziny, a nie tylko jedną, więc trzeba połączyć komórki
    }

Akcja w kontrolerze:


 public ActionResult List()
        {
            var userId = ((UserIdentity)this.User).Id;
            var user = userRepository.Get(userId);
            var hotel = hotelRepository.Get(user.Hotel.Id);
            var open =
                openingRepository.Openings()
                    .FirstOrDefault(x => x.DayOfWeek == DateTime.Today.DayOfWeek && x.Hotel.Id == hotel.Id);
            
           int timeAmount = (open.OpenTo - open.OpenFrom).Hours;
            var roomList = roomRepository.Rooms().Where(x => x.Hotel.Id == hotel.Id).ToList();
            var lista = new List<TableCell>();

            foreach (var room in roomList)
            {
                for (int i = 0; i < timeAmount; i++)
                {
                    var t = new TableCell
                    {
                        RoomId = room.Id,
                        RoomName = room.Name,
                        Bookings = new List<BookingHelper>(),
                        Time = open.OpenFrom.Hours + i
                    };

                    lista.Add(t);
                }
            }

            var bookinglist =
                bookingRepository.Bookings()
                    .Where(x => x.Hotel.Id == user.Hotel.Id && x.BookedFor.Date == DateTime.Today)
                    .ToList();

            for (int i = 0; i < bookinglist.Count; i++)
            {
                if (bookinglist[i].TimeAmount.Hours == 1)
                {
                    var list1 = lista.Where(
                     x =>
                     x.RoomId == bookinglist[i].Room.Id && x.Time < (bookinglist[i].BookedFor.TimeOfDay + bookinglist[i].TimeAmount).Hours
                     && x.Time >= bookinglist[i].BookedFor.Hour);

                    foreach (var v in list1)
                    {
                        var vs = new BookingHelper
                        {
                            CSurname = bookinglist[i].CustomerName,
                            CName = bookinglist[i].CustomerName,
                            Id = bookinglist[i].Id,
                            RoomId = bookinglist[i].Room.Id,
                            Time = bookinglist[i].BookedFor.Hour
                        };
                        v.Bookings.Add(vs);
                    }

                }

                if (bookinglist[i].TimeAmount.Hours > 1)
                {
                    var list1 = lista.Where(
                    x =>
                    x.RoomId == bookinglist[i].Room.Id && x.Time < (bookinglist[i].BookedFor.TimeOfDay + bookinglist[i].TimeAmount).Hours
                    && x.Time >= bookinglist[i].BookedFor.Hour);
                    var cell = lista.FirstOrDefault(x => x.RoomId == bookinglist[i].Room.Id && bookinglist[i].BookedFor.Hour == x.Time);

                    foreach (var v in list1)
                    {
                        var vs = new BookingHelper
                        {
                            CSurname = bookinglist[i].CustomerName,
                            CName = bookinglist[i].CustomerName,
                            Id = bookinglist[i].Id,
                            RoomId = bookinglist[i].Room.Id,
                            Time = bookinglist[i].BookedFor.Hour
                        };

                        cell.Bookings.Add(vs);
                    }
                }
            }
            var li = lista.GroupBy(x => x.RoomName).ToList();

            return View(li);
        }

oraz widok:

<table class="bordered">
    <thead>
        <tr>
            <th>Time / Room</th>
            @foreach (var ck in Model.First())
            {
                <th>
                    @ck.Time
                </th>
            }
        </tr>
    </thead>
    <tbody>
        @{
            foreach (var i in Model)
            {
                <tr>
                    <th>
                        Room @i.Key
                    </th>
                    @{
                var k = i.ToList();
                    }

                    @for (int j = 0; j < i.Count(); j++)
                    {
                        <td style="height: 40px; width:120px">
                            @if (k[j].Bookings.Count() != 0)
                            {
                                if (k[j].Bookings.Count() == 1)
                                {
                                    @Html.Label("Name: ")
                                    @Html.DisplayFor(item => k[j].Bookings.FirstOrDefault().CName)
                                    <br />
                                    @Html.Label("Surname: ")
                                    @Html.DisplayFor(item => k[j].Bookings.FirstOrDefault().CSurname)
                                }
                                else
                                {
                                <th colspan="@k[j].Bookings.Count()">
                                    @Html.Label("Name: ") @Html.DisplayFor(item => k[j].Bookings.FirstOrDefault().CName)<br />
                                    @Html.Label("Surname: ") @Html.DisplayFor(item => k[j].Bookings.FirstOrDefault().CSurname)
                                </th>
                                    j = j + k[j].Bookings.Count();
                                }
                            }
                        </td>
                    }
                </tr>
            }
        }
    </tbody>
</table>


Sugestie w celu usprawnienia kodu mile widziane.

1
  1. Bardzo długa metoda, gdyby foreach zastąpić przez LINQ mogłaby być przynajmniej o to krótsza.
  2. Przypadki z bookinglist[i].TimeAmount.Hours równym i większym 1 są bardzo podobne, więc można by tu utworzyć jakąś metodę, a nie kopiować i wklejać kod z drobną zmianą.
  3. Moim zdaniem wpychanie logiki bazującej na encjach do kontrolerów, nie jest dobre, ale co kto lubi.
0
  1. dzięki za odpowiedź.
  2. ciekawe dlaczego poprawiasz mój tekst i zaznaczasz że jest tam błąd ortograficzny, skoro samemu takowe popełniasz, innych użytkowników nie poprawiasz...
0

Dlaczego zapakowales w gruncie rzeczy cala logike do kontrolera?
Dlaczego nie uzywasz jakiegos mappera?

1

ja tylko sie przyczepie po raz kolejny do czytaelnosci, bo nawet jesli piszesz kod tylko i wylacznie dla siebie to rob to tak zeby inni go mogli cyztac i to czytac ze zrozumieniem, bo takiego czegos:

 foreach (var i in Model)
            {
                ...
                var k = i.ToList(); 

czy takiego

 foreach (var v in list1)
                    {
                        ...
                        v.Bookings.Add(vs);

To nawet TY za kilka tygodni nie bedziesz w stanie rozkminic, nie mowiac o kims kto siadzie po Tobie do projektu.

Tak samo masz tam list = costam. I potem operujesz na tej liscie. i teraz zeby wiedziec co to za lista to trzeba skrollowac do miejsca deklaracji lub przypisania, ew. czekasz az ci visual studio podpowie.

 @foreach (var ck in Model.First())
            {
                <th>
                    @ck.Time
                </th>
            }

z kodu powyzej to jedynie wiadomo ze wyswietla jakis czas. co to ck?? kij wie, tymbardziej ze jest to obiekt z listy Model.First , gdzie slowo first wskazuje ze bedzie to pojedynczy obiekt a nie lista.

Jeszcze raz to, ze kod sie kompiluje i dziala i robi co ma robic nie oznacza ze jest dobrze napisany, bo odlozysz ten projekt na kilka dni/tygodni i ci recze ze do niego nie wrocisz bo w co drugiej linijce bedziesz rozkminial co tu robisz i co to jest k, ck, j czy model.first.

Wygenerowany kod html tej tabeli jest niepoprawny. tagi th sa w srodku td i nie bedzie zgadzac sie ich ilosc co moze sie wysypac na niektrych przegladarkach

I do konca nie jestem przekonany ze on dziala, bo starasz sie wyswietlic elementy listy z listy tych list, co juz pokazuje jak wiele danych wejdzie w jeden wiersz. troche duzo za duzo jak dla mnie.

Plus to co koledzy powiedzieli wyzej. wszystko masz w tym kontrolerze. dla mnie kontroler powinien byc prosty, a wszystko wepchnac w jakis service lub manager, bo teraz jak juz sie napocisz i napiszesz ta swoja aplikacje i zechce ci sie udostepnic API, zeby np. ktos mogl z tego korzystac, no i bedziesz rzezbil wszystko od nowa pod API. a tak jakbys mial wszystko schowane nizej, to API robisz w przyslowiowe 5 minut udostepniajac tylko dane z service w odpowiednim formacie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1