|
|
@ -1,10 +1,13 @@ |
|
|
|
import deform |
|
|
|
import deform |
|
|
|
|
|
|
|
import io |
|
|
|
|
|
|
|
import xlsxwriter |
|
|
|
|
|
|
|
|
|
|
|
from datetime import datetime |
|
|
|
from datetime import datetime |
|
|
|
from collections import OrderedDict |
|
|
|
from collections import OrderedDict |
|
|
|
|
|
|
|
|
|
|
|
from pyramid.httpexceptions import HTTPFound |
|
|
|
from pyramid.httpexceptions import HTTPFound |
|
|
|
from pyramid.renderers import render |
|
|
|
from pyramid.renderers import render |
|
|
|
|
|
|
|
from pyramid.response import FileIter |
|
|
|
from pyramid.view import view_config |
|
|
|
from pyramid.view import view_config |
|
|
|
|
|
|
|
|
|
|
|
from ordr2.events import OrderStatusChange |
|
|
|
from ordr2.events import OrderStatusChange |
|
|
@ -58,6 +61,86 @@ def change_column_view(context, request): |
|
|
|
return HTTPFound(context.url()) |
|
|
|
return HTTPFound(context.url()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@view_config( |
|
|
|
|
|
|
|
context='ordr2:resources.OrderList', |
|
|
|
|
|
|
|
name='actions', |
|
|
|
|
|
|
|
request_param='action=export', |
|
|
|
|
|
|
|
permission='view', |
|
|
|
|
|
|
|
request_method='POST', |
|
|
|
|
|
|
|
renderer='ordr2:templates/orders/edit_multiple_stati.jinja2' |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
def download_view(context, request): |
|
|
|
|
|
|
|
''' see https://xlsxwriter.readthedocs.io/example_http_server3.html ''' |
|
|
|
|
|
|
|
# Create an in-memory output file for the new workbook. |
|
|
|
|
|
|
|
output = io.BytesIO() |
|
|
|
|
|
|
|
# Even though the final file will be in memory the module uses temp |
|
|
|
|
|
|
|
# files during assembly for efficiency. To avoid this on servers that |
|
|
|
|
|
|
|
# don't allow temp files, for example the Google APP Engine, set the |
|
|
|
|
|
|
|
# 'in_memory' constructor option to True: |
|
|
|
|
|
|
|
workbook = xlsxwriter.Workbook(output, {'in_memory': True}) |
|
|
|
|
|
|
|
worksheet = workbook.add_worksheet() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# formatting |
|
|
|
|
|
|
|
bold = workbook.add_format({'bold': 1}) |
|
|
|
|
|
|
|
# Add a number format for cells with money. |
|
|
|
|
|
|
|
money_format = workbook.add_format({'num_format': '0.00'}) |
|
|
|
|
|
|
|
# Add an Excel date format. |
|
|
|
|
|
|
|
date_format = workbook.add_format({'num_format': 'yy-mm-dd hh:mm'}) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Write the column headers |
|
|
|
|
|
|
|
headers = [ |
|
|
|
|
|
|
|
'Placed On', 'CAS / Description', 'Vendor', 'Catalog Nr', |
|
|
|
|
|
|
|
'Package Size', 'Unit Price', 'Quantity', 'Total Price', 'Currency', |
|
|
|
|
|
|
|
'Account', 'Status', 'Category', 'Placed By' |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
for col, header in enumerate(headers): |
|
|
|
|
|
|
|
worksheet.write(0, col, header, bold) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for row, resource in enumerate(context.items()): |
|
|
|
|
|
|
|
order = resource.model |
|
|
|
|
|
|
|
worksheet.write(row + 1, 0, order.created_date, date_format) |
|
|
|
|
|
|
|
worksheet.write_string(row + 1, 1, order.cas_description) |
|
|
|
|
|
|
|
worksheet.write_string(row + 1, 2, order.vendor) |
|
|
|
|
|
|
|
worksheet.write_string(row + 1, 3, order.catalog_nr) |
|
|
|
|
|
|
|
worksheet.write_string(row + 1, 4, order.package_size) |
|
|
|
|
|
|
|
worksheet.write(row + 1, 5, order.unit_price, money_format) |
|
|
|
|
|
|
|
worksheet.write(row + 1, 6, order.amount) |
|
|
|
|
|
|
|
worksheet.write(row + 1, 7, order.total_price, money_format) |
|
|
|
|
|
|
|
worksheet.write_string(row + 1, 8, order.currency) |
|
|
|
|
|
|
|
worksheet.write_string(row + 1, 9, order.account) |
|
|
|
|
|
|
|
worksheet.write_string(row + 1, 10, order.status.value.capitalize()) |
|
|
|
|
|
|
|
worksheet.write_string(row + 1, 11, order.category.value.capitalize()) |
|
|
|
|
|
|
|
worksheet.write_string(row + 1, 12, order.created_by) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Close the workbook before streaming the data. |
|
|
|
|
|
|
|
workbook.close() |
|
|
|
|
|
|
|
# Rewind the buffer. |
|
|
|
|
|
|
|
output.seek(0) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
response = request.response |
|
|
|
|
|
|
|
response.app_iter = FileIter(output) |
|
|
|
|
|
|
|
headers = response.headers |
|
|
|
|
|
|
|
headers['Content-Type'] = 'application/download' |
|
|
|
|
|
|
|
headers['Accept-Ranges'] = 'bite' |
|
|
|
|
|
|
|
headers['Content-Disposition'] = 'attachment;filename=order-list.xlsx' |
|
|
|
|
|
|
|
return response |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@view_config( |
|
|
|
|
|
|
|
context='ordr2:resources.OrderList', |
|
|
|
|
|
|
|
name='actions', |
|
|
|
|
|
|
|
request_param='action=search', |
|
|
|
|
|
|
|
permission='view', |
|
|
|
|
|
|
|
request_method='POST' |
|
|
|
|
|
|
|
) |
|
|
|
|
|
|
|
def search(context, request): |
|
|
|
|
|
|
|
term = request.POST.get('search', '') |
|
|
|
|
|
|
|
term = term.strip() |
|
|
|
|
|
|
|
if term: |
|
|
|
|
|
|
|
return HTTPFound(context.url(search=term, user=None, status=None, p=1)) |
|
|
|
|
|
|
|
return HTTPFound(context.url()) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@view_config( |
|
|
|
@view_config( |
|
|
|
context='ordr2:resources.OrderList', |
|
|
|
context='ordr2:resources.OrderList', |
|
|
|
name='actions', |
|
|
|
name='actions', |
|
|
|