Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

47 febe allow remove destination #50

Merged
merged 4 commits into from
Nov 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions src/services/map/delivery_location_service.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import sys
from typing import Optional
from typing import List, Optional

from src.models.map import Intersection, Position, Segment
from src.models.tour import DeliveryLocation
Expand All @@ -15,14 +15,13 @@ def find_delivery_location_from_position(

# TODO: Find the point on the segment
closest_intersection = self.__find_closest_intersection(position)
segments = self.__get_intersection_segments(closest_intersection)

if len(segments) == 0:
raise Exception("No segments found for intersection")

return DeliveryLocation(
segment=Segment(
name="",
origin=closest_intersection,
destination=closest_intersection,
length=0,
),
segment=segments[0],
positionOnSegment=0,
)

Expand All @@ -46,3 +45,6 @@ def __find_closest_intersection(self, position: Position) -> Intersection:
found_distance = distance

return found

def __get_intersection_segments(self, intersection: Intersection) -> List[Segment]:
return list(MapService.instance().get_map().segments[intersection.id].values())
1 change: 1 addition & 0 deletions src/services/tour/tour_computing_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def compute_tours(
)
)
for tour_request in tour_requests
if tour_request.deliveries
]

# Replace this with the data from the Map model
Expand Down
42 changes: 33 additions & 9 deletions src/services/tour/tour_service.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from typing import List, Optional
from typing import List, Optional, Tuple

from reactivex import Observable
from reactivex import Observable, combine_latest
from reactivex.operators import map
from reactivex.subject import BehaviorSubject

Expand All @@ -19,24 +19,34 @@
class TourService(Singleton):
__tour_requests: BehaviorSubject[List[TourRequest]]
__computed_tours: BehaviorSubject[List[ComputedTour]]
__selected_delivery_request: BehaviorSubject[Optional[DeliveryRequest]]

def __init__(self) -> None:
self.__tour_requests = BehaviorSubject([])
self.__computed_tours = BehaviorSubject([])
self.__selected_delivery_request = BehaviorSubject(None)

@property
def tour_requests(self) -> Observable[List[TourRequest]]:
return self.__tour_requests

@property
def tour_requests_delivery_locations(self) -> Observable[List[DeliveryLocation]]:
return self.__tour_requests.pipe(
def tour_requests_delivery_locations(
self,
) -> Observable[Tuple[DeliveryLocation, List[DeliveryLocation]]]:
return combine_latest(
self.__selected_delivery_request,
self.__tour_requests,
).pipe(
map(
lambda tour_requests: [
delivery_request.location
for tour_request in tour_requests
for delivery_request in tour_request.deliveries
]
lambda x: (
x[0],
[
delivery_request.location
for tour_request in x[1]
for delivery_request in tour_request.deliveries
],
)
)
)

Expand Down Expand Up @@ -66,6 +76,11 @@ def get_tour_request_for_delivery_man(
def get_computed_tours(self) -> List[ComputedTour]:
return self.__computed_tours.value

def select_delivery_request(
self, delivery_request: Optional[DeliveryRequest]
) -> None:
self.__selected_delivery_request.on_next(delivery_request)

def add_delivery_request(
self, position: Position, delivery_man: DeliveryMan, timeWindow: int
) -> None:
Expand Down Expand Up @@ -118,6 +133,12 @@ def remove_delivery_request(

self.__tour_requests.on_next(self.__tour_requests.value)

if self.__selected_delivery_request.value == delivery_request:
self.__selected_delivery_request.on_next(None)

# TODO: review how to compute tours when adding a delivery request
self.compute_tours()

def clear_tour_requests(self) -> None:
self.__tour_requests.on_next({})

Expand All @@ -134,6 +155,9 @@ def compute_tours(self) -> None:
map=map,
)
for index, tour_intersection_ids in enumerate(tours_intersection_ids):
if not self.__tour_requests.value[index].deliveries:
continue

computed_tours.append(
ComputedTour(
deliveries=self.__tour_requests.value[index].deliveries,
Expand Down
76 changes: 55 additions & 21 deletions src/views/main_page/delivery_form_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
QTableWidget,
QTableWidgetItem,
QVBoxLayout,
QWidget,
)

from src.controllers.navigator.page import Page
from src.models.delivery_man.delivery_man import DeliveryMan
from src.models.tour import TourRequest
from src.models.tour import DeliveryRequest, TourRequest
from src.services.tour.tour_service import TourService
from src.views.ui import Button, Callout, Separator, Text, TextSize

Expand Down Expand Up @@ -60,8 +61,8 @@ def __init__(self):
def compute_tour(self):
TourService.instance().compute_tours()

def remove_address(self, row):
pass
def remove_delivery(self, delivery: DeliveryRequest, delivery_man: DeliveryMan):
TourService.instance().remove_delivery_request(delivery, delivery_man)

def __build_delivery_man_form(self) -> QLayout:
# Define components to be used in this screen
Expand Down Expand Up @@ -107,11 +108,12 @@ def __build_delivery_table(self) -> QLayout:
layout = QVBoxLayout()

table = QTableWidget()
table.setColumnCount(3)
table.setColumnCount(4)
table.setHorizontalHeaderLabels(
["Delivery Address", "Time Window", "Delivery Man"]
["Delivery Address", "Time Window", "Delivery Man", ""]
)
table.setEditTriggers(QTableWidget.EditTrigger.NoEditTriggers)
table.setSelectionMode(QTableWidget.SelectionMode.SingleSelection)

self.__delivery_table = table

Expand Down Expand Up @@ -175,19 +177,51 @@ def __update_time_window_combobox(self, delivery_man: DeliveryMan) -> None:
def __update_delivery_table(self, tours: List[TourRequest]) -> None:
self.__delivery_table.setRowCount(0)

for tour in tours:
for delivery in tour.deliveries:
row_position = self.__delivery_table.rowCount()

timeWindow = f"{delivery.timeWindow}:00 - {delivery.timeWindow + 1}:00"

self.__delivery_table.insertRow(row_position)
self.__delivery_table.setItem(
row_position, 0, QTableWidgetItem(delivery.location.segment.name)
)
self.__delivery_table.setItem(
row_position, 1, QTableWidgetItem(timeWindow)
)
self.__delivery_table.setItem(
row_position, 2, QTableWidgetItem(tour.delivery_man.name)
)
self.table_rows = [
(tour, delivery) for tour in tours for delivery in tour.deliveries
]

for tour, delivery in self.table_rows:
row_position = self.__delivery_table.rowCount()

timeWindow = f"{delivery.timeWindow}:00 - {delivery.timeWindow + 1}:00"

actions_widget = QWidget()
actions_layout = QHBoxLayout()
remove_btn = Button("Remove")

remove_btn.clicked.connect(
lambda: self.remove_delivery(delivery, tour.delivery_man)
)

actions_layout.setContentsMargins(2, 2, 2, 2)

actions_layout.addWidget(remove_btn)
actions_widget.setLayout(actions_layout)

self.__delivery_table.insertRow(row_position)

self.__delivery_table.setItem(
row_position, 0, QTableWidgetItem(delivery.location.segment.name)
)
self.__delivery_table.setItem(row_position, 1, QTableWidgetItem(timeWindow))
self.__delivery_table.setItem(
row_position, 2, QTableWidgetItem(tour.delivery_man.name)
)
self.__delivery_table.setCellWidget(
row_position,
3,
actions_widget,
)

def select_delivery_request(row_index: int) -> None:
TourService.instance().select_delivery_request(
self.table_rows[row_index][1].location
)

self.__delivery_table.itemSelectionChanged.connect(
lambda: select_delivery_request(self.__delivery_table.currentRow())
)

self.__delivery_table.clearSelection()
TourService.instance().select_delivery_request(None)
8 changes: 6 additions & 2 deletions src/views/main_page/map/map_view.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import List, Literal, Optional
from typing import List, Literal, Optional, Tuple

from PyQt6.QtCore import QPointF, QRectF, Qt
from PyQt6.QtGui import (
Expand Down Expand Up @@ -212,8 +212,11 @@ def mouseDoubleClickEvent(self, event: QMouseEvent | None) -> None:
)

def __on_update_delivery_locations(
self, delivery_locations: List[DeliveryLocation]
self,
deliveries: Tuple[Optional[DeliveryLocation], List[DeliveryLocation]],
):
selected_delivery_location, delivery_locations = deliveries

for marker in self.__map_annotations.markers.get(MarkersTypes.Delivery):
self.__scene.removeItem(marker.shape)

Expand All @@ -226,6 +229,7 @@ def __on_update_delivery_locations(
position=delivery_location.segment.origin,
icon="map-marker-alt",
color=QColor("#f54242"),
scale=1.5 if delivery_location == selected_delivery_location else 1,
),
)

Expand Down