diff --git a/_extensions/redirects.py b/_extensions/redirects.py new file mode 100644 index 000000000..2022d3d04 --- /dev/null +++ b/_extensions/redirects.py @@ -0,0 +1,64 @@ +# Adapted from https://github.com/sphinx-contrib/redirects + +import os +import re +from pathlib import Path + +from sphinx.builders import html as builders +from sphinx.util import logging as logging + +TEMPLATE = '' + +logger = logging.getLogger(__name__) + +def generate_redirects(app): + path = os.path.join(app.srcdir, app.config.redirects_file) + if not os.path.exists(path): + logger.debug("Could not find redirects file at '%s'", path) + return + + source_suffix = next(iter(app.config.source_suffix)) + + if not type(app.builder) == builders.StandaloneHTMLBuilder: + logger.info("Redirects are only supported by the 'html' builder. Skipping...") + return + + with open(path) as redirects: + escaped_source_suffix = source_suffix.replace('.', '\.') + pattern = re.compile( + r'^[ \t]*([\w\-/]+{0})[ \t]+([\w\-/]+{0})[ \t]*(#.*)?$'.format(escaped_source_suffix) + ) + for line in redirects.readlines(): + # Exclude comment or empty lines + if not line.rstrip() or line.startswith('#'): + continue + + match_result = pattern.match(line) + + # Log malformed rules + if not match_result: + logger.error( + "Ignoring malformed redirection: {0}" + "Please use this format: old_page{1} new_page{1} # optional comment".format( + line, source_suffix) + ) + continue + + # Parse the rule + from_file, to_file, _ = match_result.groups() + logger.debug("Redirecting '%s' to '%s'", from_file, to_file) + + # Prepare source and destination paths + to_path_prefix = '../' * from_file.count('/') + from_html_file = from_file.replace(source_suffix, '.html') + to_html_file = to_path_prefix + to_file.replace(source_suffix, '.html') + absolute_from_path = Path(app.builder.outdir) / from_html_file + + # Create the redirection + absolute_from_path.parent.mkdir(parents=True, exist_ok=True) + absolute_from_path.write_text(TEMPLATE % to_html_file) + + +def setup(app): + app.add_config_value('redirects_file', 'redirects', 'env') + app.connect('builder-inited', generate_redirects) diff --git a/conf.py b/conf.py index 590f457e0..928195b1c 100644 --- a/conf.py +++ b/conf.py @@ -31,10 +31,11 @@ extensions = [ 'sphinx.ext.ifconfig', 'sphinx.ext.todo', 'odoo', - 'html_domain', 'demo_link', - 'github_link', 'embedded_video', + 'github_link', + 'html_domain', + 'redirects', ] # Add any paths that contain templates here, relative to this directory. @@ -81,6 +82,9 @@ exclude_patterns = [ 'bin', 'include', 'lib', ] +# The specifications of redirect rules used by the redirects extension. +redirects_file = 'redirects.txt' + # The reST default role (used for this markup: `text`) to use for all # documents. #default_role = None diff --git a/point_of_sale/advanced_pricing_features.rst b/point_of_sale/advanced_pricing_features.rst index 397059135..b20a2407a 100644 --- a/point_of_sale/advanced_pricing_features.rst +++ b/point_of_sale/advanced_pricing_features.rst @@ -9,4 +9,4 @@ Pricing Features advanced_pricing_features/seasonal_discount advanced_pricing_features/discount_tags advanced_pricing_features/loyalty - + advanced_pricing_features/pricelists diff --git a/point_of_sale/advanced_pricing_features/media/pricelists_01.png b/point_of_sale/advanced_pricing_features/media/pricelists_01.png new file mode 100644 index 000000000..7d35294e7 Binary files /dev/null and b/point_of_sale/advanced_pricing_features/media/pricelists_01.png differ diff --git a/point_of_sale/advanced_pricing_features/media/pricelists_02.png b/point_of_sale/advanced_pricing_features/media/pricelists_02.png new file mode 100644 index 000000000..ef820a2a7 Binary files /dev/null and b/point_of_sale/advanced_pricing_features/media/pricelists_02.png differ diff --git a/point_of_sale/advanced_pricing_features/media/pricelists_03.png b/point_of_sale/advanced_pricing_features/media/pricelists_03.png new file mode 100644 index 000000000..7d64b3122 Binary files /dev/null and b/point_of_sale/advanced_pricing_features/media/pricelists_03.png differ diff --git a/point_of_sale/advanced_pricing_features/media/pricelists_04.png b/point_of_sale/advanced_pricing_features/media/pricelists_04.png new file mode 100644 index 000000000..6ab412154 Binary files /dev/null and b/point_of_sale/advanced_pricing_features/media/pricelists_04.png differ diff --git a/point_of_sale/advanced_pricing_features/pricelists.rst b/point_of_sale/advanced_pricing_features/pricelists.rst new file mode 100644 index 000000000..60a7d82f1 --- /dev/null +++ b/point_of_sale/advanced_pricing_features/pricelists.rst @@ -0,0 +1,46 @@ +================================= +Using Pricelists in Point of Sale +================================= + +You probably know the concept of happy hour: during a certain period of +time, the barman gives a discount on some drinks (usually 50% off or a +buy one get one free). When the period is over, prices go back to +normal. But how does that relate with Odoo? + +In Odoo, you can set up happy hours. It’s one of the many possible uses +of *Pricelists*. Those *Pricelists* allow the creation of +multiple prices for the same product: a regular one and a special one +for happy hours. Available in the *PoS* app, those are really +convenient. + +Set up Pricelists +================= + +To set up a *Pricelist*, go to :menuselection:`Point of Sale --> Configuration --> Configuration` +and enable the *Pricelist* feature. Then, go to :menuselection:`Point of Sale --> Configuration +--> Point of Sale` and enable *Pricelist* for the *PoS*. + +.. image:: media/pricelists_01.png + :align: center + +Now, you can create *Pricelists* by clicking on the *Pricelists* link. +Then, set it up by choosing the product category you want to include in your happy hour +and the discount. + +.. image:: media/pricelists_02.png + :align: center + +Go back to your *PoS* settings and add the Happy Hour pricelist to the +list. You can even choose a default pricelist if needed. + +.. image:: media/pricelists_03.png + :align: center + +From now on, on the *PoS* interface, a new button is available, allowing you to choose +among the different *pricelists* you added before. + +.. image:: media/pricelists_04.png + :align: center + +.. seealso:: + * :doc:`../../sales/products_prices/prices/pricing` \ No newline at end of file diff --git a/redirects.txt b/redirects.txt new file mode 100644 index 000000000..09855004d --- /dev/null +++ b/redirects.txt @@ -0,0 +1,38 @@ +# REDIRECT RULES # + +# Each line in this file specifies a redirect rule that redirects users from one URL to another. +# +# Redirect rules must follow this pattern: old_file.rst new_file.rst # optional comment +# Both parts are file paths and must thus include the full path of the file starting from the root +# of the documentation to the file name, including the .rst extension. +# If you consider it necessary, add a comment after the symbol '#' to explain why the redirection is +# needed. +# +# A redirect rule must be added to this file in the following cases: +# +# 1. An RST file is moved from one location to another. +# Example: The TOC of the Sales app is moved into a file index.rst located in sales/ . +# Rule: sales.rst sales/index.rst +# +# 2. An RST file is renamed. +# Example: The file create_quotations.rst in sales/ is renamed to quotations.rst. +# Rule: sales/create_quotations.rst sales/quotations.rst # no longer limited to creating quotes +# +# 3. Another pertinent case. +# Example: The file open_order_line_popup.rst is removed from sales/ in 13.0. +# Rule (13.0 only): sales/open_order_line_popup.rst sales/orders.rst # feature replaced in 13.0 +# +# Note that if the old file was already present in previous versions, the rule needs to be added +# from the branch of the lowest of those versions (usually 11.0) to allow the version switcher to +# land on the correct page (the redirection will be duplicated in other branches). + + +# Redirections taking effect as of 11.0 : + + + +# Redirections taking effect as of 12.0 : + + + +# Redirections taking effect as of 13.0 :