diff --git a/InvenTree/order/api.py b/InvenTree/order/api.py index 8b949b50d1..0f1b05db4b 100644 --- a/InvenTree/order/api.py +++ b/InvenTree/order/api.py @@ -1449,6 +1449,8 @@ class OrderCalendarExport(ICalFeed): ordertype_title = _('Purchase Order') elif obj["ordertype"] == 'sales-order': ordertype_title = _('Sales Order') + elif obj["ordertype"] == 'return-order': + ordertype_title = _('Return Order') else: ordertype_title = _('Unknown') @@ -1459,7 +1461,7 @@ class OrderCalendarExport(ICalFeed): return f'//{self.instance_url}//{self.title(obj)}//EN' def items(self, obj): - """Return a list of PurchaseOrders. + """Return a list of Orders. Filters: - Only return those which have a target_date set @@ -1472,23 +1474,32 @@ class OrderCalendarExport(ICalFeed): outlist = models.PurchaseOrder.objects.filter(target_date__isnull=False).filter(status__lt=PurchaseOrderStatus.COMPLETE) else: outlist = models.PurchaseOrder.objects.filter(target_date__isnull=False) - else: + elif obj["ordertype"] == 'sales-order': if obj['include_completed'] is False: # Do not include completed (=shipped) orders from list in this case # Shipped status = 20 outlist = models.SalesOrder.objects.filter(target_date__isnull=False).filter(status__lt=SalesOrderStatus.SHIPPED) else: outlist = models.SalesOrder.objects.filter(target_date__isnull=False) + elif obj["ordertype"] == 'return-order': + if obj['include_completed'] is False: + # Do not include completed orders from list in this case + # Complete status = 30 + outlist = models.ReturnOrder.objects.filter(target_date__isnull=False).filter(status__lt=ReturnOrderStatus.COMPLETE) + else: + outlist = models.ReturnOrder.objects.filter(target_date__isnull=False) + else: + outlist = [] return outlist def item_title(self, item): - """Set the event title to the purchase order reference""" - return item.reference + """Set the event title to the order reference""" + return f"{item.reference}" def item_description(self, item): """Set the event description""" - return item.description + return f"Company: {item.company.name}\nStatus: {item.get_status_display()}\nDescription: {item.description}" def item_start_datetime(self, item): """Set event start to target date. Goal is all-day event.""" @@ -1664,6 +1675,6 @@ order_api_urls = [ path('', ReturnOrderExtraLineList.as_view(), name='api-return-order-extra-line-list'), ])), - # API endpoint for subscribing to ICS calendar of purchase/sales orders - re_path(r'^calendar/(?Ppurchase-order|sales-order)/calendar.ics', OrderCalendarExport(), name='api-po-so-calendar'), + # API endpoint for subscribing to ICS calendar of purchase/sales/return orders + re_path(r'^calendar/(?Ppurchase-order|sales-order|return-order)/calendar.ics', OrderCalendarExport(), name='api-po-so-calendar'), ] diff --git a/InvenTree/order/test_api.py b/InvenTree/order/test_api.py index 1e0f5f6a2b..5908283d4b 100644 --- a/InvenTree/order/test_api.py +++ b/InvenTree/order/test_api.py @@ -2200,3 +2200,15 @@ class ReturnOrderTests(InvenTreeAPITestCase): self.assertEqual(deltas['customer'], customer.pk) self.assertEqual(deltas['location'], 1) self.assertEqual(deltas['returnorder'], rma.pk) + + def test_ro_calendar(self): + """Test the calendar export endpoint""" + + # Full test is in test_po_calendar. Since these use the same backend, test only + # that the endpoint is available + url = reverse('api-po-so-calendar', kwargs={'ordertype': 'return-order'}) + + # Test without completed orders + response = self.get(url, expected_code=200, format=None) + calendar = Calendar.from_ical(response.content) + self.assertIsInstance(calendar, Calendar) diff --git a/docs/docs/order/return_order.md b/docs/docs/order/return_order.md index de16d651ef..0c2f8f326c 100644 --- a/docs/docs/order/return_order.md +++ b/docs/docs/order/return_order.md @@ -99,3 +99,12 @@ While [line items](#line-items) must reference a particular stock item, extra li ## Return Order Reports Custom [reports](../report/return_order.md) can be generated against each Return Order. + +### Calendar view + +Using the button to the top right of the list of Return Orders, the view can be switched to a calendar view using the button . This view shows orders with a defined target date only. + +This view can be accessed externally as an ICS calendar using a URL like the following: +`http://inventree.example.org/api/order/calendar/return-order/calendar.ics` + +by default, completed orders are not exported. These can be included by appending `?include_completed=True` to the URL.