1+ import traceback
2+
13from django .conf import settings
24from django .contrib .contenttypes .models import ContentType
35from django .utils .translation import gettext_lazy as _
46from netbox .plugins import PluginTemplateExtension
57from netbox .ui import panels , actions
68
7- from .models import hardware
8- from .ui import HardwareLifecyclePanel , HardwareLifecycleDatesPanel
9+ from netbox_lifecycle import constants
10+ from netbox_lifecycle .models import hardware
11+ from netbox_lifecycle .ui import HardwareLifecyclePanel , HardwareLifecycleDatesPanel
12+ from netbox_lifecycle .ui .panels .tabbed import TabbedTablePanel
913
1014PLUGIN_SETTINGS = settings .PLUGINS_CONFIG .get ('netbox_lifecycle' , {})
1115
@@ -58,8 +62,7 @@ def right_page(self):
5862 if hasattr (self , '_render_lifecycle_info' ):
5963 result += self ._render_lifecycle_info ('right_page' )
6064 if hasattr (self , '_render_contract_card' ):
61- result += self ._render_contract_card ('right_page' , expired = False )
62- result += self ._render_contract_card ('right_page' , expired = True )
65+ result += self ._render_contract_card ('right_page' )
6366 if hasattr (self , '_render_license_card' ):
6467 result += self ._render_license_card ('right_page' )
6568 return result
@@ -69,8 +72,7 @@ def left_page(self):
6972 if hasattr (self , '_render_lifecycle_info' ):
7073 result += self ._render_lifecycle_info ('left_page' )
7174 if hasattr (self , '_render_contract_card' ):
72- result += self ._render_contract_card ('left_page' , expired = False )
73- result += self ._render_contract_card ('left_page' , expired = True )
75+ result += self ._render_contract_card ('left_page' )
7476 if hasattr (self , '_render_license_card' ):
7577 result += self ._render_license_card ('left_page' )
7678 return result
@@ -80,8 +82,7 @@ def full_width_page(self):
8082 if hasattr (self , '_render_lifecycle_info' ):
8183 result += self ._render_lifecycle_info ('full_width_page' )
8284 if hasattr (self , '_render_contract_card' ):
83- result += self ._render_contract_card ('full_width_page' , expired = False )
84- result += self ._render_contract_card ('full_width_page' , expired = True )
85+ result += self ._render_contract_card ('full_width_page' )
8586 if hasattr (self , '_render_license_card' ):
8687 result += self ._render_license_card ('full_width_page' )
8788 return result
@@ -122,56 +123,87 @@ class ContractMixin:
122123 def get_contract_card_position (self ):
123124 return PLUGIN_SETTINGS .get ('contract_card_position' , 'right_page' )
124125
125- def _render_contract_card (self , location = None , expired = None ):
126+ def _render_contract_card (self , location = None ):
126127 if self .get_contract_card_position () != location :
127128 return ''
128129
129130 title = _ ('Contracts' )
130- filter = {}
131- action = []
132- if expired is True or expired is False :
133- filter = {'expired' : expired }
134- title = _ ('Expired Contracts' ) if expired else _ ('Active Contracts' )
135-
136- if not expired :
137- action = [
138- actions .AddObject (
139- 'netbox_lifecycle.SupportContractAssignment' ,
140- url_params = {
141- self .model_name : lambda ctx : ctx ['object' ].pk ,
142- },
143- ),
144- ]
131+ action = [
132+ actions .AddObject (
133+ 'netbox_lifecycle.SupportContractAssignment' ,
134+ url_params = {
135+ self .model_name : lambda ctx : ctx ['object' ].pk ,
136+ },
137+ ),
138+ ]
145139
140+ include_columns = [
141+ 'contract' ,
142+ 'sku' ,
143+ ]
144+ exclude_columns = [
145+ 'device_name' ,
146+ 'module_name' ,
147+ 'virtual_machine_name' ,
148+ 'license_name' ,
149+ 'device_model' ,
150+ 'device_serial' ,
151+ 'module_serial' ,
152+ 'device_status' ,
153+ 'virtual_machine_status' ,
154+ 'quantity' ,
155+ 'renewal' ,
156+ 'end' ,
157+ 'description' ,
158+ 'comments' ,
159+ 'actions' ,
160+ ]
161+ filter = {
162+ self .field_name : lambda ctx : ctx ['object' ].pk ,
163+ }
146164 context = self .get_context (self .context )
147- panel = panels .ObjectsTablePanel (
148- title = title ,
149- model = 'netbox_lifecycle.supportcontractassignment' ,
150- filters = {self .field_name : lambda ctx : ctx ['object' ].pk , ** filter },
151- include_columns = [
152- 'contract' ,
153- 'sku' ,
154- ],
155- exclude_columns = [
156- 'device_name' ,
157- 'module_name' ,
158- 'virtual_machine_name' ,
159- 'license_name' ,
160- 'device_model' ,
161- 'device_serial' ,
162- 'module_serial' ,
163- 'device_status' ,
164- 'virtual_machine_status' ,
165- 'quantity' ,
166- 'renewal' ,
167- 'end' ,
168- 'description' ,
169- 'comments' ,
170- 'actions' ,
171- ],
172- actions = action ,
173- )
174- return panel .render (context = context )
165+ try :
166+ panel = TabbedTablePanel (
167+ title = title ,
168+ tabs = {
169+ 'active' : panels .ObjectsTablePanel (
170+ title = _ ('Active' ),
171+ model = 'netbox_lifecycle.supportcontractassignment' ,
172+ filters = {** filter , 'status' : constants .CONTRACT_STATUS_ACTIVE },
173+ include_columns = include_columns ,
174+ exclude_columns = exclude_columns ,
175+ ),
176+ 'expired' : panels .ObjectsTablePanel (
177+ title = _ ('Expired' ),
178+ model = 'netbox_lifecycle.supportcontractassignment' ,
179+ filters = {** filter , 'status' : constants .CONTRACT_STATUS_EXPIRED },
180+ include_columns = include_columns ,
181+ exclude_columns = exclude_columns ,
182+ ),
183+ 'future' : panels .ObjectsTablePanel (
184+ title = _ ('Future' ),
185+ model = 'netbox_lifecycle.supportcontractassignment' ,
186+ filters = {** filter , 'status' : constants .CONTRACT_STATUS_FUTURE },
187+ include_columns = include_columns ,
188+ exclude_columns = exclude_columns ,
189+ ),
190+ 'unspecified' : panels .ObjectsTablePanel (
191+ title = _ ('Unspecified' ),
192+ model = 'netbox_lifecycle.supportcontractassignment' ,
193+ filters = {
194+ ** filter ,
195+ 'status' : constants .CONTRACT_STATUS_UNSPECIFIED ,
196+ },
197+ include_columns = include_columns ,
198+ exclude_columns = exclude_columns ,
199+ ),
200+ },
201+ actions = action ,
202+ )
203+ return panel .render (context = context )
204+ except Exception as e :
205+ traceback .print_exception (type (e ), e , e .__traceback__ )
206+ # traceback.print_exception(e)
175207
176208
177209class LicenseMixin :
@@ -198,7 +230,8 @@ def _render_license_card(self, location=None, exclude=None, include=None):
198230 model = 'netbox_lifecycle.licenseassignment' ,
199231 filters = {self .field_name : lambda ctx : ctx ['object' ].pk },
200232 include_columns = [
201- 'vendor' , 'license' ,
233+ 'vendor' ,
234+ 'license' ,
202235 'quantity' ,
203236 ],
204237 exclude_columns = [
@@ -235,7 +268,9 @@ class ModuleTypeLifecycleContent(LifecycleMixin, BaseMixin, PluginTemplateExtens
235268 models = ['dcim.moduletype' ]
236269
237270
238- class VirtualMachineContractContent (ContractMixin , LicenseMixin , BaseMixin , PluginTemplateExtension ):
271+ class VirtualMachineContractContent (
272+ ContractMixin , LicenseMixin , BaseMixin , PluginTemplateExtension
273+ ):
239274 """Template extension for VirtualMachine detail pages showing contracts and licenses."""
240275
241276 models = ['virtualization.virtualmachine' ]
0 commit comments