[MERGE] Forward-port of 12.0 to 13.0
This commit is contained in:
commit
9e75cc33c4
64
_extensions/redirects.py
Normal file
64
_extensions/redirects.py
Normal file
@ -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 = '<html><head><meta http-equiv="refresh" content="0; url=%s"/></head></html>'
|
||||||
|
|
||||||
|
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)
|
8
conf.py
8
conf.py
@ -31,10 +31,11 @@ extensions = [
|
|||||||
'sphinx.ext.ifconfig',
|
'sphinx.ext.ifconfig',
|
||||||
'sphinx.ext.todo',
|
'sphinx.ext.todo',
|
||||||
'odoo',
|
'odoo',
|
||||||
'html_domain',
|
|
||||||
'demo_link',
|
'demo_link',
|
||||||
'github_link',
|
|
||||||
'embedded_video',
|
'embedded_video',
|
||||||
|
'github_link',
|
||||||
|
'html_domain',
|
||||||
|
'redirects',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
@ -81,6 +82,9 @@ exclude_patterns = [
|
|||||||
'bin', 'include', 'lib',
|
'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
|
# The reST default role (used for this markup: `text`) to use for all
|
||||||
# documents.
|
# documents.
|
||||||
#default_role = None
|
#default_role = None
|
||||||
|
@ -9,4 +9,4 @@ Pricing Features
|
|||||||
advanced_pricing_features/seasonal_discount
|
advanced_pricing_features/seasonal_discount
|
||||||
advanced_pricing_features/discount_tags
|
advanced_pricing_features/discount_tags
|
||||||
advanced_pricing_features/loyalty
|
advanced_pricing_features/loyalty
|
||||||
|
advanced_pricing_features/pricelists
|
||||||
|
BIN
point_of_sale/advanced_pricing_features/media/pricelists_01.png
Normal file
BIN
point_of_sale/advanced_pricing_features/media/pricelists_01.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
BIN
point_of_sale/advanced_pricing_features/media/pricelists_02.png
Normal file
BIN
point_of_sale/advanced_pricing_features/media/pricelists_02.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.8 KiB |
BIN
point_of_sale/advanced_pricing_features/media/pricelists_03.png
Normal file
BIN
point_of_sale/advanced_pricing_features/media/pricelists_03.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 18 KiB |
BIN
point_of_sale/advanced_pricing_features/media/pricelists_04.png
Normal file
BIN
point_of_sale/advanced_pricing_features/media/pricelists_04.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
46
point_of_sale/advanced_pricing_features/pricelists.rst
Normal file
46
point_of_sale/advanced_pricing_features/pricelists.rst
Normal file
@ -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`
|
38
redirects.txt
Normal file
38
redirects.txt
Normal file
@ -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 :
|
Loading…
Reference in New Issue
Block a user