コード例 #1
0
 def setUp(self):
     super(TestWebsiteSaleCheckoutAddress, self).setUp()
     self.website = self.env.ref('website.default_website')
     self.country_id = self.env.ref('base.be').id
     self.WebsiteSaleController = WebsiteSale()
     self.default_address_values = {
         'name': 'a res.partner address', 'email': '*****@*****.**', 'street': 'ooo',
         'city': 'ooo', 'zip': '1200', 'country_id': self.country_id, 'submitted': 1,
     }
コード例 #2
0
    def test_create_visitor_on_tracked_product(self):
        self.WebsiteSaleController = WebsiteSale()
        Visitor = self.env['website.visitor']
        Track = self.env['website.track']

        self.assertEqual(len(Visitor.search([])), 0,
                         "No visitor at the moment")
        self.assertEqual(len(Track.search([])), 0, "No track at the moment")

        product = self.env['product.product'].create({
            'name': 'Storage Box',
            'website_published': True,
        })

        with MockRequest(self.env, website=self.website):
            self.cookies = self.WebsiteSaleController.products_recently_viewed_update(
                product.id)

        self.assertEqual(
            len(Visitor.search([])), 1,
            "A visitor should be created after visiting a tracked product")
        self.assertEqual(
            len(Track.search([])), 1,
            "A track should be created after visiting a tracked product")

        with MockRequest(self.env, website=self.website, cookies=self.cookies):
            self.WebsiteSaleController.products_recently_viewed_update(
                product.id)

        self.assertEqual(
            len(Visitor.search([])), 1,
            "No visitor should be created after visiting another tracked product"
        )
        self.assertEqual(
            len(Track.search([])), 1,
            "No track should be created after visiting the same tracked product before 30 min"
        )

        product = self.env['product.product'].create({
            'name': 'Large Cabinet',
            'website_published': True,
            'list_price': 320.0,
        })

        with MockRequest(self.env, website=self.website, cookies=self.cookies):
            self.WebsiteSaleController.products_recently_viewed_update(
                product.id)

        self.assertEqual(
            len(Visitor.search([])), 1,
            "No visitor should be created after visiting another tracked product"
        )
        self.assertEqual(
            len(Track.search([])), 2,
            "A track should be created after visiting another tracked product")
コード例 #3
0
class WebsiteSaleVisitorTests(TransactionCase):
    def setUp(self):
        super().setUp()
        self.website = self.env['website'].browse(1)
        self.WebsiteSaleController = WebsiteSale()
        self.cookies = {}

    def test_create_visitor_on_tracked_product(self):
        self.WebsiteSaleController = WebsiteSale()
        Visitor = self.env['website.visitor']
        Track = self.env['website.track']

        self.assertEqual(len(Visitor.search([])), 0,
                         "No visitor at the moment")
        self.assertEqual(len(Track.search([])), 0, "No track at the moment")

        product = self.env.ref('product.product_product_7')

        with MockRequest(self.env, website=self.website):
            self.cookies = self.WebsiteSaleController.products_recently_viewed_update(
                product.id)

        self.assertEqual(
            len(Visitor.search([])), 1,
            "A visitor should be created after visiting a tracked product")
        self.assertEqual(
            len(Track.search([])), 1,
            "A track should be created after visiting a tracked product")

        with MockRequest(self.env, website=self.website, cookies=self.cookies):
            self.WebsiteSaleController.products_recently_viewed_update(
                product.id)

        self.assertEqual(
            len(Visitor.search([])), 1,
            "No visitor should be created after visiting another tracked product"
        )
        self.assertEqual(
            len(Track.search([])), 1,
            "No track should be created after visiting the same tracked product before 30 min"
        )

        product = self.env.ref('product.product_product_6')
        with MockRequest(self.env, website=self.website, cookies=self.cookies):
            self.WebsiteSaleController.products_recently_viewed_update(
                product.id)

        self.assertEqual(
            len(Visitor.search([])), 1,
            "No visitor should be created after visiting another tracked product"
        )
        self.assertEqual(
            len(Track.search([])), 2,
            "A track should be created after visiting another tracked product")
コード例 #4
0
 def setUp(self):
     super(TestWebsiteSaleCheckoutAddress, self).setUp()
     self.website = self.env['website'].browse(1)
     self.country_id = self.env['res.country'].search([], limit=1).id
     self.WebsiteSaleController = WebsiteSale()
     self.default_address_values = {
         'name': 'a res.partner address',
         'email': '*****@*****.**',
         'street': 'ooo',
         'city': 'ooo',
         'country_id': self.country_id,
         'submitted': 1,
     }
コード例 #5
0
 def slider_data(self, **kwargs):
     slider_id = kwargs.get('slider_id', False)
     filter_id = kwargs.get('filter_id', False)
     slider_obj = request.env['slider'].sudo().search([('id', '=', int(slider_id))])
     vals ={}
     if slider_obj:
         if slider_obj.slider_type == 'product':
             filter = slider_obj.slider_filter_ids[0] if not filter_id  else request.env['slider.filter'].sudo().search([('id', '=', int(filter_id))])
             if filter.filter_id.domain:
                 compute_currency, pricelist_context, pricelist =  WebsiteSale()._get_compute_currency_and_context()
                 domain = safe_eval(filter.filter_id.domain)
                 domain+=['|',('website_id', '=',None),('website_id', '=', request.website.id),('website_published','=',True)]
                 product = request.env['product.template'].sudo().search(domain,limit=slider_obj.slider_limit)
                 vals ={
                         'slider_obj':slider_obj,
                         'filter_data':product,
                         'compute_currency':compute_currency,
                         'active_filter_data':filter_id if filter_id else slider_obj.slider_filter_ids[0].id,
                         'is_default':False if filter_id else True
                     }
             tmplt_external_id=slider_obj.slider_style_id.get_external_id().get(slider_obj.slider_style_id.id)+"_template"
             tmplt=request.env['ir.ui.view'].sudo().search([('key','=',tmplt_external_id)])
             if tmplt:
                 response = http.Response(template=tmplt_external_id, qcontext=vals)
                 return response.render()
             else:
                 return False
         else:
             domain=[('website_id','in',(False,request.website.get_current_website().id)),('parent_id','=',False)]
             category = request.env['product.public.category'].sudo().search(domain,limit=slider_obj.slider_limit)
             return request.env.ref("emipro_theme_base.theme_category_carousel").render({'object':category})
コード例 #6
0
 def GetUrlData(self, token, token2=None, page=0, **kwargs):
     url = '/' + token
     if token2:
         url = url + '/' + token2
     page_resouce = request.env['seo.url'].sudo().search(
         [('url', '=', url), ('website_id.id', '=', request.website.id)],
         limit=1)
     if page_resouce and page_resouce.product_id:
         if page_resouce.product_id.is_published:
             product_object = WebsiteSale()
             return product_object.product(page_resouce.product_id,
                                           **kwargs)
         else:
             return request.render("website.404")
     elif page_resouce and page_resouce.categ_id:
         if page_resouce.categ_id.website_published:
             shop_object = WebsiteSale()
             return shop_object.shop(category=page_resouce.categ_id,
                                     page=page,
                                     **kwargs)
         else:
             return request.render("website.404")
     else:
         website_page = request.env['ir.http']._serve_page()
         if website_page:
             return website_page
         else:
             raise request.not_found()
コード例 #7
0
ファイル: test_sale_process.py プロジェクト: veivaa/odoo
class TestWebsiteSaleCheckoutAddress(TransactionCaseWithUserDemo):
    ''' The goal of this method class is to test the address management on
        the checkout (new/edit billing/shipping, company_id, website_id..).
    '''
    def setUp(self):
        super(TestWebsiteSaleCheckoutAddress, self).setUp()
        self.website = self.env.ref('website.default_website')
        self.country_id = self.env.ref('base.be').id
        self.WebsiteSaleController = WebsiteSale()
        self.default_address_values = {
            'name': 'a res.partner address',
            'email': '*****@*****.**',
            'street': 'ooo',
            'city': 'ooo',
            'zip': '1200',
            'country_id': self.country_id,
            'submitted': 1,
        }

    def _create_so(self, partner_id=None):
        return self.env['sale.order'].create({
            'partner_id':
            partner_id,
            'website_id':
            self.website.id,
            'order_line': [(0, 0, {
                'product_id':
                self.env['product.product'].create({
                    'name': 'Product A',
                    'list_price': 100
                }).id,
                'name':
                'Product A',
            })]
        })

    def _get_last_address(self, partner):
        ''' Useful to retrieve the last created shipping address '''
        return partner.child_ids.sorted('id', reverse=True)[0]

    # TEST WEBSITE
    def test_01_create_shipping_address_specific_user_account(self):
        ''' Ensure `website_id` is correctly set (specific_user_account) '''
        p = self.env.user.partner_id
        so = self._create_so(p.id)

        with MockRequest(self.env, website=self.website, sale_order_id=so.id):
            self.WebsiteSaleController.address(**self.default_address_values)
            self.assertFalse(
                self._get_last_address(p).website_id,
                "New shipping address should not have a website set on it (no specific_user_account)."
            )

            self.website.specific_user_account = True

            self.WebsiteSaleController.address(**self.default_address_values)
            self.assertEqual(
                self._get_last_address(p).website_id, self.website,
                "New shipping address should have a website set on it (specific_user_account)."
            )

    # TEST COMPANY
    def _setUp_multicompany_env(self):
        ''' Have 2 companies A & B.
            Have 1 website 1 which company is B
            Have admin on company A
        '''
        self.company_a = self.env['res.company'].create({
            'name': 'Company A',
        })
        self.company_b = self.env['res.company'].create({
            'name': 'Company B',
        })
        self.company_c = self.env['res.company'].create({
            'name': 'Company C',
        })
        self.website.company_id = self.company_b
        self.env.user.company_id = self.company_a

        self.demo_user = self.user_demo
        self.demo_user.company_ids += self.company_c
        self.demo_user.company_id = self.company_c
        self.demo_partner = self.demo_user.partner_id

    def test_02_demo_address_and_company(self):
        ''' This test ensure that the company_id of the address (partner) is
            correctly set and also, is not wrongly changed.
            eg: new shipping should use the company of the website and not the
                one from the admin, and editing a billing should not change its
                company.
        '''
        self._setUp_multicompany_env()
        so = self._create_so(self.demo_partner.id)

        env = api.Environment(self.env.cr, self.demo_user.id, {})
        # change also website env for `sale_get_order` to not change order partner_id
        with MockRequest(env,
                         website=self.website.with_env(env),
                         sale_order_id=so.id):
            # 1. Logged in user, new shipping
            self.WebsiteSaleController.address(**self.default_address_values)
            new_shipping = self._get_last_address(self.demo_partner)
            self.assertTrue(
                new_shipping.company_id != self.env.user.company_id,
                "Logged in user new shipping should not get the company of the sudo() neither the one from it's partner.."
            )
            self.assertEqual(new_shipping.company_id, self.website.company_id,
                             ".. but the one from the website.")

            # 2. Logged in user, edit billing
            self.default_address_values['partner_id'] = self.demo_partner.id
            self.WebsiteSaleController.address(**self.default_address_values)
            self.assertEqual(
                self.demo_partner.company_id, self.company_c,
                "Logged in user edited billing (the partner itself) should not get its company modified."
            )

    def test_03_public_user_address_and_company(self):
        ''' Same as test_02 but with public user '''
        self._setUp_multicompany_env()
        so = self._create_so(self.website.user_id.partner_id.id)

        env = api.Environment(self.env.cr, self.website.user_id.id, {})
        # change also website env for `sale_get_order` to not change order partner_id
        with MockRequest(env,
                         website=self.website.with_env(env),
                         sale_order_id=so.id):
            # 1. Public user, new billing
            self.default_address_values['partner_id'] = -1
            self.WebsiteSaleController.address(**self.default_address_values)
            new_partner = so.partner_id
            self.assertNotEqual(
                new_partner, self.website.user_id.partner_id,
                "New billing should have created a new partner and assign it on the SO"
            )
            self.assertEqual(
                new_partner.company_id, self.website.company_id,
                "The new partner should get the company of the website")

            # 2. Public user, edit billing
            self.default_address_values['partner_id'] = new_partner.id
            self.WebsiteSaleController.address(**self.default_address_values)
            self.assertEqual(
                new_partner.company_id, self.website.company_id,
                "Public user edited billing (the partner itself) should not get its company modified."
            )

    def test_04_apply_empty_pl(self):
        ''' Ensure empty pl code reset the applied pl '''
        so = self._create_so(self.env.user.partner_id.id)
        eur_pl = self.env['product.pricelist'].create({
            'name':
            'EUR_test',
            'website_id':
            self.website.id,
            'code':
            'EUR_test',
        })

        with MockRequest(self.env, website=self.website, sale_order_id=so.id):
            self.WebsiteSaleController.pricelist('EUR_test')
            self.assertEqual(so.pricelist_id, eur_pl,
                             "Ensure EUR_test is applied")

            self.WebsiteSaleController.pricelist('')
            self.assertNotEqual(
                so.pricelist_id, eur_pl,
                "Pricelist should be removed when sending an empty pl code")
コード例 #8
0
 def setUp(self):
     super().setUp()
     self.website = self.env['website'].browse(1)
     self.WebsiteSaleController = WebsiteSale()
     self.cookies = {}
コード例 #9
0
    def Brand(self,
              brand=None,
              page=0,
              category=None,
              search='',
              ppg=False,
              **post):
        add_qty = int(post.get('add_qty', 1))
        Category = request.env['product.public.category']
        if category:
            category = Category.search([('id', '=', int(category))], limit=1)
            if not category or not category.can_access_from_current_website():
                raise NotFound()
        else:
            category = Category

        if ppg:
            try:
                ppg = int(ppg)
                post['ppg'] = ppg
            except ValueError:
                ppg = False
        if not ppg:
            ppg = 20

        ppr = 4

        attrib_list = request.httprequest.args.getlist('attrib')
        attrib_values = [[int(x) for x in v.split("-")] for v in attrib_list
                         if v]
        attributes_ids = {v[0] for v in attrib_values}
        attrib_set = {v[1] for v in attrib_values}

        domain = WebsiteSale._get_search_domain(self, search, category,
                                                attrib_values)

        # Set the brand product
        if brand:
            domain += [('product_brand_ept_id.id', '=', brand.id)]
        else:
            domain += [('product_brand_ept_id', '!=', False)]

        keep = QueryURL('/shop',
                        category=category and int(category),
                        search=search,
                        attrib=attrib_list,
                        order=post.get('order'))

        pricelist_context, pricelist = WebsiteSale._get_pricelist_context(self)

        request.context = dict(request.context,
                               pricelist=pricelist.id,
                               partner=request.env.user.partner_id)

        url = "/shop"
        if search:
            post["search"] = search
        if attrib_list:
            post['attrib'] = attrib_list

        Product = request.env['product.template'].with_context(bin_size=True)

        search_product = Product.search(domain)
        website_domain = request.website.website_domain()
        categs_domain = [('parent_id', '=', False)] + website_domain
        # if search:
        #     search_categories = Category.search(
        #         [('product_tmpl_ids', 'in', search_product.ids)] + website_domain).parents_and_self
        #     categs_domain.append(('id', 'in', search_categories.ids))
        # else:
        #     search_categories = Category
        search_categories = False
        if search:
            categories = search_product.mapped('public_categ_ids')
            search_categories = Category.search(
                [('id', 'parent_of', categories.ids)] +
                request.website.website_domain())
            categs = search_categories.filtered(lambda c: not c.parent_id)
        else:
            categs = Category.search([('parent_id', '=', False)] +
                                     request.website.website_domain())
        # categs = Category.search(categs_domain)

        if category:
            url = "/shop/category/%s" % slug(category)

        product_count = len(search_product)
        pager = request.website.pager(url=url,
                                      total=product_count,
                                      page=page,
                                      step=ppg,
                                      scope=7,
                                      url_args=post)
        products = Product.search(domain,
                                  limit=ppg,
                                  offset=pager['offset'],
                                  order=WebsiteSale._get_search_order(
                                      self, post))

        ProductAttribute = request.env['product.attribute']
        # if products:
        #     # get all products without limit
        #     attributes = ProductAttribute.search([('product_tmpl_ids', 'in', search_product.ids)])
        # else:
        #     attributes = ProductAttribute.browse(attributes_ids)

        if products:
            attributes = ProductAttribute.search([
                ('attribute_line_ids.value_ids', '!=', False),
                ('attribute_line_ids.product_tmpl_id', 'in',
                 search_product.ids)
            ])
        else:
            attributes = ProductAttribute.browse(attributes_ids)

        layout_mode = request.session.get('website_sale_shop_layout_mode')
        if not layout_mode:
            if request.website.viewref(
                    'website_sale.products_list_view').active:
                layout_mode = 'list'
            else:
                layout_mode = 'grid'

        values = {
            'search': search,
            'category': category,
            'attrib_values': attrib_values,
            'attrib_set': attrib_set,
            'pager': pager,
            'pricelist': pricelist,
            'add_qty': add_qty,
            'products': products,
            'search_count': product_count,  # common for all searchbox
            'bins': TableCompute().process(products, ppg, ppr),
            'ppg': ppg,
            'ppr': ppr,
            'categories': categs,
            'attributes': attributes,
            'keep': keep,
            # 'search_categories_ids': search_categories.ids,
            'layout_mode': layout_mode,
            'brand': brand,
            'is_brand_page': True
        }
        if category:
            values['main_object'] = category
        return request.render("website_sale.products", values)
コード例 #10
0
 def setUpClass(cls):
     super(WebsiteSaleCart, cls).setUpClass()
     cls.website = cls.env['website'].browse(1)
     cls.WebsiteSaleController = WebsiteSale()
     cls.public_user = cls.env.ref('base.public_user')
コード例 #11
0
 def blog_post(self, **kw):
     response = super(WebsiteSaleBlog, self).blog_post(**kw)
     if response.status_code == 200:
         response.qcontext['pricelist'] = WebsiteSale(
         )._get_pricelist_context()[1]
     return response
コード例 #12
0
 def setUp(self):
     super().setUp()
     self.website = self.env.ref('website.default_website')
     self.WebsiteSaleController = WebsiteSale()
     self.cookies = {}
コード例 #13
0
class WebsiteSaleVisitorTests(TransactionCase):

    def setUp(self):
        super().setUp()
        self.website = self.env.ref('website.default_website')
        self.WebsiteSaleController = WebsiteSale()
        self.cookies = {}

    def test_create_visitor_on_tracked_product(self):
        self.WebsiteSaleController = WebsiteSale()
        existing_visitors = self.env['website.visitor'].search([])
        existing_tracks = self.env['website.track'].search([])

        product = self.env['product.product'].create({
            'name': 'Storage Box',
            'website_published': True,
        })

        with MockRequest(self.env, website=self.website):
            self.cookies = self.WebsiteSaleController.products_recently_viewed_update(product.id)

        new_visitors = self.env['website.visitor'].search([('id', 'not in', existing_visitors.ids)])
        new_tracks = self.env['website.track'].search([('id', 'not in', existing_tracks.ids)])
        self.assertEqual(len(new_visitors), 1, "A visitor should be created after visiting a tracked product")
        self.assertEqual(len(new_tracks), 1, "A track should be created after visiting a tracked product")

        with MockRequest(self.env, website=self.website, cookies=self.cookies):
            self.WebsiteSaleController.products_recently_viewed_update(product.id)

        new_visitors = self.env['website.visitor'].search([('id', 'not in', existing_visitors.ids)])
        new_tracks = self.env['website.track'].search([('id', 'not in', existing_tracks.ids)])
        self.assertEqual(len(new_visitors), 1, "No visitor should be created after visiting another tracked product")
        self.assertEqual(len(new_tracks), 1, "No track should be created after visiting the same tracked product before 30 min")

        product = self.env['product.product'].create({
            'name': 'Large Cabinet',
            'website_published': True,
            'list_price': 320.0,
        })

        with MockRequest(self.env, website=self.website, cookies=self.cookies):
            self.WebsiteSaleController.products_recently_viewed_update(product.id)

        new_visitors = self.env['website.visitor'].search([('id', 'not in', existing_visitors.ids)])
        new_tracks = self.env['website.track'].search([('id', 'not in', existing_tracks.ids)])
        self.assertEqual(len(new_visitors), 1, "No visitor should be created after visiting another tracked product")
        self.assertEqual(len(new_tracks), 2, "A track should be created after visiting another tracked product")

    def test_recently_viewed_company_changed(self):
        # Test that, by changing the company of a tracked product, the recently viewed product do not crash
        new_company = self.env['res.company'].create({
            'name': 'Test Company',
        })
        public_user = self.env.ref('base.public_user')

        product = self.env['product.product'].create({
            'name': 'Test Product',
            'website_published': True,
            'sale_ok': True,
        })

        self.website = self.website.with_user(public_user).with_context(website_id=self.website.id)
        with MockRequest(self.website.env, website=self.website):
            self.cookies = self.WebsiteSaleController.products_recently_viewed_update(product.id)
        product.product_tmpl_id.company_id = new_company
        product.product_tmpl_id.flush_recordset(['company_id'])
        with MockRequest(self.website.env, website=self.website, cookies=self.cookies):
            # Should not raise an error
            res = self.website.env['website.snippet.filter']._get_products_latest_viewed(self.website, 16, [], {})
            self.assertFalse(res)
コード例 #14
0
ファイル: amp_main.py プロジェクト: dionisiotorres/googletag
    def shop_amp(self, page=0, category=None, search='', ppg=False, **post):
        if request.website.is_amp_enable:
            add_qty = int(post.get('add_qty', 1))
            Category = request.env['product.public.category']
            if category:
                category = Category.search([('id', '=', int(category))],
                                           limit=1)
                if not category or not category.can_access_from_current_website(
                ):
                    raise NotFound()
            else:
                category = Category

            page_no = request.env['product.per.page.no'].sudo().search([
                ('set_default_check', '=', True)
            ])
            if page_no:
                ppg = int(page_no.name)
            else:
                ppg = result.qcontext['ppg']

            ppr = request.env['website'].get_current_website().shop_ppr or 4

            attrib_list = request.httprequest.args.getlist('attrib')
            attrib_values = [[int(x) for x in v.split("-")]
                             for v in attrib_list if v]
            attributes_ids = {v[0] for v in attrib_values}
            attrib_set = {v[1] for v in attrib_values}

            domain = self._get_search_domain(search, category, attrib_values)
            if request.session.get('default_paging_no'):
                ppg = int(request.session.get('default_paging_no'))
            keep = QueryURL('/shop/amp',
                            category=category and int(category),
                            search=search,
                            attrib=attrib_list,
                            order=post.get('order'))

            pricelist_context, pricelist = WebsiteSale._get_pricelist_context(
                self)

            request.context = dict(request.context,
                                   pricelist=pricelist.id,
                                   partner=request.env.user.partner_id)

            url = "/shop/amp"
            if search:
                post["search"] = search
            if attrib_list:
                post['attrib'] = attrib_list

            Product = request.env['product.template'].with_context(
                bin_size=True)

            search_product = Product.search(domain)
            website_domain = request.website.website_domain()
            categs_domain = [('parent_id', '=', False)] + website_domain
            if search:
                search_categories = Category.search(
                    [('product_tmpl_ids', 'in', search_product.ids)] +
                    website_domain).parents_and_self
                categs_domain.append(('id', 'in', search_categories.ids))
            else:
                search_categories = Category
            categs = Category.search(categs_domain)

            if category:
                url = "/shop/amp/category/%s" % slug(category)

            product_count = len(search_product)
            pager = request.website.pager(url=url,
                                          total=product_count,
                                          page=page,
                                          step=ppg,
                                          scope=7,
                                          url_args=post)
            products = Product.search(domain,
                                      limit=ppg,
                                      offset=pager['offset'],
                                      order=self._get_search_order(post))

            ProductAttribute = request.env['product.attribute']
            if products:
                # get all products without limit
                attributes = ProductAttribute.search([
                    ('product_tmpl_ids', 'in', search_product.ids)
                ])
            else:
                attributes = ProductAttribute.browse(attributes_ids)

            layout_mode = request.session.get('website_sale_shop_layout_mode')
            if not layout_mode:
                if request.website.viewref(
                        'website_sale.products_list_view').active:
                    layout_mode = 'list'
                else:
                    layout_mode = 'grid'

            values = {
                'search': search,
                'category': category,
                'attrib_values': attrib_values,
                'attrib_set': attrib_set,
                'pager': pager,
                'pricelist': pricelist,
                'add_qty': add_qty,
                'products': products,
                'search_count': product_count,  # common for all searchbox
                'bins': TableCompute().process(products, ppg, ppr),
                'ppg': ppg,
                'ppr': ppr,
                'categories': categs,
                'attributes': attributes,
                'keep': keep,
                'search_categories_ids': search_categories.ids,
                'layout_mode': layout_mode,
            }
            if category:
                values['main_object'] = category
            return request.render("theme_scita.apm_shop_page_view", values)
        else:
            raise NotFound()