[IMP] clean sitemap, enumerate pages + fixes
[odoo/odoo.git] / addons / website_quote / controllers / main.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2013-Today OpenERP SA (<http://www.openerp.com>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 from openerp import SUPERUSER_ID
23 from openerp.addons.web import http
24 from openerp.addons.web.http import request
25 import werkzeug
26 import datetime
27 import time
28
29 from openerp.tools.translate import _
30
31 class sale_quote(http.Controller):
32     @http.route([
33         "/quote/<int:order_id>",
34         "/quote/<int:order_id>/<token>"
35     ], type='http', auth="public", website=True)
36     def view(self, order_id, token=None, message=False, **post):
37         # use SUPERUSER_ID allow to access/view order for public user
38         # only if he knows the private token
39         order = request.registry.get('sale.order').browse(request.cr, token and SUPERUSER_ID or request.uid, order_id)
40         now = time.strftime('%Y-%m-%d')
41         if token:
42             if token != order.access_token:
43                 return request.website.render('website.404')
44             # Log only once a day
45             if request.session.get('view_quote',False)!=now:
46                 request.session['view_quote'] = now
47                 body=_('Quotation viewed by customer')
48                 self.__message_post(body, order_id, type='comment')
49         days = 0
50         if order.validity_date:
51             days = (datetime.datetime.strptime(order.validity_date, '%Y-%m-%d') - datetime.datetime.now()).days + 1
52         values = {
53             'quotation': order,
54             'message': message and int(message) or False,
55             'option': bool(filter(lambda x: not x.line_id, order.options)),
56             'order_valid': (not order.validity_date) or (now <= order.validity_date),
57             'days_valid': max(days, 0)
58         }
59         return request.website.render('website_quote.so_quotation', values)
60
61     @http.route(['/quote/accept'], type='json', auth="public", website=True)
62     def accept(self, order_id, token=None, signer=None, sign=None, **post):
63         order_obj = request.registry.get('sale.order')
64         order = order_obj.browse(request.cr, SUPERUSER_ID, order_id)
65         if token != order.access_token:
66             return request.website.render('website.404')
67         attachments=sign and [('signature.png', sign)] or []
68         order_obj.signal_order_confirm(request.cr, SUPERUSER_ID, [order_id], context=request.context)
69         message = _('Order signed by %s') % (signer,)
70         self.__message_post(message, order_id, type='comment', subtype='mt_comment', attachments=attachments)
71         return True
72
73     @http.route(['/quote/<int:order_id>/<token>/decline'], type='http', auth="public", website=True)
74     def decline(self, order_id, token, **post):
75         order_obj = request.registry.get('sale.order')
76         order = order_obj.browse(request.cr, SUPERUSER_ID, order_id)
77         if token != order.access_token:
78             return request.website.render('website.404')
79         request.registry.get('sale.order').action_cancel(request.cr, SUPERUSER_ID, [order_id])
80         message = post.get('decline_message')
81         if message:
82             self.__message_post(message, order_id, type='comment', subtype='mt_comment')
83         return werkzeug.utils.redirect("/quote/%s/%s?message=2" % (order_id, token))
84
85     @http.route(['/quote/<int:order_id>/<token>/post'], type='http', auth="public", website=True)
86     def post(self, order_id, token, **post):
87         # use SUPERUSER_ID allow to access/view order for public user
88         order_obj = request.registry.get('sale.order')
89         order = order_obj.browse(request.cr, SUPERUSER_ID, order_id)
90         message = post.get('comment')
91         if token != order.access_token:
92             return request.website.render('website.404')
93         if message:
94             self.__message_post(message, order_id, type='comment', subtype='mt_comment')
95         return werkzeug.utils.redirect("/quote/%s/%s?message=1" % (order_id, token))
96
97     def __message_post(self, message, order_id, type='comment', subtype=False, attachments=[]):
98         request.session.body =  message
99         cr, uid, context = request.cr, request.uid, request.context
100         user = request.registry['res.users'].browse(cr, SUPERUSER_ID, uid, context=context)
101         if 'body' in request.session and request.session.body:
102             request.registry.get('sale.order').message_post(cr, SUPERUSER_ID, order_id,
103                     body=request.session.body,
104                     type=type,
105                     subtype=subtype,
106                     author_id=user.partner_id.id,
107                     context=context,
108                     attachments=attachments
109                 )
110             request.session.body = False
111         return True
112
113     @http.route(['/quote/update_line'], type='json', auth="public", website=True)
114     def update(self, line_id, remove=False, unlink=False, order_id=None, token=None, **post):
115         order = request.registry.get('sale.order').browse(request.cr, SUPERUSER_ID, int(order_id))
116         if token != order.access_token:
117             return request.website.render('website.404')
118         if order.state not in ('draft','sent'):
119             return False
120         line_id=int(line_id)
121         if unlink:
122             request.registry.get('sale.order.line').unlink(request.cr, SUPERUSER_ID, [line_id], context=request.context)
123             return False
124         number=(remove and -1 or 1)
125
126         order_line_obj = request.registry.get('sale.order.line')
127         order_line_val = order_line_obj.read(request.cr, SUPERUSER_ID, [line_id], [], context=request.context)[0]
128         quantity = order_line_val['product_uom_qty'] + number
129         order_line_obj.write(request.cr, SUPERUSER_ID, [line_id], {'product_uom_qty': (quantity)}, context=request.context)
130         return [str(quantity), str(order.amount_total)]
131
132     @http.route(["/quote/template/<model('sale.quote.template'):quote>"], type='http', auth="user", website=True, multilang=True)
133     def template_view(self, quote, **post):
134         values = { 'template': quote }
135         return request.website.render('website_quote.so_template', values)
136
137     @http.route(["/quote/add_line/<int:option_id>/<int:order_id>/<token>"], type='http', auth="public", website=True)
138     def add(self, option_id, order_id, token, **post):
139         vals = {}
140         order = request.registry.get('sale.order').browse(request.cr, SUPERUSER_ID, order_id)
141         if token != order.access_token:
142             return request.website.render('website.404')
143         option_obj = request.registry.get('sale.order.option')
144         option = option_obj.browse(request.cr, SUPERUSER_ID, option_id)
145
146         res = request.registry.get('sale.order.line').product_id_change(request.cr, SUPERUSER_ID, order_id,
147             False, option.product_id.id, option.quantity, option.uom_id.id, option.quantity, option.uom_id.id,
148             option.name, order.partner_id.id, False, True, time.strftime('%Y-%m-%d'),
149             False, order.fiscal_position.id, True, request.context)
150         vals = res.get('value', {})
151         if 'tax_id' in vals:
152             vals['tax_id'] = [(6, 0, vals['tax_id'])]
153
154         vals.update({
155             'price_unit': option.price_unit,
156             'website_description': option.website_description,
157             'name': option.name,
158             'order_id': order.id,
159             'product_id' : option.product_id.id,
160             'product_uos_qty': option.quantity,
161             'product_uos': option.uom_id.id,
162             'product_uom_qty': option.quantity,
163             'product_uom': option.uom_id.id,
164             'discount': option.discount,
165         })
166         line = request.registry.get('sale.order.line').create(request.cr, SUPERUSER_ID, vals, context=request.context)
167         option_obj.write(request.cr, SUPERUSER_ID, [option.id], {'line_id': line}, context=request.context)
168         return werkzeug.utils.redirect("/quote/%s/%s#pricing" % (order.id, token))
169
170