Add printer-friendly view for "full" employee schedule
i.e. whatever version of that the user happens to be currently viewing
This commit is contained in:
		
							parent
							
								
									c9799f5943
								
							
						
					
					
						commit
						f97b26506f
					
				
					 7 changed files with 182 additions and 137 deletions
				
			
		|  | @ -1,6 +1,5 @@ | |||
| ## -*- coding: utf-8 -*- | ||||
| <%inherit file="/base.mako" /> | ||||
| <%namespace file="/autocomplete.mako" import="autocomplete" /> | ||||
| 
 | ||||
| <%def name="title()">${page_title}</%def> | ||||
| 
 | ||||
|  | @ -85,139 +84,6 @@ | |||
| 
 | ||||
| <%def name="context_menu()"></%def> | ||||
| 
 | ||||
| <%def name="timesheet(edit_form=None, edit_tools=None)"> | ||||
|     <style type="text/css"> | ||||
|       .timesheet thead th { | ||||
|            width: ${'{:0.2f}'.format(100.0 / 9)}%; | ||||
|       } | ||||
|     </style> | ||||
| 
 | ||||
|     <div class="timesheet-wrapper"> | ||||
| 
 | ||||
|       ${form.begin(id='filter-form')} | ||||
| 
 | ||||
|       <table class="timesheet-header"> | ||||
|         <tbody> | ||||
|           <tr> | ||||
| 
 | ||||
|             <td class="filters" rowspan="2"> | ||||
| 
 | ||||
|               % if employee is not UNDEFINED: | ||||
|                   <div class="field-wrapper employee"> | ||||
|                     <label>Employee</label> | ||||
|                     <div class="field"> | ||||
|                       % if request.has_perm('{}.viewall'.format(permission_prefix)): | ||||
|                           ${autocomplete('employee', url('employees.autocomplete'), | ||||
|                                          field_value=employee.uuid if employee else None, | ||||
|                                          field_display=unicode(employee or ''), | ||||
|                                          selected='employee_selected')} | ||||
|                       % else: | ||||
|                           ${form.hidden('employee', value=employee.uuid)} | ||||
|                           ${employee} | ||||
|                       % endif | ||||
|                     </div> | ||||
|                   </div> | ||||
|               % endif | ||||
| 
 | ||||
|               % if store_options is not UNDEFINED: | ||||
|                   ${form.field_div('store', h.select('store', store.uuid if store else None, store_options))} | ||||
|               % endif | ||||
| 
 | ||||
|               % if department_options is not UNDEFINED: | ||||
|                   ${form.field_div('department', h.select('department', department.uuid if department else None,  department_options))} | ||||
|               % endif | ||||
| 
 | ||||
|               <div class="field-wrapper week"> | ||||
|                 <label>Week of</label> | ||||
|                 <div class="field"> | ||||
|                   ${week_of} | ||||
|                 </div> | ||||
|               </div> | ||||
| 
 | ||||
|               % if edit_tools: | ||||
|                   ${edit_tools()} | ||||
|               % endif | ||||
| 
 | ||||
|             </td><!-- filters --> | ||||
| 
 | ||||
|             <td class="menu"> | ||||
|               <ul id="context-menu"> | ||||
|                 ${self.context_menu()} | ||||
|               </ul> | ||||
|             </td><!-- menu --> | ||||
|           </tr> | ||||
| 
 | ||||
|           <tr> | ||||
|             <td class="tools"> | ||||
|               <div class="grid-tools"> | ||||
|                 <div class="week-picker"> | ||||
|                   <button type="button" class="nav" data-date="${prev_sunday.strftime('%m/%d/%Y')}">« Previous</button> | ||||
|                   <button type="button" class="nav" data-date="${next_sunday.strftime('%m/%d/%Y')}">Next »</button> | ||||
|                   <label>Jump to week:</label> | ||||
|                   ${form.text('date', value=sunday.strftime('%m/%d/%Y'))} | ||||
|                 </div> | ||||
|               </div><!-- grid-tools --> | ||||
|             </td><!-- tools --> | ||||
|           </tr> | ||||
| 
 | ||||
|         </tbody> | ||||
|       </table><!-- timesheet-header --> | ||||
| 
 | ||||
|       ${form.end()} | ||||
| 
 | ||||
|       % if edit_form: | ||||
|           ${edit_form()} | ||||
|       % endif | ||||
| 
 | ||||
|       <table class="timesheet"> | ||||
|         <thead> | ||||
|           <tr> | ||||
|             <th>Employee</th> | ||||
|             % for day in weekdays: | ||||
|                 <th>${day.strftime('%A')}<br />${day.strftime('%b %d')}</th> | ||||
|             % endfor | ||||
|             <th>Total<br />Hours</th> | ||||
|           </tr> | ||||
|         </thead> | ||||
|         <tbody> | ||||
|           % for emp in sorted(employees, key=unicode): | ||||
|               <tr data-employee-uuid="${emp.uuid}"> | ||||
|                 <td class="employee">${emp}</td> | ||||
|                 % for day in emp.weekdays: | ||||
|                     <td class="day"> | ||||
|                       ${self.render_day(day)} | ||||
|                     </td> | ||||
|                 % endfor | ||||
|                 <td class="total">${emp.hours_display}</td> | ||||
|               </tr> | ||||
|           % endfor | ||||
|           % if employee is UNDEFINED: | ||||
|               <tr class="total"> | ||||
|                 <td class="employee">${len(employees)} employees</td> | ||||
|                 % for day in weekdays: | ||||
|                     <td></td> | ||||
|                 % endfor | ||||
|                 <td></td> | ||||
|               </tr> | ||||
|           % else: | ||||
|               <tr> | ||||
|                 <td> </td> | ||||
|                 % for day in employee.weekdays: | ||||
|                     <td>${day['hours_display']}</td> | ||||
|                 % endfor | ||||
|                 <td>${employee.hours_display}</td> | ||||
|               </tr> | ||||
|           % endif | ||||
|         </tbody> | ||||
|       </table> | ||||
| 
 | ||||
|       % if edit_form: | ||||
|           ${h.end_form()} | ||||
|       % endif | ||||
| 
 | ||||
|     </div><!-- timesheet-wrapper --> | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="render_day(day)"> | ||||
|   % for shift in day['shifts']: | ||||
|       <p class="shift">${render_shift(shift)}</p> | ||||
|  |  | |||
							
								
								
									
										143
									
								
								tailbone/templates/shifts/lib.mako
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										143
									
								
								tailbone/templates/shifts/lib.mako
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,143 @@ | |||
| ## -*- coding: utf-8 -*- | ||||
| <%namespace file="/autocomplete.mako" import="autocomplete" /> | ||||
| 
 | ||||
| <%def name="timesheet_wrapper(edit_form=None, edit_tools=None, context_menu=None, render_day=None)"> | ||||
|     <div class="timesheet-wrapper"> | ||||
| 
 | ||||
|       ${form.begin(id='filter-form')} | ||||
| 
 | ||||
|       <table class="timesheet-header"> | ||||
|         <tbody> | ||||
|           <tr> | ||||
| 
 | ||||
|             <td class="filters" rowspan="2"> | ||||
| 
 | ||||
|               % if employee is not UNDEFINED: | ||||
|                   <div class="field-wrapper employee"> | ||||
|                     <label>Employee</label> | ||||
|                     <div class="field"> | ||||
|                       % if request.has_perm('{}.viewall'.format(permission_prefix)): | ||||
|                           ${autocomplete('employee', url('employees.autocomplete'), | ||||
|                                          field_value=employee.uuid if employee else None, | ||||
|                                          field_display=unicode(employee or ''), | ||||
|                                          selected='employee_selected')} | ||||
|                       % else: | ||||
|                           ${form.hidden('employee', value=employee.uuid)} | ||||
|                           ${employee} | ||||
|                       % endif | ||||
|                     </div> | ||||
|                   </div> | ||||
|               % endif | ||||
| 
 | ||||
|               % if store_options is not UNDEFINED: | ||||
|                   ${form.field_div('store', h.select('store', store.uuid if store else None, store_options))} | ||||
|               % endif | ||||
| 
 | ||||
|               % if department_options is not UNDEFINED: | ||||
|                   ${form.field_div('department', h.select('department', department.uuid if department else None,  department_options))} | ||||
|               % endif | ||||
| 
 | ||||
|               <div class="field-wrapper week"> | ||||
|                 <label>Week of</label> | ||||
|                 <div class="field"> | ||||
|                   ${week_of} | ||||
|                 </div> | ||||
|               </div> | ||||
| 
 | ||||
|               % if edit_tools: | ||||
|                   ${edit_tools()} | ||||
|               % endif | ||||
| 
 | ||||
|             </td><!-- filters --> | ||||
| 
 | ||||
|             <td class="menu"> | ||||
|               <ul id="context-menu"> | ||||
|                 % if context_menu: | ||||
|                     ${context_menu()} | ||||
|                 % endif | ||||
|               </ul> | ||||
|             </td><!-- menu --> | ||||
|           </tr> | ||||
| 
 | ||||
|           <tr> | ||||
|             <td class="tools"> | ||||
|               <div class="grid-tools"> | ||||
|                 <div class="week-picker"> | ||||
|                   <button type="button" class="nav" data-date="${prev_sunday.strftime('%m/%d/%Y')}">« Previous</button> | ||||
|                   <button type="button" class="nav" data-date="${next_sunday.strftime('%m/%d/%Y')}">Next »</button> | ||||
|                   <label>Jump to week:</label> | ||||
|                   ${form.text('date', value=sunday.strftime('%m/%d/%Y'))} | ||||
|                 </div> | ||||
|               </div><!-- grid-tools --> | ||||
|             </td><!-- tools --> | ||||
|           </tr> | ||||
| 
 | ||||
|         </tbody> | ||||
|       </table><!-- timesheet-header --> | ||||
| 
 | ||||
|       ${form.end()} | ||||
| 
 | ||||
|       % if edit_form: | ||||
|           ${edit_form()} | ||||
|       % endif | ||||
| 
 | ||||
|       ${timesheet(render_day=render_day)} | ||||
| 
 | ||||
|       % if edit_form: | ||||
|           ${h.end_form()} | ||||
|       % endif | ||||
| 
 | ||||
|     </div><!-- timesheet-wrapper --> | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="timesheet(render_day=None)"> | ||||
|   <style type="text/css"> | ||||
|     .timesheet thead th { | ||||
|          width: ${'{:0.2f}'.format(100.0 / 9)}%; | ||||
|     } | ||||
|   </style> | ||||
| 
 | ||||
|   <table class="timesheet"> | ||||
|     <thead> | ||||
|       <tr> | ||||
|         <th>Employee</th> | ||||
|         % for day in weekdays: | ||||
|             <th>${day.strftime('%A')}<br />${day.strftime('%b %d')}</th> | ||||
|         % endfor | ||||
|         <th>Total<br />Hours</th> | ||||
|       </tr> | ||||
|     </thead> | ||||
|     <tbody> | ||||
|       % for emp in sorted(employees, key=unicode): | ||||
|           <tr data-employee-uuid="${emp.uuid}"> | ||||
|             <td class="employee">${emp}</td> | ||||
|             % for day in emp.weekdays: | ||||
|                 <td class="day"> | ||||
|                   % if render_day: | ||||
|                       ${render_day(day)} | ||||
|                   % endif | ||||
|                 </td> | ||||
|             % endfor | ||||
|             <td class="total">${emp.hours_display}</td> | ||||
|           </tr> | ||||
|       % endfor | ||||
|       % if employee is UNDEFINED: | ||||
|           <tr class="total"> | ||||
|             <td class="employee">${len(employees)} employees</td> | ||||
|             % for day in weekdays: | ||||
|                 <td></td> | ||||
|             % endfor | ||||
|             <td></td> | ||||
|           </tr> | ||||
|       % else: | ||||
|           <tr> | ||||
|             <td> </td> | ||||
|             % for day in employee.weekdays: | ||||
|                 <td>${day['hours_display']}</td> | ||||
|             % endfor | ||||
|             <td>${employee.hours_display}</td> | ||||
|           </tr> | ||||
|       % endif | ||||
|     </tbody> | ||||
|   </table> | ||||
| </%def> | ||||
|  | @ -1,13 +1,17 @@ | |||
| ## -*- coding: utf-8 -*- | ||||
| <%inherit file="/shifts/base.mako" /> | ||||
| <%namespace file="/shifts/lib.mako" import="timesheet_wrapper" /> | ||||
| 
 | ||||
| <%def name="context_menu()"> | ||||
|   % if request.has_perm('schedule.edit'): | ||||
|       <li>${h.link_to("Edit Schedule", url('schedule.edit'))}</li> | ||||
|   % endif | ||||
|   % if request.has_perm('schedule.print'): | ||||
|       <li>${h.link_to("Print Schedule", url('schedule.print'), target='_blank')}</li> | ||||
|   % endif | ||||
|   % if request.has_perm('timesheet.view'): | ||||
|       <li>${h.link_to("View this Time Sheet", url('schedule.goto.timesheet'), class_='goto')}</li> | ||||
|   % endif | ||||
| </%def> | ||||
| 
 | ||||
| ${self.timesheet()} | ||||
| ${timesheet_wrapper(context_menu=context_menu, render_day=self.render_day)} | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| ## -*- coding: utf-8 -*- | ||||
| <%inherit file="/shifts/base.mako" /> | ||||
| <%namespace file="/shifts/lib.mako" import="timesheet_wrapper" /> | ||||
| 
 | ||||
| <%def name="head_tags()"> | ||||
|   ${parent.head_tags()} | ||||
|  | @ -267,6 +268,9 @@ | |||
|   % if request.has_perm('schedule.viewall'): | ||||
|       <li>${h.link_to("View Schedule", url('schedule'))}</li> | ||||
|   % endif | ||||
|   % if request.has_perm('schedule.print'): | ||||
|       <li>${h.link_to("Print Schedule", url('schedule.print'), target='_blank')}</li> | ||||
|   % endif | ||||
| </%def> | ||||
| 
 | ||||
| <%def name="render_day(day)"> | ||||
|  | @ -290,7 +294,7 @@ | |||
|   </div> | ||||
| </%def> | ||||
| 
 | ||||
| ${self.timesheet(edit_form=edit_form, edit_tools=edit_tools)} | ||||
| ${timesheet_wrapper(edit_form=edit_form, edit_tools=edit_tools, context_menu=context_menu, render_day=render_day)} | ||||
| 
 | ||||
| ${edit_tools()} | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										20
									
								
								tailbone/templates/shifts/schedule_print.mako
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								tailbone/templates/shifts/schedule_print.mako
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,20 @@ | |||
| ## -*- coding: utf-8 -*- | ||||
| <%namespace file="/shifts/lib.mako" import="timesheet" /> | ||||
| <%namespace file="/shifts/base.mako" import="render_day" /> | ||||
| <html> | ||||
|   <head> | ||||
|     ## TODO: this seems a little hacky..? | ||||
|     ${h.stylesheet_link(request.static_url('tailbone:static/css/normalize.css'))} | ||||
|     ${h.stylesheet_link(request.static_url('tailbone:static/css/base.css'))} | ||||
|     ${h.stylesheet_link(request.static_url('tailbone:static/css/newgrids.css'))} | ||||
|     ${h.stylesheet_link(request.static_url('tailbone:static/css/timesheet.css'))} | ||||
|   </head> | ||||
|   <body> | ||||
|     <h1> | ||||
|       ${store if store else "(all stores)"} - | ||||
|       ${department if department else "(all departments)"} - | ||||
|       ${week_of} | ||||
|     </h1> | ||||
|     ${timesheet(render_day=render_day)} | ||||
|   </body> | ||||
| </html> | ||||
|  | @ -1,5 +1,6 @@ | |||
| ## -*- coding: utf-8 -*- | ||||
| <%inherit file="/shifts/base.mako" /> | ||||
| <%namespace file="/shifts/lib.mako" import="timesheet_wrapper" /> | ||||
| 
 | ||||
| <%def name="context_menu()"> | ||||
|     % if request.has_perm('schedule.view'): | ||||
|  | @ -7,4 +8,4 @@ | |||
|     % endif | ||||
| </%def> | ||||
| 
 | ||||
| ${self.timesheet()} | ||||
| ${timesheet_wrapper(context_menu=context_menu, render_day=self.render_day)} | ||||
|  |  | |||
|  | @ -184,6 +184,13 @@ class ScheduleView(TimeSheetView): | |||
|                         permission='schedule.edit') | ||||
|         config.add_tailbone_permission('schedule', 'schedule.edit', "Edit full schedule") | ||||
| 
 | ||||
|         # print schedule | ||||
|         config.add_route('schedule.print', '/schedule/print') | ||||
|         config.add_view(cls, attr='full', route_name='schedule.print', | ||||
|                         renderer='/shifts/schedule_print.mako', | ||||
|                         permission='schedule.print') | ||||
|         config.add_tailbone_permission('schedule', 'schedule.print', "Print schedule") | ||||
| 
 | ||||
| 
 | ||||
| def includeme(config): | ||||
|     ScheduleView.defaults(config) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Lance Edgar
						Lance Edgar