mirror of
https://github.com/bringout/oca-ocb-sale.git
synced 2026-04-27 18:52:07 +02:00
352 lines
13 KiB
Python
352 lines
13 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from datetime import datetime, timedelta
|
|
from lxml import etree
|
|
from urllib.parse import urlparse
|
|
|
|
from odoo.fields import Command
|
|
from odoo.tests import HttpCase, tagged
|
|
|
|
from odoo.addons.website_sale.tests.common import MockRequest
|
|
from odoo.addons.website_sale.tests.common_gmc import WebsiteSaleGMCCommon
|
|
|
|
|
|
@tagged('post_install', '-at_install')
|
|
class TestWebsiteSaleGMC(WebsiteSaleGMCCommon, HttpCase):
|
|
|
|
def test_gmc_xml_accessible_if_gmc_setting_enabled(self):
|
|
response = self.url_open(self.gmc_feed.url)
|
|
|
|
self.assertEqual(200, response.status_code)
|
|
|
|
def test_gmc_xml_not_found_if_gmc_setting_disabled(self):
|
|
self.website.enabled_gmc_src = False
|
|
|
|
response = self.url_open(self.gmc_feed.url)
|
|
|
|
self.assertEqual(404, response.status_code, 'Not Found')
|
|
|
|
def test_gmc_xml_correct_xml_format(self):
|
|
response = self.url_open(self.gmc_feed.url)
|
|
|
|
gmc_xml = etree.XML(response.content) # assert valid xml
|
|
self.assertEqual(self.website.name, gmc_xml.xpath('//title')[0].text)
|
|
self.assertURLEqual('/en', gmc_xml.xpath('//link')[0].text)
|
|
self.assertEqual(
|
|
'This is the homepage of the website',
|
|
gmc_xml.xpath('//description')[0].text,
|
|
)
|
|
|
|
def test_gmc_xml_localization(self):
|
|
fr_lang = self.env['res.lang']._activate_lang('fr_FR')
|
|
self.website.language_ids += fr_lang
|
|
self.gmc_feed.lang_id = fr_lang
|
|
self.red_sofa.with_context(lang=fr_lang.code).name = 'Canapé'
|
|
self.color_attribute_red.with_context(lang=fr_lang.code).name = 'rouge'
|
|
|
|
self.update_items()
|
|
|
|
self.assertRegex(
|
|
self.parse_http_location(self.red_sofa_item['link']).path,
|
|
f'^\\/{fr_lang.url_code}.*',
|
|
'The links must redirect to the french website.',
|
|
)
|
|
self.assertEqual(
|
|
'Canapé (rouge)',
|
|
self.red_sofa_item['title'],
|
|
)
|
|
|
|
def test_gmc_xml_pricelist(self):
|
|
self.gmc_feed.pricelist_id = self.eur_pricelist
|
|
|
|
with MockRequest(
|
|
self.env,
|
|
website=self.website,
|
|
website_sale_current_pl=self.pricelist.id,
|
|
):
|
|
gmc_xml = etree.XML(self.gmc_feed._render_gmc_feed().encode())
|
|
|
|
self.assertEqual(
|
|
'1100.0 EUR', # 1000.0 * 1.1 (EUR rate)
|
|
gmc_xml.xpath(
|
|
'//item[g:id="SOFA-R"]/g:price', namespaces={'g': 'http://base.google.com/ns/1.0'}
|
|
)[0].text
|
|
)
|
|
|
|
def test_gmc_items_required_fields(self):
|
|
self.update_items()
|
|
|
|
for item in self.items.values():
|
|
self.assertLessEqual(
|
|
{
|
|
'id',
|
|
'title',
|
|
'description',
|
|
'link',
|
|
'image_link',
|
|
'availability',
|
|
'price',
|
|
'identifier_exists',
|
|
},
|
|
item.keys(),
|
|
) # subseteq
|
|
|
|
def test_gmc_items_use_internal_reference_if_exists(self):
|
|
"""Test prefer internal code to database id"""
|
|
# setup: red_sofa.code = 'SOFA-R', blue_sofa.code = False
|
|
self.update_items()
|
|
|
|
self.assertEqual(self.red_sofa.code, self.red_sofa_item['id'])
|
|
self.assertEqual(self.blue_sofa.id, self.blue_sofa_item['id'])
|
|
|
|
def test_gmc_items_link_redirects_to_correct_product_case_default_pricelist(self):
|
|
self.update_items()
|
|
|
|
for product in self.red_sofa + self.blue_sofa:
|
|
response = self.url_open(self.items[product]['link'])
|
|
|
|
self.assertEqual(200, response.status_code)
|
|
self.assertURLEqual(product.website_url, response.url)
|
|
|
|
def test_gmc_items_link_redirects_to_correct_product_case_specific_pricelist(self):
|
|
self.gmc_feed.pricelist_id = self.eur_pricelist
|
|
self.update_items()
|
|
|
|
for product in self.red_sofa + self.blue_sofa:
|
|
response = self.url_open(self.items[product]['link'])
|
|
|
|
self.assertEqual(200, response.status_code)
|
|
url = urlparse(product.website_url)
|
|
self.assertURLEqual(
|
|
f'{url.path}'
|
|
f'?attribute_values={",".join(str(i) for i in product.product_template_attribute_value_ids.product_attribute_value_id.ids)}'
|
|
f'&pricelist={self.eur_pricelist.id}'
|
|
f'#{url.fragment}',
|
|
response.url,
|
|
)
|
|
|
|
def test_gmc_items_prices_match_website_prices_default(self):
|
|
self.update_items()
|
|
|
|
self.assertEqual('1000.0 USD', self.red_sofa_item['price'])
|
|
self.assertEqual('1200.0 USD', self.blue_sofa_item['price'])
|
|
self.start_tour(
|
|
self.red_sofa_item['link'],
|
|
'website_sale_gmc_check_advertised_prices_red_sofa_default',
|
|
)
|
|
self.start_tour(
|
|
self.blue_sofa_item['link'],
|
|
'website_sale_gmc_check_advertised_prices_blue_sofa_default',
|
|
)
|
|
|
|
def test_gmc_items_prices_match_website_prices_christmas(self):
|
|
self.gmc_feed.pricelist_id = self._create_pricelist(
|
|
name="EUR Christmas Sales",
|
|
currency_id=self.eur_currency.id,
|
|
selectable=True,
|
|
item_ids=[
|
|
Command.create({
|
|
'product_tmpl_id': self.product_template_sofa.id,
|
|
'compute_price': 'percentage',
|
|
'percent_price': 10.0,
|
|
'date_start': datetime.now() - timedelta(1),
|
|
'date_end': datetime.now() + timedelta(1),
|
|
}),
|
|
Command.create({
|
|
'compute_price': 'percentage',
|
|
'percent_price': 0.0,
|
|
}),
|
|
],
|
|
)
|
|
|
|
self.update_items()
|
|
|
|
# 1000.0 (list_price) * 1.1 (EUR rate) - 10% (discount)
|
|
self.assertEqual('990.0 EUR', self.red_sofa_item['sale_price'])
|
|
# 1200.0 (list_price) * 1.1 (EUR rate) - 10% (discount)
|
|
self.assertEqual('1188.0 EUR', self.blue_sofa_item['sale_price'])
|
|
# 100.0 (list_price) * 1.1 (EUR rate)
|
|
self.assertEqual('110.0 EUR', self.items[self.blanket]['price'])
|
|
self.assertNotIn('sale_price', self.items[self.blanket]) # no discount
|
|
self.assertNotEqual(self.red_sofa_item['link'], self.blue_sofa_item['link'])
|
|
self.start_tour(
|
|
self.red_sofa_item['link'],
|
|
'website_sale_gmc_check_advertised_prices_red_sofa_christmas',
|
|
)
|
|
self.start_tour(
|
|
self.blue_sofa_item['link'],
|
|
'website_sale_gmc_check_advertised_prices_blue_sofa_christmas',
|
|
)
|
|
|
|
def test_gmc_items_prices_match_website_prices_tax_included(self):
|
|
# 15% taxes
|
|
self.website.show_line_subtotals_tax_selection = 'tax_included'
|
|
|
|
self.update_items()
|
|
|
|
self.assertEqual('1150.0 USD', self.red_sofa_item['price'])
|
|
self.assertEqual('1380.0 USD', self.blue_sofa_item['price'])
|
|
self.start_tour(
|
|
self.red_sofa_item['link'],
|
|
'website_sale_gmc_check_advertised_prices_red_sofa_tax_included',
|
|
)
|
|
self.start_tour(
|
|
self.blue_sofa_item['link'],
|
|
'website_sale_gmc_check_advertised_prices_blue_sofa_tax_included',
|
|
)
|
|
|
|
def test_gmc_items_additional_images_limit_to_10(self):
|
|
image = self._create_image('blue')
|
|
self.blue_sofa.write({
|
|
'product_variant_image_ids': [
|
|
Command.create({
|
|
'name': f'image {i}',
|
|
'image_1920': image,
|
|
})
|
|
for i in range(12)
|
|
]
|
|
})
|
|
|
|
self.update_items()
|
|
|
|
self.assertEqual(10, len(self.blue_sofa_item['additional_image_link']))
|
|
|
|
def test_gmc_items_identifier_exists_iff_barcode_exists(self):
|
|
self.red_sofa.barcode = '0232344532564'
|
|
|
|
self.update_items()
|
|
|
|
self.assertEqual(self.red_sofa.barcode, self.red_sofa_item['gtin'])
|
|
self.assertEqual('yes', self.red_sofa_item['identifier_exists'])
|
|
self.assertNotIn('gtin', self.blue_sofa_item)
|
|
self.assertEqual('no', self.blue_sofa_item['identifier_exists'])
|
|
|
|
def test_gmc_items_sorted_types(self):
|
|
# Furnitures / Sofas
|
|
# Furnitures / Indoor Furnitures / Indoor Sofas
|
|
furnitures_categ, sofas_categ = self._create_public_category([
|
|
{'name': 'Furnitures'},
|
|
{'name': 'Sofas', 'sequence': 1},
|
|
])
|
|
indoor_sofas_categ = self._create_public_category([
|
|
{'name': 'Indoor Furnitures', 'parent_id': furnitures_categ.id},
|
|
{'name': 'Indoor Sofas', 'sequence': 2},
|
|
])
|
|
self.public_categories = sofas_categ + indoor_sofas_categ
|
|
self.product_template_sofa.public_categ_ids = self.public_categories
|
|
|
|
self.update_items()
|
|
|
|
self.assertListEqual(
|
|
list(
|
|
name.replace('/', '>')
|
|
for name in self.public_categories.sorted('sequence').mapped('display_name')
|
|
),
|
|
self.red_sofa_item['product_type']
|
|
)
|
|
|
|
def test_gmc_items_types_limit_to_5(self):
|
|
self.product_template_sofa.write({
|
|
'public_categ_ids': [
|
|
Command.create({'name': f'Category {i}'}) for i in range(6)
|
|
]
|
|
})
|
|
|
|
self.update_items()
|
|
|
|
self.assertEqual(5, len(self.red_sofa_item['product_type']))
|
|
|
|
def test_gmc_product_variants(self):
|
|
product_one_variant = self.env['product.template'].create({
|
|
'name': 'Test product',
|
|
'attribute_line_ids': [
|
|
Command.create({
|
|
'attribute_id': attr.attribute_id.id,
|
|
'value_ids': [Command.link(attr.id)],
|
|
})
|
|
for attr in (self.color_attribute_green + self.size_attribute_l)
|
|
],
|
|
'list_price': 49.0,
|
|
'is_published': True,
|
|
}).product_variant_ids
|
|
self.products |= product_one_variant
|
|
|
|
self.update_items()
|
|
|
|
# same template
|
|
self.assertEqual(self.red_sofa_item['item_group_id'], self.blue_sofa_item['item_group_id'])
|
|
# no other variant
|
|
self.assertNotIn('item_group_id', self.items[product_one_variant])
|
|
|
|
def test_gmc_items_bundle_if_is_combo_product(self):
|
|
self.update_items()
|
|
|
|
self.assertEqual('yes', self.items[self.sofa_bundle]['is_bundle'])
|
|
self.assertEqual('no', self.red_sofa_item['is_bundle'])
|
|
|
|
def test_gmc_items_sorted_labels(self):
|
|
tags = [f'tag {i}' for i in range(3)]
|
|
self.product_template_sofa.write({
|
|
'product_tag_ids': [
|
|
Command.create({'name': tag, 'sequence': i})
|
|
for i, tag in enumerate(tags)
|
|
]
|
|
})
|
|
|
|
self.update_items()
|
|
|
|
self.assertListEqual(tags, [name for _, name in self.red_sofa_item['custom_label']])
|
|
|
|
def test_gmc_items_tags_limit_to_5(self):
|
|
self.product_template_sofa.write({
|
|
'product_tag_ids': [
|
|
Command.create({'name': f"Tag {i}", 'sequence': i})
|
|
for i in range(10)
|
|
]
|
|
})
|
|
|
|
self.update_items()
|
|
|
|
self.assertEqual(5, len(self.red_sofa_item['custom_label']))
|
|
|
|
def test_gmc_items_default_availability_in_stock(self):
|
|
self.update_items()
|
|
|
|
self.assertEqual(
|
|
'in_stock',
|
|
self.red_sofa_item['availability'],
|
|
)
|
|
|
|
def _setup_6l_water_pack(self):
|
|
self.env.user.group_ids |= self.env.ref('uom.group_uom')
|
|
uom_litre = self.env.ref('uom.product_uom_pack_6')
|
|
base_unit_litre = self.env['website.base.unit'].create({'name': 'L'})
|
|
six_pack = self.env['product.product'].create([{
|
|
'name': 'Water Pack 6L',
|
|
'list_price': 12.0,
|
|
'uom_id': uom_litre.id,
|
|
'base_unit_count': 6.0,
|
|
'base_unit_id': base_unit_litre.id,
|
|
'is_published': True,
|
|
}])
|
|
self.products |= six_pack
|
|
return six_pack
|
|
|
|
def test_gmc_items_unit_pricing_iff_product_reference_enabled(self):
|
|
six_pack = self._setup_6l_water_pack()
|
|
self.update_items()
|
|
self.assertNotIn('unit_pricing_measure', self.items[six_pack])
|
|
|
|
# enable "Product Reference Price" setting
|
|
self.env.user.group_ids |= self.env.ref('website_sale.group_show_uom_price')
|
|
self.update_items()
|
|
|
|
self.assertEqual('6.0l', self.items[six_pack]['unit_pricing_measure'], '$12 / 6l')
|
|
|
|
def test_gmc_items_dont_send_unsupported_unit(self):
|
|
six_pack = self._setup_6l_water_pack()
|
|
six_pack.base_unit_id = False # remove `L` alias -> falls back to `Pack of 6`
|
|
|
|
self.update_items()
|
|
|
|
self.assertNotIn('unit_pricing_measure', self.items[six_pack])
|