Compare commits

..

1 Commits

Author SHA1 Message Date
Jonathan
bf48e5ba5c [MOV] pos: restructuration of pos toctree
task-3284514
2023-04-21 17:48:33 +02:00
82 changed files with 314 additions and 2068 deletions

View File

@@ -43,7 +43,7 @@ API permissions
---------------
The :guilabel:`API permissions` should be set next. Odoo will need specific API permissions to be
able to read (IMAP) and send (SMTP) emails in the Microsoft 365 setup. First, click the
able to read (IMAP) and send (IMAP) emails in the Microsoft 365 setup. First, click the
:guilabel:`API permissions` link, located in the left menu bar. Next, click on the
:guilabel:`(+) Add a Permission` button and select :guilabel:`Microsoft Graph` under
:guilabel:`Commonly Used Microsoft APIs`. After, select the :guilabel:`Delegated Permissions`

View File

@@ -21,87 +21,64 @@ Setup in Google
Create a new project
--------------------
To get started, go to the `Google API Console <https://console.developers.google.com>`_. Log in
with your *Google Workspace* account if you have one, otherwise log in with your personal Gmail
account (this should match the email address you want to configure in Odoo).
To get started, go to the `Google API Platform
<https://console.cloud.google.com/apis/credentials/consent>`_. Log in with your *Google Workspace*
account if you have one, otherwise log in with your personal Gmail account (this should match the
email address you want to configure in Odoo).
After that, click on :guilabel:`Create Project`, located on the far right of the :guilabel:`OAuth
consent screen`. If a project has already been created in this account, then the :guilabel:`New
Project` option will be located on the top right under the :guilabel:`Select a project` drop-down
menu.
After that, click on :guilabel:`Create Project`, located on the far right of the OAuth consent
screen. If a project has already been created in this account, then the :guilabel:`New Project`
option will be located on the top left under the :guilabel:`Select a project` drop-down menu.
On the :menuselection:`New Project` screen, rename the :guilabel:`Project name` to `Odoo` and
browse for the :guilabel:`Location`. Set the :guilabel:`Location` as the *Google Workspace
organization*. If you are using a personal Gmail account, then leave the :guilabel:`Location` as
:guilabel:`No Organization`.
On the :guilabel:`New Project` screen, rename the :guilabel:`Project name` to `Odoo` and browse for
the :guilabel:`Location`. Set the :guilabel:`Location` as the `Google Workspace` organization. If
you are using a personal Gmail account, then leave the :guilabel:`Location` as `No Organization`.
.. image:: google_oauth/new-project.png
:align: center
:alt: Project Name and Location for Google OAuth.
:alt: Project Name and Location for Google Oauth.
Click on :guilabel:`Create` to finish this step.
OAuth consent screen
--------------------
If the page doesn't redirect to the :menuselection:`User Type` options, click on :guilabel:`OAuth
consent screen` in the left menu.
Under :guilabel:`User Type` options, select the appropriate :guilabel:`User Type`, and then click on
:guilabel:`Create` again, which will finally navigate to the :menuselection:`Edit app registration`
page.
.. warning::
*Personal* Gmail Accounts are only allowed to be **External** User Type, which means Google may
require an approval, or for *Scopes* to be added on. However, using a *Google WorkSpace* account
allows for **Internal** User Type to be used.
Note, as well, that while the API connection is in the *External* testing mode, then no approval is
necessary from Google. User limits in this testing mode is set to 100 users.
Click on :guilabel:`Create` to finish this step. On the next screen, :guilabel:`User Type` options,
select the :guilabel:`External` option, and then click on :guilabel:`Create` again, which will
finally navigate to the :guilabel:`Edit app registration` page.
Edit app registration
---------------------
Next we will configure the app registration of the project.
On the :guilabel:`OAuth consent screen` step, under the :guilabel:`App information` section, enter
`Odoo` in the :guilabel:`App name` field. Select the organization's email address under the
:guilabel:`User support` email field.
Next, under :menuselection:`App Domain --> Authorized domains`, click on :guilabel:`Add Domain` and
enter `odoo.com`.
After that, under the :guilabel:`Developer contact information` section, enter the organization's
email address. Google uses this email address to notify the organization about any changes to your
project.
Next, click on the :guilabel:`Save and Continue` button. Then, skip the :menuselection:`Scopes` page
by scrolling to the bottom and clicking on :guilabel:`Save and Continue`.
If continuing in testing mode (External), add the email addresses being configured under the
:guilabel:`Test users` step, by clicking on :guilabel:`Add Users`, and then the :guilabel:`Save and
Continue` button. A summary of the app registration appears.
Finally, scroll to the bottom and click on :guilabel:`Back to Dashboard` to finish setting up the
project.
- On the :guilabel:`Oauth consent screen` step, under the :guilabel:`App information` section,
enter `Odoo` in the :guilabel:`App name` field. Select the organization's email address under the
:guilabel:`User support` email field.
- Next, under :menuselection:`App Domain --> Authorized domains`, click on :guilabel:`Add Domain`
and enter `odoo.com`.
- After that, under the :guilabel:`Developer contact information` section, enter the organization's
email address. Google uses this email address to notify the organization about any changes to
your project.
- Next, click on the :guilabel:`Save and Continue` button.
- Then, skip the :guilabel:`Scopes` page by scrolling to the bottom and clicking on
:guilabel:`Save and Continue`.
- Next, add the email being configured under the :guilabel:`Test users` step by clicking on
:guilabel:`Add Users` and then the :guilabel:`Save and Continue` button. A summary of the
:guilabel:`App registration` appears.
- Finally, scroll to the bottom and click on :guilabel:`Back to Dashboard`.
Create Credentials
------------------
Now that the project is set up, credentials should be created, which includes the *Client ID* and
*Client Secret*. First, click on :guilabel:`Credentials` in the left sidebar menu.
Now that you have set up the project, you need to create credentials, which includes the
:guilabel:`Client ID` and :guilabel:`Client Secret`. First, click on :guilabel:`Credentials` in the
left sidebar menu.
Then, click on :guilabel:`Create Credentials` in the top menu and select :guilabel:`OAuth client ID`
from the dropdown menu.
Then, click on :guilabel:`Create Credentials` in the top menu and select
:guilabel:`OAuth client ID` from the dropdown menu.
- Under :guilabel:`Application Type`, select :guilabel:`Web Application` from the dropdown menu.
- In the :guilabel:`Name` field, enter `Odoo`.
- In the :guilabel:`Client ID` field, enter `Odoo`.
- Under the :guilabel:`Authorized redirect URIs` label, click the button :guilabel:`ADD URI`, and
then input `https://yourdbname.odoo.com/google_gmail/confirm` in the :guilabel:`URIs 1` field.
Be sure to replace the *yourdbname* part of the URL with the actual Odoo database name.
- Next, click on :guilabel:`Create` to generate an OAuth :guilabel:`Client ID` and :guilabel:`Client
Secret`. Finally, copy each generated value for later use when configuring in Odoo, and then
navigate to the Odoo database.
then input `https://yourdbname.odoo.com/google_gmail/confirm` in the :guilabel:`URIs 1` field. Be
sure to replace the *yourdbname* part of the URL with your actual Odoo database name.
- Next, click on :guilabel:`Create` to generate an OAuth :guilabel:`Client ID` and
:guilabel:`Client Secret`. Finally, copy each generated value for later use when configuring in
Odoo, and then navigate to the Odoo database.
.. image:: google_oauth/client-credentials.png
:align: center
@@ -114,37 +91,32 @@ Enter Google Credentials
------------------------
First, open Odoo and navigate to the :guilabel:`Apps` module. Then, remove the :guilabel:`Apps`
filter from the search bar and type in `Google`. Install the module called :guilabel:`Google
Gmail`.
filter from the search bar and type in `Google`. Install the module called :guilabel:`Google Gmail`.
Next, navigate to :menuselection:`Settings --> General Settings`, and under the :guilabel:`Discuss`
section, ensure that the checkbox for :guilabel:`Custom Email Servers` or :guilabel:`External Email
Servers` is checked. This populates a new option for :guilabel:`Gmail Credentials` or :guilabel:`Use
a Gmail Sever`. Then, copy and paste the respective values into the :guilabel:`Client ID` and
:guilabel:`Client Secret` fields and :guilabel:`Save` the settings.
section, ensure that the checkbox for :guilabel:`Custom Email Servers` is checked. This populates a
new option for :guilabel:`Gmail Credentials`. Then, copy and paste the :guilabel:`Client ID` and
:guilabel:`Client Secret` into the respective fields and :guilabel:`Save` the settings.
Configure outgoing email server
-------------------------------
To configure the external Gmail account, return to the top of the :guilabel:`Custom Email Servers`
setting and then click the :guilabel:`Outgoing Email Servers` link.
After that, on the :guilabel:`General Settings` page, under :guilabel:`Custom Email Servers`, click
:guilabel:`Outgoing Email Servers` to configure the external Gmail account.
.. image:: google_oauth/outgoing-servers.png
:align: center
:alt: Configure Outgoing Email Servers in Odoo.
Then, click on :guilabel:`New` or :guilabel:`Create` to create a new email server, and fill in the
:guilabel:`Name`, :guilabel:`Description`, and the email :guilabel:`Username` (if required).
Then, :guilabel:`Create` a new email server and select the option for :guilabel:`Gmail`. Next, fill
in the :guilabel:`Description` (can be anything) and the email :guilabel:`Username` and click on
:guilabel:`Connect your Gmail account`.
Next, click on :guilabel:`Gmail OAuth Authentication` or :guilabel:`Gmail` (under the
:guilabel:`Authenticate with` or :guilabel:`Connection` section). Finally, click on
:guilabel:`Connect your Gmail Account`.
A new window labeled :guilabel:`Google` opens to complete the authorization process. Select the
A new window from :guilabel:`Google` opens to complete the authorization process. Select the
appropriate email address that is being configured in Odoo.
If the email address is a personal account, then an extra step pops up, so click
:guilabel:`Continue` to allow the verification and connect the Gmail account to Odoo.
If the email address is a personal account, an extra step pops up, click :guilabel:`Continue` to
allow the verification and connect the Gmail account to Odoo.
Then, allow Odoo to access the Google account by clicking on :guilabel:`Continue` or
:guilabel:`Allow`. After that, the page navigates back to the newly configured outgoing email
@@ -155,8 +127,9 @@ server in Odoo. The configuration automatically loads the token in Odoo, and a t
:align: center
:alt: Configure Outgoing Email Servers in Odoo.
Finally, :guilabel:`Test the Connection`. A confirmation message should appear. The Odoo database
can now send safe, secure emails through Google using OAuth authentication.
Finally, save the settings and :guilabel:`Test the Connection`. A confirmation message should
appear. The Odoo database can now send safe, secure emails through Google using OAuth
authentication.
Google OAuth FAQ
================
@@ -164,8 +137,8 @@ Google OAuth FAQ
Production VS Testing Publishing Status
---------------------------------------
Choosing :guilabel:`Production` as the :guilabel:`Publishing Status` (instead of
:guilabel:`Testing`) will display the following warning message:
Choosing :guilabel:`Production` as the :guilabel:`Publishing Status` (instead of Testing) will
display the following warning message:
.. image:: google_oauth/published-status.png
:align: center
@@ -185,35 +158,39 @@ populate.
:align: center
:alt: 403 Access Denied Error.
To correct this error, return to the :guilabel:`OAuth consent screen` under :guilabel:`APIs &
Services` and add test user(s) to the app. Add the email that you are configuring in Odoo.
To correct this error, return to the :guilabel:`OAuth consent screen` under
:guilabel:`APIs & Services` and add test user(s) to the app. Add the email that you are configuring
in Odoo.
Gmail Module not updated
------------------------
If the *Google Gmail* module in Odoo has not been updated to the latest version, then a
If the :guilabel:`Gmail Module` in Odoo has not been updated to the latest version, then a
:guilabel:`Forbidden` error message populates.
.. image:: google_oauth/forbidden-error.png
:align: center
:alt: Forbidden you don't have the permission to access the requested resource.
To correct this error, go to the :menuselection:`Apps` module and clear out the search terms. Then,
search for `Gmail` or `Google` and upgrade the :guilabel:`Google Gmail` module. Finally, click
on the three dots on the upper right of the module and select :guilabel:`Upgrade`.
To correct this error, go to the :guilabel:`Apps` module and clear out the search terms. Then,
search for `Gmail` or `Google` and upgrade the :guilabel:`Google Gmail` module. Finally, click on
the three dots on the upper right of the module and select :guilabel:`Upgrade`.
Application Type
----------------
When creating the credentials (OAuth *Client ID* and *Client Secret*), if :guilabel:`Desktop App` is
selected for the :guilabel:`Application Type`, an :guilabel:`Authorization Error` appears.
When creating the :guilabel:`Credentials` (OAuth Client ID and Client Secret), if
:guilabel:`Desktop App` is selected for the :guilabel:`Application Type`, an
:guilabel:`Authorization Error` appears.
.. image:: google_oauth/error-400.png
:align: center
:alt: Error 400 Redirect URI Mismatch.
To correct this error, delete the credentials already created and create new credentials, selecting
:guilabel:`Web Application` for the :guilabel:`Application Type`. Then, under :guilabel:`Authorized
redirect URIs`, click :guilabel:`ADD URI` and type:
`https://yourdbname.odoo.com/google_gmail/confirm` in the field, being sure to replace *yourdbname*
in the URL with the Odoo database name.
:guilabel:`Web Application` for the :guilabel:`Application Type`. Then, under
:guilabel:`Authorized redirect URIs`, click :guilabel:`ADD URI` and type:
`https://yourdbname.odoo.com/google_gmail/confirm` in the field.
.. note::
Replace *yourdbname* in the URL with the Odoo database name.

View File

@@ -2,14 +2,14 @@
Google Sign-In Authentication
=============================
The *Google Sign-In Authentication* is a useful function that allows Odoo users to sign in to their
database with their Google account.
The **Google Sign-In Authentication** is a useful function that allows your users to sign in to Odoo
with their Google account.
This is particularly helpful if the organization uses Google Workspace, and wants employees within
the organization to connect to Odoo using their Google Accounts.
This is particularly helpful if your organization uses Google Workforce and you want the employees
within your organization to connect to Odoo with their Google Accounts.
.. seealso::
- :doc:`/applications/productivity/calendar/google`
- :doc:`../../productivity/calendar/google`
- :doc:`/administration/maintain/google_oauth`
.. _google-sign-in/configuration:
@@ -17,7 +17,7 @@ the organization to connect to Odoo using their Google Accounts.
Configuration
=============
The integration of the Google sign-in function requires configuration both on Google *and* Odoo.
The integration of the Google sign-in function requires configuration both on Google and on Odoo.
.. _google-sign-in/api:
@@ -25,16 +25,15 @@ Google API Dashboard
--------------------
#. Go to the `Google API Dashboard <https://console.developers.google.com/>`_.
#. Make sure the right project is opened. If there isn't a project yet, click on :guilabel:`Create
Project`, fill out the project name and other details of the company, and click on
:guilabel:`Create`.
#. Make sure the right project is opened. If you don't have a project yet, click on *Create
Project*, fill out the project name and other details of your company, and click on *Create*.
.. image:: google/new-project-details.png
:align: center
:alt: Filling out the details of a new project.
:alt: Filling out the details of a new project
.. tip::
Choose the name of the company from the drop-down menu.
Choose the name of your own company from the drop-down menu.
.. _google-sign-in/oauth:
@@ -45,30 +44,16 @@ OAuth consent screen
.. image:: google/consent-selection.png
:align: center
:alt: Google OAuth consent selection menu.
:alt: Google oauth consent selection menu
#. Choose one of the options (:guilabel:`Internal` / :guilabel:`External`), and click on
:guilabel:`Create`.
#. Choose the option for :guilabel:`internal`, and click on :guilabel:`Create`.
.. image:: google/consent.png
:align: center
:alt: Choice of a user type in OAuth consent.
:alt: Choice of a user type in oauth consent
.. warning::
*Personal* Gmail Accounts are only allowed to be **External** User Type, which means Google
may require an approval, or for *Scopes* to be added on. However, using a *Google WorkSpace*
account allows for **Internal** User Type to be used.
Note, as well, that while the API connection is in the *External* testing mode, then no
approval is necessary from Google. User limits in this testing mode is set to 100 users.
#. Fill out the required details and domain info, then click on :guilabel:`Save and Continue`.
#. On the :menuselection:`Scopes` page, leave all fields as is, and click on :guilabel:`Save and
Continue`.
#. Next, if continuing in testing mode (*External*), add the email addresses being configured under
the :guilabel:`Test users` step by clicking on :guilabel:`Add Users`, and then the
:guilabel:`Save and Continue` button. A summary of the app registration appears.
#. Finally, scroll to the bottom, and click on :guilabel:`Back to Dashboard`.
#. Fill out your details and domain info, then click on *Save and Continue*.
#. On the **Scopes** page, leave all fields as is, and click on *Save and Continue*.
.. _google-sign-in/credentials:
@@ -79,24 +64,24 @@ Credentials
.. image:: google/credentials-button.png
:align: center
:alt: Credentials button menu.
:alt: Credentials button menu
#. Click on :guilabel:`Create Credentials`, and select :guilabel:`OAuth client ID`.
#. Click on *Create Credentials* and select **OAuth client ID**.
.. image:: google/client-id.png
:align: center
:alt: OAuth client id selection.
:alt: Oauth client id selection
#. Select :guilabel:`Web Application` as the :guilabel:`Application Type`. Now, configure the
allowed pages on which Odoo will be redirected.
#. Select **Web Application** as the Application type. Now configure the allowed pages on which you
will be redirected.
In order to achieve this, in the :guilabel:`Authorized redirect URIs` field, enter the database's
domain immediately followed by `/auth_oauth/signin`. For example:
`https://mydomain.odoo.com/auth_oauth/signin`, then click on :guilabel:`Create`.
In order to achieve this, in the **Authorized redirect URIs** field, enter your database's domain
immediately followed by ``/auth_oauth/signin``. For example:
``https://mydomain.odoo.com/auth_oauth/signin``, then click on *Create*.
#. Now that the *OAuth client* has been created, a screen will appear with the :guilabel:`Client ID`
and :guilabel:`Client Secret`. Copy the :guilabel:`Client ID` for later, as it will be necessary
for the configuration in Odoo, which will be covered in the following steps.
.. image:: google/create-client-id.png
:align: center
:alt: Creating oauth client id
.. _google-sign-in/auth-odoo:
@@ -108,53 +93,47 @@ Google Authentication on Odoo
Retrieve the Client ID
~~~~~~~~~~~~~~~~~~~~~~
Once the previous steps are complete, two keys are generated on the Google API Dashboard:
:guilabel:`Client ID` and :guilabel:`Client Secret`. Copy the :guilabel:`Client ID`.
Once you have done the previous steps, two keys are generated on the Google API Dashboard: *Client
ID* and *Client Secret*. Copy the *Client ID*.
.. image:: google/secret-ids.png
:align: center
:alt: Google OAuth Client ID generated.
:alt: Google OAuth Client ID generated
.. _google-sign-in/odoo-activation:
Odoo activation
~~~~~~~~~~~~~~~
#. Go to :menuselection:`Odoo General Settings --> Integrations` and activate :guilabel:`OAuth
Authentication`.
#. Go to :menuselection:`Odoo General Settings --> Integrations` and activate **OAuth
Authentication**.
.. note::
Odoo may prompt the user to log-in again after this step.
You may have to log in again after this step.
#. Go back to :menuselection:`General Settings --> Integrations --> OAuth Authentication`, activate
the selection and :guilabel:`Save`. Next, return to :menuselection:`General Settings -->
Integrations --> Google Authentication` and activate the selection. Then fill out the
:guilabel:`Client ID` with the key from the Google API Dashboard, and :guilabel:`Save`.
#. Go back to :menuselection:`General Settings --> Integrations`, activate **Google
Authentication**, then fill out the *Client ID* with the key from the Google API Dashboard, and
*Save*.
.. image:: google/odoo-client-id.png
:align: center
:alt: Filling out the client id in Odoo settings.
.. note::
Google OAuth2 configuration can also be accessed by clicking on :guilabel:`OAuth Providers`
under the :guilabel:`OAuth Authentication` heading in :menuselection:`Integrations`.
:alt: Filling out the client id in Odoo settings
.. _google-sign-in/log-in:
Log in to Odoo with Google
==========================
To link the Google account to the Odoo profile, click on :guilabel:`Log in with Google` when first
logging into Odoo.
To link your Google account to your Odoo profile, click on *Log in with Google* when you are asked
to choose a new password.
.. image:: google/first-login.png
:align: center
:alt: Reset password screen with "Log in with Google" button.
:alt: Reset password screen with "Log in with Google" button
Existing users must :ref:`reset their password <users/reset-password>` to access the
:menuselection:`Reset Password` page, while new users can directly click on :guilabel:`Log in with
Google`, instead of choosing a new password.
Existing users must :ref:`reset their password <users/reset-password>` to access the *reset
password* page, while new users can directly click on *Log in with Google* instead of choosing a new
password.
.. seealso::
- `Google Cloud Platform Console Help - Setting up OAuth 2.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.7 KiB

View File

@@ -10,4 +10,3 @@ Warehouses
warehouses/difference_warehouse_location
warehouses/warehouse_replenishment_transfer
warehouses/create_a_second_warehouse

View File

@@ -1,100 +0,0 @@
=========================
Create a second warehouse
=========================
A *warehouse* is a physical building or space where items are stored. In Odoo, it is possible to set
up multiple warehouses and transfer stored items between them.
By default, the Odoo platform has one warehouse that is already configured, with the address set as
the company's address. To create a second warehouse, select :menuselection:`Configuration -->
Warehouses`, then click :guilabel:`Create` and configure the form as follows:
- :guilabel:`Warehouse`: the full name of the warehouse
- :guilabel:`Short Name`: the abbreviated code by which the warehouse is referred to; the short name
for the default warehouse in Odoo is **WH**
- :guilabel:`Company`: the company that owns the warehouse; this can be set as the company that owns
the Odoo database or the company of a customer or vendor
- :guilabel:`Address`: the address where the warehouse is located
.. important::
The options below will only appear if the :guilabel:`Multi-Step Routes` checkbox is enabled in
:menuselection:`Configuration --> Settings` under the :guilabel:`Warehouse` heading. For more
information about routes and how they work in Odoo, see :ref:`Using Routes and Pull/Push Rules
<use-routes>`.
- :guilabel:`Incoming/Outgoing Shipments`: select the routes that incoming and outgoing shipments
should follow
- :guilabel:`Resupply Subcontractors`: allow subcontractors to be resupplied from this warehouse
- :guilabel:`Manufacture to Resupply`: allow for items to be manufactured in this warehouse
- :guilabel:`Manufacture`: select the route that should be followed when manufacturing goods inside
the warehouse
- :guilabel:`Buy to Resupply`: check the box to allow for purchased products to be delivered to the
warehouse
- :guilabel:`Resupply From`: select warehouses that can be used to resupply the warehouse being
created
.. image:: create_a_second_warehouse/new-warehouse-configuration.png
:align: center
:alt: A filled out form for creating a new warehouse.
.. important::
Creating a second warehouse will automatically enable the *Storage Locations* setting, which
allows location tracking of products within a warehouse. To toggle this setting, navigate to
:menuselection:`Configuration --> Settings` and click the checkbox under the
:guilabel:`Warehouse` heading.
After filling out the form, click :guilabel:`Save` and the new warehouse will be created.
Add inventory to a new warehouse
================================
If a new warehouse is created that has existing inventory in it, the inventory counts should be
added to Odoo so that the stock listed in the Odoo database reflects what is in the physical
warehouse. To add inventory to a new warehouse, navigate to :menuselection:`Inventory -->
Operations --> Inventory Adjustments`, and then click :guilabel:`Create`. The inventory adjustment
form can then be filled out as follows:
- :guilabel:`Inventory Reference`: the name or code that the inventory adjustment can be referred to
by
- :guilabel:`Locations`: the location(s) where the inventory is stored; include the new warehouse
and any locations within it that inventory will be added to
- :guilabel:`Products`: include all products that will be added to inventory or leave blank to
select any product during the next step
- :guilabel:`Include Exhausted Products`: include products with a quantity of zero; does not affect
inventory adjustments for new warehouses since they have no existing inventory
- :guilabel:`Accounting Date`: the date used by accounting teams for bookkeeping related to the
inventory
- :guilabel:`Company`: the company that owns the inventory; can be set as the user's company or as a
customer or vendor
- :guilabel:`Counted Quantities`: choose whether the counted quantities for products being added
should default to stock on hand or zero; does not affect inventory adjustments for new warehouses
since they have no existing inventory
.. image:: create_a_second_warehouse/inventory-adjustment-configuration.png
:align: center
:alt: A filled out form for an inventory adjustment.
Once the form is properly configured, click on :guilabel:`Start Inventory` to be taken to the next
page where products can be added to the inventory adjustment. Add a new product by clicking on
:guilabel:`Create` and then fill out the product line as follows:
- :guilabel:`Product`: the product being added to inventory
- :guilabel:`Location`: the location where the product is currently stored in the new warehouse;
this can be set as the overall warehouse or a location within the warehouse
- :guilabel:`Lot/Serial Number`: the lot that the product belongs to or the serial number used to
identify it
- :guilabel:`On Hand`: the total quantity of the product stored in the location for which inventory
is being adjusted; this should be zero for a new location or warehouse
- :guilabel:`Counted`: the amount of the product that is being added to inventory
- :guilabel:`Difference`: the difference between the *On Hand* and *Counted* values; this will
automatically update to reflect the value entered in the :guilabel:`Counted` column
- :guilabel:`UoM`: the unit of measure used for counting the product
.. image:: create_a_second_warehouse/product-line-configuration.png
:align: center
:alt: Include a line for each product being added to inventory.
After adding all the products already stored in the new warehouse, click :guilabel:`Validate
Inventory` to complete the inventory adjustment. The values in the :guilabel:`On Hand` column will
update to reflect those in the :guilabel:`Counted` column and the products added will appear in the
inventory of the new warehouse.

View File

@@ -1,198 +1,47 @@
===========================================================
Sell stock from multiple warehouses using virtual locations
===========================================================
While keeping stock and selling inventory from one warehouse might work for smaller companies,
bigger companies might need to keep stock in, or sell from, multiple warehouses in multiple
locations.
In Odoo, sometimes products included in a single sales order might take stock from two (or more)
warehouses. In Odoo, pulling products from multiple warehouses to satisfy sales demands can be done
by using *virtual locations*.
.. note::
In order to create virtual locations in warehouses and proceed to the following steps,
the :guilabel:`Storage Locations` and :guilabel:`Multi-Step Routes` features will need to be
enabled in the :menuselection:`Settings` app.
To do so, go to :menuselection:`Inventory --> Configuration --> Settings`, scroll down to the
:guilabel:`Warehouse` section, and click the checkboxes next to :guilabel:`Storage Locations`
and :guilabel:`Multi-Step Routes`. Then, :guilabel:`Save` the changes to finish.
Create and configure a virtual parent location
==============================================
Before creating any virtual stock locations, a new warehouse will need to be created. This new
warehouse will act as a *virtual* warehouse, and will be the *parent* location of other physical
warehouses.
.. spoiler:: Why a "virtual" warehouse?
Virtual warehouses are great for companies with multiple physical warehouses. This is because
a situation might arise when one warehouse runs out of stock of a particular product, but
another warehouse still has stock on-hand. In this case, stock from these two (or more)
warehouses could be used to fulfill a single sales order.
The "virtual" warehouse acts as a single aggregator of all the inventory stored in a company's
physical warehouses, and is used (for traceability purposes) to create a hierarchy of locations
in Odoo.
Create a new warehouse
----------------------
To create a new warehouse, go to :menuselection:`Inventory --> Configuration --> Warehouses`, and
click :guilabel:`Create`. From here, the warehouse :guilabel:`Name` and :guilabel:`Short Name` can
be changed, and other warehouse details can be changed under the :guilabel:`Warehouse Configuration`
tab.
Under the :guilabel:`Shipments` heading, set the number of steps used to process :guilabel:`Incoming
Shipments` and :guilabel:`Outgoing Shipments` by selecting between the :guilabel:`1 step`,
:guilabel:`2 steps`, and :guilabel:`3 steps` radio buttons. The desired option for
:guilabel:`Incoming Shipments` and :guilabel:`Outgoing Shipments` will depend on the warehouse's
procurement process, and might differ for individual products or product categories.
.. seealso::
- :doc:`How to choose the right flow to handle receipts?
</applications/inventory_and_mrp/inventory/management/incoming/handle_receipts>`
- :doc:`How to choose the right inventory flow to handle delivery orders?
</applications/inventory_and_mrp/inventory/management/delivery/inventory_flow>`
Under the :guilabel:`Resupply` heading, configure the method(s) for how the warehouse resupplies
its inventory:
- :guilabel:`Resupply Subcontractors`: resupply subcontractors with components from this warehouse.
- :guilabel:`Manufacture to Resupply`: when products are manufactured, they can be manufactured in
this warehouse.
- :guilabel:`Manufacture`: to produce right away, move the components to the production location
directly and start the manufacturing process; to pick first and then produce, unload the
components from the stock to input location first, and then transfer it to the production
location.
- :guilabel:`Buy to Resupply`: when products are bought, they can be delivered to this warehouse.
- :guilabel:`Resupply From`: automatically create routes to resupply this warehouse from another
chosen warehouse
.. tip::
*Routes* can be set and configured directly from the :guilabel:`Warehouse` form, by clicking on
the :guilabel:`Routes` smart button. Once the warehouse is configured, virtual *Locations* can be
created.
.. image:: stock_warehouses/stock-warehouses-create-warehouse.png
:align: center
:alt: The edit screen for creating a new warehouse.
In order to apply this virtual warehouse as the *parent* location of two *child* location
warehouses, there need to be two warehouses configured with physical stock locations.
.. example::
| **Parent Warehouse**
| :guilabel:`Warehouse`: `Virtual Warehouse`
| :guilabel:`Location`: `VWH`
| **Child Warehouses**
| :guilabel:`Warehouses`: `Warehouse A` and `Warehouse B`
| :guilabel:`Locations`: `WHA/Stock` and `WHB/Stock`
Create a virtual parent location
--------------------------------
.. important::
In order to take stock from multiple warehouses to fulfill a sales order, there need to be at
least **two** warehouses acting as *child locations* of the *virtual parent location* warehouse.
To create and edit *Locations*, go to :menuselection:`Inventory --> Configuration --> Locations`.
All :guilabel:`Locations` are listed here, including the *Stock* :guilabel:`Location` of the virtual
warehouse that was created. Click into the *Stock* :guilabel:`Location` for the virtual warehouse
that was previously created (:dfn:`Warehouse Name/Stock`).
Then, under the :guilabel:`Additional Information` section, change the :guilabel:`Location Type`
from :guilabel:`Internal Location` to :guilabel:`View`. :guilabel:`Save` the changes.
This identifies this :guilabel:`Location` as a *virtual location*, which is used to create a
hierarchical structure for a warehouse and aggregate its *child locations*.
.. note::
Products can *not* be stored in a :guilabel:`View` :guilabel:`Location Type`.
.. image:: stock_warehouses/stock-warehouses-location-types.png
:align: center
:alt: Warehouse location types in location creation screen.
Configure physical warehouse locations
======================================
Taking stock from different warehouses
======================================
Navigate back to the :guilabel:`Locations` overview (via the breadcrumbs), and remove any filters
in the :guilabel:`Search Bar`. Then, click into the first physical warehouse :guilabel:`Location`
that was previously created to be a *child location*, and click :guilabel:`Edit`.
When you plan to deliver a customer, you dont know in advance if the products will come from
Warehouse A or Warehouse B. You may, in some cases, need to take stock from different warehouses.
With *Odoo*, you can configure this by using the concept of virtual warehouses. Let us show you how
to set those virtual warehouses.
Under :guilabel:`Parent Location`, select the virtual warehouse from the drop-down menu, and
:guilabel:`Save` changes. Then, navigate back to the :guilabel:`Locations` overview, and repeat this
step for the second physical warehouse stock location. Be sure to :guilabel:`Save` changes again.
Set up virtual warehouses
=========================
Both locations are now *child locations* of the virtual warehouse *parent location*. This allows
stock to be taken from multiple locations to fulfill a single sales order, if there is not enough
stock in any one location (provided they are both tied to the same virtual warehouse *parent
location*).
Lets say you have two warehouses: Warehouse A and Warehouse B. Create a new warehouse, that will be
a virtual one. It will allow you to take the stock from A or B. To do so, go to your inventory app
settings and enable the multi-warehouses feature. Then, go to the warehouses menu and click on
create.
Example flow: Sell a product from a virtual warehouse
=====================================================
.. image:: stock_warehouses/ware1.png
:align: center
.. note::
To sell products from multiple warehouses using a virtual *parent* location in this flow, there
must be at least **two** products and at least **two** warehouses configured - with at least
**one** product with quantity on-hand in each warehouse, respectively.
The *Storage Location* feature will be automatically enabled. Good news, because you will need it
later in the process.
To create a new request for quotation, or RFQ, navigate to the :menuselection:`Sales` app, and
click :guilabel:`Create` from the :guilabel:`Quotations` overview. Fill out the information on the
new quotation by adding a :guilabel:`Customer`, and click :guilabel:`Add a product` to add the two
products stored in the two warehouses.
Now, you have to make sure that the main stock locations of warehouse A and warehouse B are children
locations of the main stock location of warehouse A + B. Go to the locations menu, and edit the main
location of your two warehouses. Then, change their parent location to main location of warehouse
A+B.
Then, click the :guilabel:`Other Info` tab on the sales order form. Under the :guilabel:`Delivery`
section, change the :guilabel:`Warehouse` field value listed to the virtual warehouse that was
previously created. Once the warehouse has been changed, click :guilabel:`Confirm` to convert the
quotation into a sales order.
Now that the quotation has been confirmed as a sales order, click the :guilabel:`Delivery` smart
button. From the warehouse delivery form, confirm that the :guilabel:`Source Location` value matches
the :guilabel:`Warehouse` field value from the sales order. Both should list the virtual warehouse
location.
.. important::
The :guilabel:`Source Location` on the warehouse delivery form and the :guilabel:`Warehouse`
under the :guilabel:`Other Info` tab on the sales order form *must* match in order for the
products included in the sales order to be pulled from different warehouses.
- If the virtual warehouse is not the value in the :guilabel:`Source Location` field on the
warehouse delivery form, then click :guilabel:`Edit`, make the change, and click
:guilabel:`Save`.
- If the virtual warehouse is not the value in the :guilabel:`Warehouse` field on the sales order,
then a new quotation may need to be generated.
- If whe :guilabel:`Warehouse` field is missing on the sales order form, then the virtual
warehouse (and its children warehouses) may not have been set up correctly, in which case,
review the documentation above again to make sure all settings/configuration were done properly.
.. image:: stock_warehouses/stock-warehouses-delivery-order.png
.. image:: stock_warehouses/ware2.png
:align: center
:alt: Delivery order with matching source and child locations.
Finally, on the warehouse delivery form, under the :guilabel:`Detailed Operations` tab, confirm
that the *Locations* values under the :guilabel:`From` column for each product matches to the *child
locations* that are tied to the virtual *parent location*.
Sell a product from the virtual warehouse
=========================================
.. note::
To view which *Locations* the products are coming from on the drop-down menus, click the
:guilabel:`internal link (arrow)` icon to expand the *Location* information. If needed, it can be
changed from here (granted there is quantity on hand for the product in that location).
Lets say you have two products, one stored in warehouse A and one stored in warehouse B. Now, you
can create a new quotation for one of each product. Go to other information and choose Warehouse A+B
in the shipping information.
Once everything has been properly set, click :guilabel:`Validate` and then :guilabel:`Apply` to
validate the delivery. Then, navigate back to the sales order form (via the breadcrumbs), and
click :guilabel:`Create Invoice` to invoice for the sales order.
.. tip::
To use a virtual *parent* location as the default warehouse for sales orders, each salesperson
can have the virtual warehouse assigned to them from the drop-down menu next to
:guilabel:`Default Warehouse` on their employee form.
.. image:: stock_warehouses/stock-warehouses-employee-form.png
.. image:: stock_warehouses/ware3.png
:align: center
Once you have done it, you can convert it to a sales order. Then, a delivery order will be
automatically generated, with a product reserved in warehouse A and one in warehouse B.
.. image:: stock_warehouses/ware4.png
:align: center
:alt: Default warehouse location on employee form.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

View File

@@ -1,5 +1,3 @@
.. _use-routes:
================================
Using Routes and Pull/Push Rules
================================

View File

@@ -11,4 +11,3 @@ Marketing
marketing/sms_marketing
marketing/events
marketing/surveys
marketing/social_marketing

View File

@@ -1,16 +0,0 @@
:nosearch:
:show-content:
:hide-page-toc:
:show-toc:
================
Social Marketing
================
.. seealso::
- `Odoo Tutorials: Marketing <https://www.odoo.com/slides/marketing-27>`_
.. toctree::
:titlesonly:
social_marketing/essentials

View File

@@ -1,11 +0,0 @@
:nosearch:
==========
Essentials
==========
.. toctree::
:titlesonly:
essentials/social_essentials
essentials/social_campaigns

View File

@@ -1,151 +0,0 @@
==========================
Social marketing campaigns
==========================
Social marketing campaigns help companies connect directly with the marketplace. These campaigns
are helpful when introducing a new product to customers, explaining the value of a product or
service, or when advertising an upcoming event or product release.
The most effective social marketing campaigns typically involve multiple channels to maximize
content distribution, and Odoo's *Social Marketing* application acts as a singular control center to
monitor, plan, post, track, and analyze all of the various content and content channels within a
single dashboard.
Campaigns page
==============
To access a complete overview of all social marketing campaigns, open the :menuselection:`Social
Marketing` application, and click :menuselection:`Campaigns` from the header menu. Doing so reveals
a separate page with every campaign in a default kanban view.
.. image:: social_campaigns/campaigns-page.png
:align: center
:alt: View of the campaigns page in the Odoo Social Marketing application.
Each *stage* in the kanban view can be edited, by clicking the :guilabel:`gear icon` to the left of
the :guilabel:`+ (plus sign)` - located to the right of the stage title.
.. note::
The **gear icon** *only* appears when the cursor hovers to the left of the **+ (plus sign)**.
When the gear icon is clicked, a drop-down menu reveals the options: :guilabel:`Fold`,
:guilabel:`Edit Stage`, and :guilabel:`Delete`.
.. image:: social_campaigns/campaign-stage-dropdown.png
:align: center
:alt: View of the campaigns page in the Odoo Social Marketing application.
Clicking :guilabel:`Fold` minimizes that specific stage's column. The stage column can be restored
by clicking the folded version of it on the main :guilabel:`Campaigns` dashboard in the default
kanban view.
Selecting :guilabel:`Edit Stage` reveals a pop-up window, in which the name and the sequence of the
stage can be modified. If changes are made, be sure to click :guilabel:`Save`.
Clicking :guilabel:`Delete` removes the stage entirely.
.. note::
To add a new stage to the pipeline, side-scroll to the right on the :guilabel:`Campaigns`
dashboard, click :guilabel:`Add a Column`, enter in the desired information, and click
:guilabel:`Add`.
.. tip::
The same social marketing campaign information on the :guilabel:`Campaigns` dashboard can also be
viewed as a list, by selecting the :guilabel:`List` option, located under the search bar, in the
upper-right corner.
Create social marketing campaigns
=================================
First, open the :menuselection:`Social Marketing` application, and select :guilabel:`Campaigns` from
the header menu.
On the :guilabel:`Campaigns` dashboard, a new campaign can be created by clicking the quick add
:guilabel:`+ (plus sign)` located in the top-right corner of each stage in the pipeline, visible in
the kanban view. Campaigns can also be created by clicking :guilabel:`Create` in the upper-left
corner of the :guilabel:`Campaigns` dashboard.
Both options reveal a new campaign detail window directly on the :guilabel:`Campaigns` dashboard
when clicked.
.. image:: social_campaigns/quick-add-campaign.png
:align: center
:alt: View of the quick add option for campaigns in Odoo Social Marketing.
Here, the :guilabel:`Campaign Name`, :guilabel:`Responsible`, and :guilabel:`Tags` can be entered.
When all modifications are complete, click :guilabel:`Add` to add the campaign to the database.
Edit social marketing campaigns
===============================
In order to edit a campaign in greater detail, and create/send various forms of communications
related to it, the template page for that campaign must be accessed and modified, accordingly.
There are multiple ways to access a template page for a campaign.
- After entering the pertinent information in the :guilabel:`Quick Add` campaign drop-down, click
:guilabel:`Edit`.
- Simply select the desired campaign from the :guilabel:`Campaigns` dashboard in list or kanban
view.
- On the :guilabel:`Campaigns` dashboard in the kanban view, select the :guilabel:`⋮ (three dots)`
drop-down menu on the desired campaign, and select :guilabel:`Edit`.
Any of the above routes will reveal the *Campaign Template* page for that specific campaign.
Social marketing campaign templates
===================================
On a *Campaign Template* page, numerous elements can be customized/modified, and various forms of
communications can be created, modified, and sent or scheduled. Below is a sample of a completed
campaign template.
.. image:: social_campaigns/create-campaign.png
:align: center
:alt: View of a sample campaign template page in Odoo Social Marketing.
.. important::
In order for the :guilabel:`Send New Mailing` option to appear on campaign templates, make sure
the *Mailing Campaigns* feature is enabled in the *Email Marketing* app. To do that, navigate to
:menuselection:`Email Marketing --> Configuration --> Settings`, activate :guilabel:`Mailing
Campaigns`, and click :guilabel:`Save`.
.. note::
In order for the :guilabel:`Send SMS` option to appear, the Odoo *SMS Marketing* application must
be installed on the database.
Add content and communications to campaigns
===========================================
If the proper settings and applications are installed (as instructed above), there are four forms
of communication/content options that can be added to campaigns. Each of these options are displayed
as buttons in the upper-left corner of the campaign template page.
- :guilabel:`Send New Mailing`: reveals a blank email template on a separate page, in which the
message can be fully customized in a variety of ways.
- :guilabel:`Send SMS`: reveals a blank SMS template on a separate page, in which a SMS
communication can be created and configured.
- :guilabel:`Send Social Post`: reveals a blank social post template on a separate page, in which
a post can be created, and applied to social media accounts that are already connected to the
database.
- :guilabel:`Push Notification`: reveals a similar blank social post template on a separate page,
however, the :guilabel:`Push Notification` options are already pre-selected in the :guilabel:`Post
on` field.
Whichever form of communication is created, once it's completed, Odoo returns to the
:guilabel:`Campaign Template` page, showcasing that new content in its corresponding tab (e.g.
:guilabel:`Mailings`, :guilabel:`SMS`, :guilabel:`Social Media`, and/or :guilabel:`Push
Notifications`).
As content and communications are added to a campaign, tabs for those specific mediums appear,
along with a variety of analytical smart buttons (e.g. :guilabel:`Revenues`, :guilabel:`Quotations`,
:guilabel:`Leads`, etc.).
These smart buttons, located at the top of the template, display different metrics related to the
campaign, and its various communications and content. Clicking any smart button reveals a separate
page dedicated to that particular element of the campaign, allowing for quicker, more organized
analysis.
.. note::
The Odoo *Social Marketing* app is integrated with other Odoo applications, such as *Sales*,
*Invoicing*, *CRM*, and *Website*.
.. seealso::
:doc:`/applications/marketing/social_marketing/essentials/social_essentials`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -1,345 +0,0 @@
===========================
Social marketing essentials
===========================
Odoo's *Social Marketing* helps content marketers create and schedule posts, manage various social
media accounts, analyze content effectiveness, and engage directly with social media followers in
one, centralized location.
Add social media accounts
=========================
In order to create posts, each social media account must be added as a stream in the Odoo *Social
Marketing* application.
Add a social media stream
-------------------------
Add a social media account as a stream by navigating to :menuselection:`Social Marketing` and then
select the :guilabel:`Add A Stream` button located in the upper left corner
When :guilabel:`Add A Stream` is clicked, the following pop-up appears, displaying the different
social media outlets to choose from.
.. image:: social_essentials/social-add-streams.png
:align: center
:alt: View of the pop-up that appears when 'Add a Stream' is selected in Odoo.
.. note::
Additional social media outlet options are available depending on your version of Odoo.
From this pop-up, select a social media option: :guilabel:`Facebook`, :guilabel:`LinkedIn`, or
:guilabel:`Twitter`.
Then, Odoo navigates directly to that specific social media outlet's authorization page, where
permission must be granted, in order for Odoo to add that particular social media account to the
*Social Marketing* application as a stream on the main dashboard of the app.
.. note::
A Facebook page can be added as long as the Facebook account that grants permission is the
administrator for the page. Also, different pages can be added for different streams.
Once permission is granted, Odoo navigates back to the :guilabel:`Feed` on the main
:guilabel:`Social Marketing` dashboard, and a new column with that account's posts are automatically
added.
From here, new accounts and/or streams can be added and managed at any time.
.. image:: social_essentials/feed.png
:align: center
:alt: Example of how a populated stream-filled dashboard looks in Odoo Social Marketing
.. note::
Adding social media accounts to the feed also links that specific social media platform's KPIs
(if the platform has them). To get redirected to the statistics and metrics related to any social
account, click on :guilabel:`Insights`.
.. image:: social_essentials/insights.png
:align: center
:alt: The insights link that can be accessed for each social media stream added in Odoo.
Create and publish social media posts in Odoo
=============================================
To create content for social media accounts in the :menuselection:`Social Marketing` application,
click the :guilabel:`New Post` button located in the upper-left corner of the main dashboard, or
navigate to :menuselection:`Posts --> Create` from the header menu.
Either route reveals a blank post template page that can be customized and configured in a number
of different ways.
.. image:: social_essentials/social-create-post.png
:align: center
:alt: How to create a social media post directly through Odoo
Post template
-------------
The post template page has many different options avaiable.
'Your Post' section
~~~~~~~~~~~~~~~~~~~
The first option is the :guilabel:`Post on` field. This is where it's determined on what social
media account(s), or on which website(s) via push notification, this post will be published.
.. important::
In order for the :guilabel:`Push Notification` option to appear, make sure the *Enable Web Push
Notifications* feature is enabled in the *Website* app. To do that, navigate to
:menuselection:`Website --> Configuration --> Settings`, activate :guilabel:`Enable Web Push
Notifications`, fill out the corresponding fields, and click :guilabel:`Save`.
Odoo automatically provides every available social media account that's been linked to the database
as an option in this section, as well.
.. note::
If a social media account hasn't been added as a stream to the *Social Marketing* application, it
will not appear as an option on the post template.
Next, there's the :guilabel:`Message` field. This is where the main content of the post is created.
Type the desired message for the post in this field. To the right, as the :guilabel:`Message` field
is populated, Odoo displays visual samples of how the post will look on all the previously selected
social media accounts from the :guilabel:`Post on` field above.
.. tip::
Emojis can also be added directly to the text in the :guilabel:`Message` field. Just click the
:guilabel:`emoji (smiley face) icon`, located on the line of the :guilabel:`Message` field to the
far right. Clicking this icon reveals a drop-down containing numerous emojis to choose from.
If images are to be used in the post, click the :guilabel:`ATTACH IMAGES` link beneath the
:guilabel:`Message` field, and Odoo reveals a pop-up window. In this pop-up, the desired image must
be chosen, and then uploaded.
A preview of the entire post, text and image (if applicable), is instantly displayed in the visual
preview of the post.
Next, there's the option to attach this post to a specific marketing campaign in the database in
the :guilabel:`Campaign` field. Click the blank line next to :guilabel:`Campaign` to reveal the
previously configured campaigns to choose from.
.. tip::
A new campaign can be created, as well, by typing the name of the new campaign on the blank
:guilabel:`Campaign` field, and selecting :guilabel:`Create` from the drop-down field menu. Or,
select :guilabel:`Create and edit` from the menu to further customize that newly-created
campaign.
.. note::
A social post does *not* need to be attached to a campaign.
Then, in the :guilabel:`When` field, choose either :guilabel:`Send Now` to have Odoo publish the
post immediately, or :guilabel:`Schedule later` to have Odoo publish the post at a later date and
time.
If :guilabel:`Schedule later` is selected, Odoo reveals a new field beneath it (the
:guilabel:`Scheduled post date` field). Clicking that empty field reveals a pop-up calendar, in
which a future date and time is designated. At which time, Odoo will promptly publish the post on
the pre-determined social media accounts.
Click on the desired date to schedule the post for that day. Then, either select and customize
the default time in the :guilabel:`Scheduled post date` field manually. Or, adjust the desired post
time, by clicking the :guilabel:`scheduling (clock) icon` located on the calendar pop-up, and choose
the desired time for Odoo to publish this post on that future date.
If scheduling a post, remember to hit :guilabel:`Schedule` in the upper left of the post template.
Doing so, locks in that specific date/time for Odoo to send the post, and it changes the status of
the post to :guilabel:`Scheduled`.
.. note::
Also, when :guilabel:`Schedule` is clicked, a number of analytical smart buttons appear on the
post page. Each one offers up a detailed anaylsis of the corresponding metric (e.g.
:guilabel:`Leads`, :guilabel:`Revenues`, etc.). These same smart buttons appear when a post is
officially published, as well.
'Web Notification Options' section
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
If any :guilabel:`Push Notifications` are selected in the :guilabel:`Post on` field, Odoo provides
another section of settings/options at the bottom of the post template. It should be noted that
*none* of these fields are required.
The first field is for a :guilabel:`Push Notification Title`. This is text that is displayed as the
title of the push notification whenever it's sent. Odoo displays a visual preview of this title, if
one is created.
To designate a specific page on the website that should trigger this push notification, enter that
page's URL in the :guilabel:`Push Target URL` field. Then, once a visitor reaches that specific
page, Odoo will display the push notification.
Below that field is the option to add a custom :guilabel:`Push Icon Image`. This is an icon that
appears beside the push notification. By default, Odoo uses a "smiley face" as the icon.
To upload a new image, click the :guilabel:`Edit (pencil) icon` when the :guilabel:`Push Icon Image`
field is hovered over with the cursor. Then, proceed to locate and upload the desired image, and
Odoo automatically displays a preview of how the icon will appear on the push notification.
Next, there is the option to :guilabel:`Send at Visitors' Timezone`. If enabled, Odoo will send it
at the appropriate, pre-determined time, taking the visitor's location into consideration.
Save, post, and test notification options
-----------------------------------------
When all the modifications have been made, and the post is completed, either click :guilabel:`Save`
to save the post as a *Draft*. Or, if the post is ready to be published immediately, click
:guilabel:`Post`, and Odoo automatically publishes the post on the pre-determined social media
accounts.
There is also the option to :guilabel:`Test Notification`, if a :guilabel:`Push Notification` was
selected in the :guilabel:`Post on` field. Clicking that, provides a quick example of how the
notification will appear for visitors.
Social post status bar
----------------------
In the top-right of the :guilabel:`Post Template` page is the :guilabel:`Status Bar`. This displays
the current status of the post.
When :guilabel:`Save` is clicked, the post is in the *Draft* status.
If the post is scheduled to be sent at a future date/time, and the :guilabel:`Schedule` button has
been clicked, the status of the post is *Scheduled*.
If the post is in the process of currently being published or sent, the status of the post is
*Posting*. And, lastly, if the post has already been published or sent, the status is *Posted*.
Posts page
==========
To see a complete overview of posts, go to Odoo :menuselection:`Social Marketing`, and click
:menuselection:`Posts` in the header menu. Here, every post that has been created and posted with
Odoo is available.
There are four different view options for :guilabel:`Posts` page data: *kanban*, *calendar*, *list*,
and *pivot*. The view options are located in the upper right corner of the :guilabel:`Posts` page,
beneath the search bar.
.. tabs::
.. tab:: Kanban view
By default, Odoo displays the posts in a kanban view. The information on this page can be
sorted even further, via the :guilabel:`Filters` and :guilabel:`Group by` drop-down menu.
.. image:: social_essentials/posts-page.png
:align: center
:alt: Kanban view of the posts page in the Odoo Social Marketing application.
.. tab:: Calendar view
The calendar view option displays a visual representation in a calendar format of when posts
were published, or are scheduled to be published. This option provides a clear overview of any
planned day, week, or month, and Odoo displays all drafted, scheduled, and published posts.
.. image:: social_essentials/calendar-view.png
:align: center
:alt: Example of the calendar view in Odoo Social Marketing.
.. tab:: List view
The list view option is similar to the kanban option, but instead of individual blocks, all
the post information is displayed in a clear, list layout. Each line of the list displays the
:guilabel:`Social Accounts`, :guilabel:`Message`, and :guilabel:`Status` of every post.
.. image:: social_essentials/list-view.png
:align: center
:alt: View of the list option on the posts page in Odoo Social Marketing.
.. tab:: Pivot view
The pivot view option provides a fully customizable grid table, where different measures of
data can be added and analyzed.
.. image:: social_essentials/pivot-view.png
:align: center
:alt: View of the pivot option on the posts page in Odoo Social Marketing.
The pivot view option provides numerous analytical options, allowing for in-depth, detailed
analysis of various posts.
Click on any :guilabel:`+ (plus sign) icon` next to a line in the pivot table to reveal more metric
options to add to the grid.
While in the pivot view, the option to :guilabel:`Insert in Spreadsheet` is available, located
to the right of the :guilabel:`Measures` drop-down.
When clicked, a pop-up appears, where the option to add this information to a current
spreadsheet is available. The option to create a new spreadsheet for this information
on-the-fly is also available in this pop-up, as well.
Next to the :guilabel:`Insert in Spreadsheet` are three view options, specific to the pivot
view.
From left to right, the options are:
- :guilabel:`Flip Axis`, which switches the *X* and *Y* axis in the grid table.
- :guilabel:`Expand All`, which expands each line in the grid, revealing more detailed
information related to it.
- :guilabel:`Download`, which, when clicked, instantly downloads the pivot table as a
spreadsheet.
Visitors
========
To see a complete overview of all the people who have visited the website(s) connected to the
database, navigate to :menuselection:`Social Marketing --> Visitors` in the header menu.
.. image:: social_essentials/visitors.png
:align: center
:alt: View of the Visitors page in the Odoo Social Marketing application.
Here, Odoo provides a detailed layout of all the visitors' pertinent information in a default
kanban view. This same information can be sorted via the :guilabel:`Filters` and :guilabel:`Group
By` options.
The visitor data can also be viewed as a list or a graph. Those view options are located in the
upper-right corner of the :guilabel:`Visitors` page beneath the search bar.
Social media page
=================
Go to :menuselection:`Configuration --> Social Media` to see a collection of all social media
options: :guilabel:`Facebook`, :guilabel:`LinkedIn`, :guilabel:`Twitter`, and :guilabel:`Push
Notifications`.
.. image:: social_essentials/social-media-page.png
:align: center
:alt: View of the social media page in the Odoo Social Marketing application.
If no account has been linked to any particular social media, click :guilabel:`Link Account` to
proceed through the linking process.
Social accounts page
====================
To see a list of all social accounts linked to the database, go to :menuselection:`Configuration -->
Social Accounts`. This page will display the :guilabel:`Medium Name` and the :guilabel:`Social
Media` platform it is associated with.
.. image:: social_essentials/social-accounts-page.png
:align: center
:alt: View of the social accounts page in the Odoo Social Marketing application.
To edit/modify any social accounts, simply select the desired account from the list on this page,
and proceed to make any adjustments necessary. Don't forget to hit :guilabel:`Save` to secure any
changes.
Social streams page
===================
Navigate to :menuselection:`Configuration --> Social Streams` to reveal a separate page containing
all of the social media streams that have been added to the main dashboard of the *Social Marketing*
app, accessible via the :guilabel:`Feed` option in the header menu.
.. image:: social_essentials/social-streams-page.png
:align: center
:alt: View of the social accounts page in the Odoo Social Marketing application.
Here, the social stream information is organized in a list with the :guilabel:`Social Media`, the
:guilabel:`Title` of the stream, and the :guilabel:`Type` of the stream (e.g. :guilabel:`Posts`,
:guilabel:`Keyword`, etc.).
To modify any stream's information, simply click the desired stream from the list, and proceed to
make any necessary adjustments. Don't forget to hit :guilabel:`Save` to secure any changes.
.. seealso::
:doc:`/applications/marketing/social_marketing/essentials/social_campaigns`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -1,4 +1,7 @@
:nosearch:
:show-content:
:hide-page-toc:
:show-toc:
=======
Surveys
@@ -10,6 +13,4 @@ Surveys
.. toctree::
:titlesonly:
surveys/create
surveys/scoring
surveys/time_random
surveys/overview

View File

@@ -0,0 +1,12 @@
:nosearch:
========
Overview
========
.. toctree::
:titlesonly:
overview/create
overview/scoring
overview/time_random

View File

@@ -1,9 +1,9 @@
=====================================
Synchronize Google calendar with Odoo
=====================================
===============================
Google Calendar synchronization
===============================
Synchronize Google Calendar with Odoo to see and manage meetings from both platforms (updates go in
both directions). This integration helps organize schedules, so a meeting is never missed.
Synchronize Google Calendar with Odoo to see and manage meetings from both platforms (updates go
in both directions). This integration helps organize your schedule so you never miss a meeting.
.. seealso::
- :doc:`/applications/general/auth/google`
@@ -12,100 +12,96 @@ both directions). This integration helps organize schedules, so a meeting is nev
Setup in Google
===============
Select (or create) a project
----------------------------
Enable Google Calendar API
--------------------------
Create a new Google API project and enable the Google Calendar API. First, go to the `Google API
Console <https://console.developers.google.com>`_ and log into the Google account.
Begin by creating a new Google API project and enabling the Google Calendar API. Then, go to the
`Google API Console <https://console.developers.google.com>`_ and log into your Google account.
.. note::
If this is the first time visiting this page, Google will prompt the user to enter a country and
If this is your first time visiting this page, Google will prompt you to enter a country and
agree to the Terms of Service. Select a country from the drop-down list and agree to the
:abbr:`ToS (Terms of Service)`.
Next, click :guilabel:`Select a project` and select (or create) an API project to configure OAuth
in, and store credentials. Click :guilabel:`New Project`.
Next, click :guilabel:`Select a project` and select or create an API project to store credentials.
.. image:: google/new-api-project.png
:align: center
:alt: Create a new API project to store credentials.
.. tip::
Give the API Project a clear name, like "Odoo Sync", so it can be easily identified.
Give the API Project a clear name like "Odoo Sync" so you can easily find it.
Enable Google calendar API
--------------------------
Now, click on :guilabel:`Enabled APIs and Services` in the left menu. Select :guilabel:`Enabled APIs
and Services` again if the :guilabel:`Search bar` doesn't appear.
Then, open the API Project and click :guilabel:`Enable APIs and Services`.
.. image:: google/enable-apis-services.png
:align: center
:alt: Enable APIs and Services on the API Project.
After that, search for `Google Calendar API` using the search bar and select :guilabel:`Google
After that, search for *Google Calendar API* using the search bar and select :guilabel:`Google
Calendar API` from the search results. Click :guilabel:`Enable`.
.. image:: google/enable-google-cal-api.png
:align: center
:alt: Enable the Google Calendar API.
OAuth consent screen
--------------------
Now that the API project has been created, OAuth should be configured. To do that, click on
:guilabel:`OAuth consent` in the left menu and then select the :guilabel:`User Type`.
.. warning::
*Personal* Gmail Accounts are only allowed to be **External** User Type, which means Google may
require an approval, or for *Scopes* to be added on. However, using a *Google WorkSpace* account
allows for **Internal** User Type to be used.
Note, as well, that while the API connection is in the *External* testing mode, then no approval is
necessary from Google. User limits in this testing mode is set to 100 users.
In the second step, :guilabel:`OAuth Consent Screen`, type `Odoo` in the :guilabel:`App name` field,
select the email address for the :guilabel:`User support email` field, and type the email address
for the :guilabel:`Developer contact information` section. Then, click :guilabel:`Save and
Continue`.
Skip the third step, :menuselection:`Scopes`, by clicking :guilabel:`Save and Continue`.
Next, if continuing in testing mode (External), add the email addresses being configured under the
:guilabel:`Test users` step, by clicking on :guilabel:`Add Users`, and then the :guilabel:`Save and
Continue` button. A summary of the app registration appears.
Finally, scroll to the bottom, and click on :guilabel:`Back to Dashboard`.
Now, the OAuth consent has been configured, and it's time to create credentials.
Create credentials
------------------
The *Client ID* and the *Client Secret* are both needed to connect Google Calendar to Odoo. This is
the last step in the Google console. Begin by clicking :guilabel:`Credentials` in the left menu.
Then, click :guilabel:`Create Credentials`, and select :guilabel:`OAuth client ID`, Google will open
a guide to create credentials.
Now that you have created your API project and enabled the Google Calendar API, you need to create
credentials. Begin by clicking :guilabel:`Create Credentials`. Google will then guide you through
four steps to create your API credentials.
Under :menuselection:`Create OAuth Client ID`, select :guilabel:`Website application` for the
:guilabel:`Application Type` field, and type `My Odoo Database` for the :guilabel:`Name`.
- In the first step, :guilabel:`Credential Type`, select the :guilabel:`Google Calendar API` and
:guilabel:`User Data` options. Then, click :guilabel:`Next`.
- Under the :guilabel:`Authorized JavaScript Origins` section, click :guilabel:`+ Add URI` and
type the company's Odoo full :abbr:`URL (Uniform Resource Locator)` address.
- Under the :guilabel:`Authorized redirect URIs` section, click :guilabel:`+ Add URI` and type
the company's Odoo :abbr:`URL (Uniform Resource Locator)` address followed by
`/google_account/authentication`. Finally, click :guilabel:`Create`.
.. image:: google/credential-type.png
:align: center
:alt: Select Google Calendar API and User Data for the Credential Type.
- In the second step, :guilabel:`OAuth Consent Screen`, type *Odoo* in the :guilabel:`App name`
field, select your email address for the :guilabel:`User support email` field, and type your email
address for the :guilabel:`Developer contact information` section. Then, click :guilabel:`Save
and Continue`.
- Skip the third step, :guilabel:`Scopes`, by clicking :guilabel:`Save and Continue`.
- In the last step, :guilabel:`OAuth Client ID`, select :guilabel:`Website application` for the
:guilabel:`Application Type` field and type *My Odoo Database* for the :guilabel:`Name`.
- Under the :guilabel:`Authorized JavaScript Origins` section, click :guilabel:`+ Add URI` and
type your company's Odoo URL address.
- Under the :guilabel:`Authorized redirect URIs` section, click :guilabel:`+ Add URI` and type
your company's Odoo URL address followed by */google_account/authentication*. Finally, click
:guilabel:`Create` and :guilabel:`Done`.
.. image:: google/uri.png
:align: center
:alt: Add the authorized JavaScript origins and the authorized redirect URIs.
A :guilabel:`Client ID` and :guilabel:`Client Secret` will appear, copy these to a notepad.
After successfully creating a new API project, enabling the Google Calendar API, and generating the
Google Calendar API credentials, you should now have a Client ID and Client Secret.
Client ID & Client Secret
-------------------------
The **Client ID** and the **Client Secret** are both needed to connect Google Calendar to Odoo. Find
the Client ID and the Client Secret by opening the Google Cloud Platform navigation menu and going
to :menuselection:`API & Services --> Credentials --> OAuth 2.0 Client IDs`.
Next, locate the credentials you just created for the Google Calendar API. Then, click on
:guilabel:`Edit OAuth Client` (the pencil icon). The page will redirect to the edit page, where you
can view the Client ID and the Client Secret.
.. image:: google/edit-oauth-2.png
:align: center
:alt: Click Edit OAuth Client to view the credential details.
Setup in Odoo
=============
Once the *Client ID* and the *Client Secret* are located, open the Odoo database and go to
Once the Client ID and the Client Secret are located, open the Odoo database and go to
:menuselection:`Settings --> General Settings --> Integrations --> Google Calendar`. Check the box
next to :guilabel:`Google Calendar`.
@@ -113,25 +109,20 @@ next to :guilabel:`Google Calendar`.
:align: center
:alt: The Google Calendar checkbox in General Settings.
Next, copy and paste the *Client ID* and the *Client Secret* from the Google Calendar API
credentials page into their respective fields below the :guilabel:`Google Calendar` checkbox. Then,
click :guilabel:`Save`.
Next, copy and paste the Client ID and the Client Secret from the Google Calendar API Credentials
page into their respective fields below the :guilabel:`Google Calendar` checkbox. Then, click
:guilabel:`Save`.
Sync calendar in Odoo
=====================
Finally, open the :menuselection:`Calendar` app in Odoo and click on the :guilabel:`Google` sync
button to sync Google Calendar with Odoo.
Finally, open the Calendar module in Odoo and click on the :guilabel:`Google` sync button to sync
Google Calendar with Odoo.
.. image:: google/sync-google.png
:align: center
:alt: Click the Google sync button in Odoo Calendar to sync Google Calendar with Odoo.
.. note::
When syncing Google Calendar with Odoo for the first time, the page will redirect to the Google
Account. From there, select the :guilabel:`Email Account` that should have access, then select
:guilabel:`Continue` (should the app be unverifed), and finally select :guilabel:`Continue` (to
give permission for the transfer of data)`.
The first time you sync your Google Calendar with Odoo, the page will redirect to your Google
Account. Click :guilabel:`OK` and :guilabel:`Allow` to authorize Odoo to access Google Calendar.
.. image:: google/trust-odoo.png
:align: center
@@ -139,17 +130,6 @@ button to sync Google Calendar with Odoo.
Now, Odoo Calendar is successfully synced with Google Calendar!
.. warning::
Odoo highly recommends testing the Google calendar synchronization on a test database and a test
email address (that is not used for any other purpose) before attempting to sync the desired
Google Calendar with the user's production database.
Once a user synchronizes their Google calendar with the Odoo calendar:
- Creating an event in Odoo causes Google to send an invitation to all event attendees.
- Deleting an event in Odoo causes Google to send a cancellation to all event attendees.
- Adding a contact to an event causes Google to send an invitation to all event attendees.
- Removing a contact from an event causes Google to send a cancellation to all event attendees.
Events can be created in Google Calendar without sending a notification by selecting
:guilabel:`Don't Send` when prompted to send invitation emails.
.. image:: google/successful-sync.png
:align: center
:alt: Successfully sync between Odoo and Google Calendar.

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

@@ -115,6 +115,6 @@ To close your session,
point_of_sale/configuration
point_of_sale/shop
point_of_sale/restaurant
point_of_sale/pricing
point_of_sale/payment_methods
point_of_sale/pricing
point_of_sale/reporting

View File

@@ -7,9 +7,8 @@ Pricing features
.. toctree::
:titlesonly:
pricing/cash_rounding
pricing/discounts
pricing/discount_tags
pricing/loyalty
pricing/pricelists
pricing/fiscal_position
pricing/cash_rounding

View File

@@ -14,7 +14,7 @@ Once the POS is set to be used in a restaurant or a bar, you can:
- :doc:`communicate with the kitchen or the bar through the POS <restaurant/kitchen_printing>`;
- :doc:`print bills in advance and split them <restaurant/bill_printing>`;
- :doc:`collect tips <restaurant/tips>`; and
- :doc:`set different taxes for takeaway food <pricing/fiscal_position>`.
- :doc:`set different taxes for takeaway food <restaurant/fiscal_position>`.
Configuration
=============
@@ -32,4 +32,5 @@ select your POS, and click :menuselection:`Edit --> Is a Bar/Restaurant --> Save
restaurant/bill_printing
restaurant/floors_tables
restaurant/kitchen_printing
restaurant/fiscal_position
restaurant/tips

View File

@@ -1,7 +1,7 @@
:nosearch:
=============
Shop features
Shop Features
=============
.. toctree::

View File

@@ -51,27 +51,23 @@ and then push them to GitHub. Skip this section and go to
.. code-block:: console
$ cd /CommunityPath
$ git remote add dev git@github.com:<your_github_account>/odoo.git
If you have access to `odoo/enterprise`, configure the related remote too.
.. code-block:: console
$ cd /EnterprisePath
$ git remote add dev git@github.com:<your_github_account>/enterprise.git
.. tab:: Link Git with odoo-dev
.. code-block:: console
$ cd /CommunityPath
$ git remote add dev git@github.com:odoo-dev/odoo.git
$ git remote set-url --push origin ''
$ git remote set-url --push origin no_push
$ cd /EnterprisePath
$ git remote add dev git@github.com:odoo-dev/enterprise.git
$ git remote set-url --push origin ''
$ git remote set-url --push origin no_push
#. That's it! You are ready to :ref:`make your first contribution
<contributing/development/first-contribution>`.

View File

@@ -12,7 +12,6 @@ Tutorials
tutorials/define_module_data
tutorials/restrict_data_access
tutorials/unit_tests
tutorials/git
tutorials/pdf_reports
tutorials/dashboards
@@ -35,6 +34,7 @@ Tutorials
.. card:: Restrict access to data
:target: tutorials/restrict_data_access
:tag: Beginner
Implement security measures to restrict access to sensitive data with the help of groups,
access rights, and record rules.
@@ -46,13 +46,6 @@ Tutorials
Write effective unit tests in Python to ensure the resilience of your code and safeguard it
against unexpected behaviors and regressions.
.. card:: Collaborate using git
:target: tutorials/git
:tag: Beginner
Hands on git and github, the two softwares that are used by both Odoo employees and external
people to work together on the source code and this documentation.
.. card:: Build PDF reports
:target: tutorials/pdf_reports

View File

@@ -1,374 +0,0 @@
=====================
Collaborate using git
=====================
Introduction
============
*What are git and github, what are there for*
Setup git and github
====================
Follow the same steps as in :ref:`contributing/development/setup`.
Explore the history
===================
We begin this tutorial by exploring the git history of Odoo. This section should help you get a first gasp of what git, commits and branches are for. Remember that whatever you do on your own computer stayes on your computer, git is not like dropbox in that regard. You are free to move around, open and read files and even modify them, it doesn't disturb anybody.
Status
------
Before doing anything complicated, we'll start with the command that show "what's going on": ``git status``. Open a terminal and move to the community path, then type ``git status``.
.. code-block:: console
:caption: status just after a clone
$ git status
On branch 16.0
Your branch is up to date with 'origin/16.0'.
nothing to commit, working tree clean
If you haven't done anything (beside changing the configuration), this is what the status should looks like.
The first line reads "On branch 16.0" (it is ok if it reports another version), it means that you are looking at the state of the Odoo source code as it is for the version 16. The second line reads "Your branch is up to date with 'origin/16.0'.", it means that your local copy of Odoo 16.0 is up to date with the remote copy of Odoo 16.0 on Github, in this context ``origin`` refers to https://github.com/odoo/odoo. The third line reads "nothing to commit, working tree clean", it means that you haven't modified any file.
.. warning::
Depending on your system configuration, the message may have been printed in French or in another language than English. We suggest you `configure <https://stackoverflow.com/a/10872202>`_ git to always print the messages in English, at least for this tutorial.
Log
---
You can open the file at ``odoo/release.py`` in a text editor (Windows users can use Notepad), it is a Python source code file with some informations about the software, among them there is the current version (again, it is fine if you have another version):
.. code-block:: python
:caption: version inside of odoo/release.py
version_info = (16, 0, 0, FINAL, 0, '')
In the introduction, we said git was also used to keep an history of all the changes done, you can consult this history using the ``git log`` command:
.. code-block:: console
:caption: all commits (revisions) in the history of the 16.0 version for the ``odoo/release.py`` file, one per line
$ git log 16.0 --oneline odoo/release.py
fa58938b3e24 [REL] 16.0 FINAL
1c0d46b68b1e [FIX] release: change version level to beta
2636bea44775 [REL] 16.0
00d36ec92971 [FIX] core: decrement master release version
e5361e93be3e [IMP] core: bump master release to 16.1 alpha
c336dddab8bc [IMP] release: correct typo in code comment
082aa4d35289 [IMP] core: bump master release to 15.4 alpha
8cc0a225a541 [IMP] core: bump master release to 15.3 alpha
c6600d1ea493 [IMP] core: bump master release version to 15.2
...
a84070f3ba49 [REL] 9.saas~13
9e64f9f95141 [REF] openerp: move `openerp` to `odoo`
.. tip::
In case there are more lines than your terminal can show at a same time, git shows the result inside of a *pager*. You can move inside the pager using the arrow keys and you can quit it by pressing ``q``.
Each line reports a different revision of the file, each revision is called a "commit" in git jargon. The first column is the commit hash, a unique identifier created by git to identify the commit. The second column is a tag that describe the type of change beeing done inside of the commit, REL for a release, FIX for a bug fix, IMP for an improvement, there are a few others not listed here. Finally, the rest of the line is the commit message title, a short description of what beeing done inside of the commit.
Using ``-p`` instead of ``--oneline``, we can show each commit with all its details: complete hash, date, author, full message and the lines that changed.
.. code-block:: console
:caption: meta informations of the commit fa58938b3e24…
$ git log 16.0 -p odoo/release.py
commit fa58938b3e2477f0db22cc31d4f5e6b5024f478b
Author: Christophe Monniez <moc@odoo.com>
Date: Tue Oct 11 14:01:40 2022 +0000
.. code-block:: text
:caption: free description (message) of the commit fa58938b3e24…
[REL] 16.0 FINAL
closes odoo/odoo#103147
Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
.. code-block:: udiff
:caption: lines changed (diff) by the commit fa58938b3e24…
-version_info = (16, 0, 0, BETA, 0, '')
+version_info = (16, 0, 0, FINAL, 0, '')
We only show here the first (most recent) commit that changed of file ``odoo/release.py`` in the history of the 16.0 branch. In your own terminal there is a pager that shows you all the commits that modified this file, you can quit it by pressing ``q``.
Each commit is separated in three sections, some meta informations, the commit message and the commit *diff*:
1. The meta part lists the unique full 40-chararacter longs :abbr:`commit hash (fa58938b3e2477f0db22cc31d4f5e6b5024f478b)`, the :abbr:`author (Christophe Monniez)` of the commit and the :abbr:`date (11 Oct. 2022)`.
#. The commit message is a free text written by Christophe, it contains a :abbr:`title/subject ([REL] 16.0 FINAL)`, an empty body and some trailers (:abbr:`Closes (closes odoo/odoo#103147)`, :abbr:`Signed-off-by (Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>)`). In this example, the two trailers were automatically added, the first is a `reference <https://github.com/odoo/odoo/pull/103147>`_ to a pull-request on Github, the second means that Xavier reviewed the changes and validated them.
#. The *diff* (difference) shows what lines changed during this revision. It is quite complicated, what matters are the two lines ``-version_info = (16, 0, 0, BETA, 0, '')`` and ``+version_info = (16, 0, 0, FINAL, 0, '')``. The lines beginning with a single ``-`` means that they were removed, wheras the ones beginning with a single ``+`` means they were added. It reads that the line ``version_info = (16, 0, 0, BETA, 0, '')`` was replaced by ``version_info = (16, 0, 0, FINAL, 0, '')``, i.e. ``BETA`` was replaced by ``FINAL``.
Reading all those informations we learn that this commit was the one at released Odoo 16.0, from a beta version, to the final release.
We can also study the history of other versions, like to list all commits that modified this ``odoo/release.py`` but this time inside of the 15.0 version
.. code-block:: text
:caption: all commits (revisions) in the history of the 15.0 version for the ``odoo/release.py`` file, one per line
$ git log 15.0 --oneline odoo/release.py
b50796d51607 [REL] 15.0
15b4cc97f302 [REL] saas-14.5
c2179731372d [IMP] core: bump master release version to 14.5 alpha
6f9aa96c16a2 [IMP] core: bump master version to 14.4 alpha1
55986ffa21da [IMP] core: bump master version to 14.3 alpha1
8fd7232a0e7c [IMP] core: bump master version to 14.2 alpha1
...
a84070f3ba49 [REL] 9.saas~13
9e64f9f95141 [REF] openerp: move `openerp` to `odoo`
Again, using ``-p`` instead of ``--oneline`` to show all details:
.. code-block:: console
:caption: meta informations of the commit b50796d51607…
$ git log -p 15.0 odoo/release.py
commit b50796d5160745d9f85992467d632d9ce2476697
Author: Christophe Monniez <moc@odoo.com>
Date: Tue Oct 5 09:28:30 2021 +0200
.. code-block:: text
:caption: free description (message) of the commit b50796d51607…
[REL] 15.0
.. code-block:: udiff
:caption: lines changed (diff) by the commit b50796d51607…
diff --git a/odoo/release.py b/odoo/release.py
index 7c114b120700..546d1c49a12f 100644
--- a/odoo/release.py
+++ b/odoo/release.py
@@ -12,7 +12,7 @@ RELEASE_LEVELS_DISPLAY = {ALPHA: ALPHA,
# properly comparable using normal operarors, for example:
# (6,1,0,'beta',0) < (6,1,0,'candidate',1) < (6,1,0,'candidate',2)
# (6,1,0,'candidate',2) < (6,1,0,'final',0) < (6,1,2,'final',0)
-version_info = ('saas~14', 5, 0, FINAL, 0, '')
+version_info = (15, 0, 0, FINAL, 0, '')
version = '.'.join(str(s) for s in version_info[:2]) + RELEASE_LEVELS_DISPLAY[version_info[3]] + str(version_info[4] or '') + version_info[5]
series = serie = major_version = '.'.join(str(s) for s in version_info[:2])
Reading all those informations, we learn the version saas-14.5 became known as 15.0. Please note that usually new saas releases are forked from master. The full release (e.g. 14.0, 15.0) are an exception as they are generally based on the lastest saas-x.5 release (itself forked from master).
Show
----
A second way to study the history is to look at a precise commit. Say you are reading the *oneline* history and that one of the commit titles get your attention, that you want to print all the details of that specific commit. That's what ``show`` is for. Let's say you wonder how long your session is going to last, like how often <odoo.com> is going to ask you to type your password again because your session would had expired. Technically this is known as the "session lifetime" so you can search the history looking for those two words:
.. code-block:: console
:caption: all commits in 16.0 mentionning *session* and *lifetime*, one per line
$ git log --oneline --grep 'session' --grep 'lifetime' --all-match
05ff9a2db32c [FIX] http: make session lifetime consistent and configurable
f61aa39ff119 [REF] core: HTTPocalypse (9) ORM initialization
17e6a69b9189 [IMP] core: use Savepoint object in TestCursor
1fbafa4e69ee [MERGE][IMP] im_livechat: random assignation of conversation
The commit ``[FIX] http: make session lifetime consistent and configurable`` gets your attention, using ``show`` you can reveal all its secrets:
.. code-block:: console
$ git show 05ff9a2db32c
.. tabs::
.. group-tab:: Headers & Trailers
commit
05ff9a2db32c2fb1afa107ac005423218f452290
Author
Olivier Dony <odo@odoo.com>
Date
Tue May 30 10:59:42 2023 +0000
closes
odoo/odoo#122888
Signed-off-by
Julien Castiaux (juc) <juc@odoo.com>
.. group-tab:: Message
**[FIX] http: make session lifetime consistent and configurable**
Before 16.0 and `HTTPocalypse <HTTPocalypse_>`_ the session cookie duration was set to 3 months, but the server-side garbage collection of inactive session was reaping them after 7 days of inactivity. The cookie lifetime was essentially superseded by the server-side GC.
After `HTTPocalypse <HTTPocalypse_>`_ these limits were made consistent with each other, but the lifetime value was kept at 3 months, which is a bit too long as a default.
This commit changes the default ``SESSION_LIFETIME`` back to 7 days for both limits.
In addition, since the server-side GC is now implemented by a database-specific cron job, this commit introduces an optional system parameter ``sessions.max_inactivity_seconds`` that can be set to override the default server-side GC threshold, to make it shorter.
Note 1: the ICP does not modify the cookie lifetime which will remain set to the default 7 days. This means normal browser sessions won't stay alive for longer than 7 days of inactivity. So ``sessions.max_inactivity_seconds`` can't be effectively set to a longer expiration time. This seems like a reasonably safe default.
Note 2: the session GC happens during the execution of the autovacuum cron job ("Base: Auto-vacuum internal data") which is scheduled once per day by default. When setting a small ``sessions.max_inactivity_seconds`` value, it may be necessary to increase the frequency of that cron job accordingly.
.. group-tab:: Diff
.. code-block:: udiff
diff --git a/odoo/addons/base/models/ir_http.py b/odoo/addons/base/models/ir_http.py
index 951459bbc4be..a35e0b5afa7c 100644
--- a/odoo/addons/base/models/ir_http.py
+++ b/odoo/addons/base/models/ir_http.py
@@ -216,7 +216,9 @@ class IrHttp(models.AbstractModel):
@api.autovacuum
def _gc_sessions(self):
- http.root.session_store.vacuum()
+ ICP = self.env["ir.config_parameter"]
+ max_lifetime = int(ICP.get_param('sessions.max_inactivity_seconds', http.SESSION_LIFETIME))
+ http.root.session_store.vacuum(max_lifetime=max_lifetime)
@api.model
def get_translations_for_webclient(self, modules, lang):
diff --git a/odoo/http.py b/odoo/http.py
index aa7369e9a5f2..6b3f3fb1ce2d 100644
--- a/odoo/http.py
+++ b/odoo/http.py
@@ -261,9 +261,10 @@ if parse_version(werkzeug.__version__) >= parse_version('2.0.2'):
# let's add the websocket key only when appropriate.
ROUTING_KEYS.add('websocket')
-# The duration of a user session before it is considered expired,
-# three months.
-SESSION_LIFETIME = 60 * 60 * 24 * 90
+# The default duration of a user session cookie. Inactive sessions are reaped
+# server-side as well with a threshold that can be set via an optional
+# config parameter `sessions.max_inactivity_seconds` (default: SESSION_LIFETIME)
+SESSION_LIFETIME = 60 * 60 * 24 * 7
# The cache duration for static content from the filesystem, one week.
STATIC_CACHE = 60 * 60 * 24 * 7
@@ -858,8 +859,8 @@ class FilesystemSessionStore(sessions.FilesystemSessionStore):
session.should_rotate = False
self.save(session)
- def vacuum(self):
- threshold = time.time() - SESSION_LIFETIME
+ def vacuum(self, max_lifetime=SESSION_LIFETIME):
+ threshold = time.time() - max_lifetime
for fname in glob.iglob(os.path.join(root.session_store.path, '*', '*')):
path = os.path.join(root.session_store.path, fname)
with contextlib.suppress(OSError):
.. _HTTPocalypse: https://github.com/odoo/odoo/pull/78857
If you have had a prior experience with Git, you might be surprised to read such a lenghty commit message. It is the company policy to thoroughly describe the context of every change and to explain why they are necessary. This way we make sure that all contributors can understand the scope and rationnals of every feature and give feedback even if they were not part of the original design/specification of that feature. This is quite important for an open-source software company with hundreds external contributors
Contrary to ``git log`` that can list all commits that modified to a single file, ``git show`` lists all modifications over all the files that a single commit modified. In this example we see that two files were modified: ``odoo/addons/base/models/ir_http.py`` and ``odoo/http.py``. It is not relevant to this tutorial to understand what actually changed but you can give it a try.
Understand the branching model
==============================
The last section was about discovering git, discovering what the history and commits are for, it was also about understanding that multiple versions co-exist. This section is about going deeper in this notion of co-existing versions, called *branches* in git jargon. What's the difference between the various branches out there, namely the differences between stable, *master* and development branches.
Stable branches
---------------
Stable branches are branches that are deployed on Odoo Online and that are used by customers for their business. Those branches are labelled *stable* because developers don't try anything new on those branches, the list of features is frozen at the moment of the release and developers focus on fixing bugs.
The stable branches all reside in the official odoo/odoo github repository, they are the versions named "xx.0" and "saas-xx.y". The "xx.0" versions (e.g. 14.0, 15.0, 16.0, ...) are released every year during the Odoo Experience, most customers and partners use those versions. The "saas-xx.y" versions (saas-15.2, saas-16.1, ...) are released every two/three months and while available for all are generally only used by customers on Odoo Online.
.. example::
Since its release in late 2020, there have been more than 6.000 new commits on the 14.0 branch, of them 84% are bug fixes and 7% are feature improvement.
.. image:: git/plot-commits-14-0.png
:alt: Plot of the various [IMP] and [FIX] commits in the 14.0 branch indexed per month in the period Sept 2022 - March 2023
Master branch
-------------
The master branch is the branch where all new features are integrated once ready, tested and validated. This branch is halfway stable and halfway development, it is expected to always work bug-free but this assumption often fails because programming is hard and integrating many applications together is even more so. Because it is not that stable, the master branch is never deployed.
The master branch is split every two/three months and the new branch becomes the new stable release. The new branch isn't immediately deployed on Odoo Online, it first undergoes a stabilization process where the applications are extensively tested. Usually the new branch is made available to customers on Odoo Online after a few weeks.
The master branch is also hosted in the official odoo/odoo github repository.
.. note::
Because new features will be rarely added on the new stable branch, the process of splitting master in two is known at Odoo as the *freeze* even though bugfix commits will still be added.
.. example::
Since late 2020, there have been more than 18.000 new commits on the master branch, of them 58% are bug fixes, 32% are features and 5% are refactors.
.. image:: git/plot-commits-master.png
:alt: Plot of the various [IMP] and [FIX] commits in the master branch indexed per month in the period Sept 2022 - March 2023
Development branches
--------------------
The development branches are the branches were new features are being imagined, developed and tested. They are usually based on the latest revision of one of the official branches (stables or master) in which they will be ultimately integrated (if validated).
Contrary to the official branches, development branches are not hosted on the official odoo/odoo GitHub repository. All companies all individuals that contributes to Odoo work on their own *fork* (copy) of the official odoo/odoo repository, by example Odoo employees host their development branches on odoo-dev/odoo.
The integration is done via pull-requests (PR) on GitHub, a pull-request is a place where the developers publish their work for others to review and test. Reviews are mandatory at Odoo, all works must be validated by someone with "r+ rights" (a senior Odoo developer). Tests are mandatory too, every pull-request is ran against an extensible automated test suite that will block the pull-request in case of failure.
.. important::
The operation to integrate the work done in a development branch into an official one is known as *merging the branch into master/16.0/...*. This can be misleading as development branches are usually not integrated using a merge commit but are instead rebased and fast-forwaded, more on that later. Still "merge" is somewhat the de-facto way of designing this operation.
Branching model visualized
--------------------------
.. image:: git/odoo-workflow.drawio.png
:alt: Graph of the git workflow at Odoo
The graph shows a summary of the branching model inside the odoo/odoo (top half) and odoo-dev/odoo (bottom half) repositories. The graph features 8 branches: 2 stable branches (15.0 and 16.0), the master branch and 5 unammed development branches.
Each solid circle is a commit, blue for a new feature, greed for a release, yellow for a bugfix. Each callout poinThe callouts point to the last commit of their branch. the solid arrows show the order of the commits. The first commit of the master branch (top-left blue one) is present in all branches, the second commit of the master branch (second blue one) is present in 16.0, master and 4 of the unammed developemnt branches.
When a commit has two next commits it means that the branch was split. When the new branch is hosted in odoo/odoo, it means that there has been a new release, hence the green [REL] commits. When the new branch is hosted in odoo-dev/odoo (or in any other company or individual fork) it means that a new development has started.
New features are usually reserved for the master branch, the graph reflects that situation as once released stable branches only receive bugfixes.
Most features and bugfix can generally be grouped into a single comprehensive commit but sometime it is welcome to have multiple commits inside of a single branch, e.g. to fix a pre-existing bug that is revealed by a new feature. The development branches reflect that, most of them hold a single commit, except for the branch based on the latest master that hold multiple commits.
Not all development branches are ready for review, some features require several days/weeks to be completed but the branch is still saved on GitHub for the sake of saving it somewhere. The third unamed branch on the graph reflects that. That branch is also based on an outdated revision of the 16.0 official branch, the new commits from 16.0 should be integrated in the development branch via a *rebase*, more on that later.
Modify files
============
*Make them create a branch named "master-sandbox-<trigram>" based on the latest master, simply say that it is to isolate their changes from the ones of the others, don't explain branches yet*
*Deep dive the few status/diff/add/rm/restore/commit commands*
*Basically do stuff on the working directory, type status/diff to understand what changed, then add or rm or restore or commit, again status/diff/log to understand what happened*
Backup changes on Github
========================
*Make them push their branch so they can see it on github*
*Visit the various logs/diffs/blames/files this time using the github interface*
*Make them remove their branch so they can fetch it back from github*
Gather feedback
===============
*Basically pull requests, reviews, runbot*
*The ci/style will be red because we made them push commits with bad titles*
Cleanup the mess
================
*Explanation about keeping the history clean and writing good commit messages with hands on example in the history*
*Make them clean their branch basically using commit --amend, interactive rebase, and push --force-with-lease*
*Give a formal explaination of what branches are, with nice graphs*
*Make them fetch the latest master branch, show the difference git log master vs git log origin/master*
*Make them fast-forward their local master branch*
*Make them rebase their sandbox branch and push it back*
*Runbot should be green*

View File

@@ -1,19 +0,0 @@
The *drawio* graphes have been generated thanks to [diagrams.net].
To modify the graphes, open the web-app, import one of the `drawio` files and make your changes.
To save your modification, click *save* from the *file* menu and download the file (as XML).
To render a new PNG image, select everything with ctrl-a, click *export as PNG* from the *file*
menu and enter the following settings:
* Zoom 200%
* Border Width: 5
* [x] Selection Only
* Size: Diagram
* [ ] Transparent Background
* [ ] Shadow
* [ ] Grid
* [ ] Include a copy of my diagram
[diagrams.net]: https://app.diagrams.net/?src=about

View File

@@ -1,281 +0,0 @@
<mxfile host="app.diagrams.net" modified="2023-06-05T14:59:34.748Z" agent="Mozilla/5.0 (X11; Linux x86_64; rv:109.0) Gecko/20100101 Firefox/113.0" etag="CL9WIreMFmtxhxDaCxs9" version="21.3.0" type="device">
<diagram id="eDTlZYB63iw13qqHwxX-" name="Page-1">
<mxGraphModel dx="398" dy="213" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="850" pageHeight="1100" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="_4l3IvHe-3uS5yegyjGe-203" value="odoo-dev/odoo" style="rounded=0;whiteSpace=wrap;html=1;fontSize=11;verticalAlign=bottom;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="70" y="550" width="370" height="60" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-202" value="odoo/odoo" style="rounded=0;whiteSpace=wrap;html=1;fontSize=11;verticalAlign=top;fontStyle=1" parent="1" vertex="1">
<mxGeometry x="70" y="360" width="370" height="190" as="geometry" />
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-22" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=classic;endFill=1;" parent="1" source="_4l3IvHe-3uS5yegyjGe-63" target="UUBjyu-xDhq7s3pnQ-3j-14" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="203" y="517" as="sourcePoint" />
<mxPoint x="160" y="630" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-24" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=classic;endFill=1;" parent="1" source="_4l3IvHe-3uS5yegyjGe-67" target="_4l3IvHe-3uS5yegyjGe-170" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="203" y="517" as="sourcePoint" />
<mxPoint x="130" y="600" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-25" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=classic;endFill=1;" parent="1" source="_4l3IvHe-3uS5yegyjGe-69" target="_4l3IvHe-3uS5yegyjGe-168" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="293" y="487" as="sourcePoint" />
<mxPoint x="250" y="600" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-30" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=classic;endFill=1;" parent="1" source="_4l3IvHe-3uS5yegyjGe-40" target="_4l3IvHe-3uS5yegyjGe-162" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="360" y="430" as="sourcePoint" />
<mxPoint x="360" y="640" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-39" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="_4l3IvHe-3uS5yegyjGe-52" target="_4l3IvHe-3uS5yegyjGe-50" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="320" y="410" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-40" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="340" y="400" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-42" value="I" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Verdana;" parent="1" vertex="1">
<mxGeometry x="300" y="400" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-44" value="I" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Verdana;" parent="1" vertex="1">
<mxGeometry x="260" y="400" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-46" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="220" y="400" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-48" value="I" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Verdana;" parent="1" vertex="1">
<mxGeometry x="180" y="400" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-50" value="I" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Verdana;" parent="1" vertex="1">
<mxGeometry x="140" y="400" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-51" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;dashed=1;dashPattern=1 4;" parent="1" source="_4l3IvHe-3uS5yegyjGe-52" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="80" y="410" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-52" value="I" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Verdana;" parent="1" vertex="1">
<mxGeometry x="100" y="400" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-59" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;endArrow=classic;endFill=1;" parent="1" source="_4l3IvHe-3uS5yegyjGe-57" target="_4l3IvHe-3uS5yegyjGe-61" edge="1">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-57" value="R" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="130" y="430" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-61" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="160" y="460" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-63" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="190" y="490" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-67" value="R" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
<mxGeometry x="250" y="430" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-69" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="280" y="460" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-87" value="15.0" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;fontSize=11;size=5;position=0.25;position2=0;" parent="1" vertex="1">
<mxGeometry x="200" y="465" width="40" height="25" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-88" value="16.0" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;fontSize=11;size=5;position=0.25;position2=0;" parent="1" vertex="1">
<mxGeometry x="290" y="435" width="40" height="25" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-90" value="master" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;fontSize=11;size=5;position=0.25;position2=0;" parent="1" vertex="1">
<mxGeometry x="350" y="375" width="40" height="25" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-160" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="150" y="570" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-162" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="330" y="570" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-163" value="I" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Verdana;" parent="1" vertex="1">
<mxGeometry x="370" y="570" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-168" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="270" y="570" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-170" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
<mxGeometry x="230" y="570" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-1" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="180" y="410" as="targetPoint" />
<mxPoint x="160" y="410" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-2" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="220" y="410" as="targetPoint" />
<mxPoint x="200" y="410" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-3" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="260" y="410" as="targetPoint" />
<mxPoint x="240" y="410" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-4" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="300" y="410" as="targetPoint" />
<mxPoint x="280" y="410" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-5" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="340" y="410" as="targetPoint" />
<mxPoint x="320" y="410" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-6" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;endArrow=classic;endFill=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="177" y="477" as="sourcePoint" />
<mxPoint x="193" y="493" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-7" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;endArrow=classic;endFill=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="117" y="417" as="sourcePoint" />
<mxPoint x="133" y="433" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-8" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;endArrow=classic;endFill=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="237" y="417" as="sourcePoint" />
<mxPoint x="253" y="433" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-9" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;endArrow=classic;endFill=1;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="267" y="447" as="sourcePoint" />
<mxPoint x="283" y="463" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-10" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;endArrow=block;endFill=0;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="207" y="507" as="sourcePoint" />
<mxPoint x="223" y="523" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-11" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;dashed=1;" parent="1" vertex="1">
<mxGeometry x="220" y="520" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-12" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=0;entryDx=0;entryDy=0;endArrow=block;endFill=0;" parent="1" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="297" y="477" as="sourcePoint" />
<mxPoint x="313" y="493" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-13" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;dashed=1;" parent="1" vertex="1">
<mxGeometry x="310" y="490" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-14" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;endArrow=block;endFill=0;" parent="1" source="_4l3IvHe-3uS5yegyjGe-40" target="d4MCrwgoJ-HxTQabZ7jv-15" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="367" y="407" as="sourcePoint" />
<mxPoint x="383" y="423" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="d4MCrwgoJ-HxTQabZ7jv-15" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;dashed=1;" parent="1" vertex="1">
<mxGeometry x="380" y="400" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-193" value="" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;fontSize=11;size=10;position=0;position2=0.5;base=10;" parent="1" vertex="1">
<mxGeometry x="260" y="560" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-194" value="" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;fontSize=11;size=10;position=0;position2=0.5;base=10;" parent="1" vertex="1">
<mxGeometry x="220" y="560" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-199" value="" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;fontSize=11;size=10;position=0;position2=0.5;base=10;" parent="1" vertex="1">
<mxGeometry x="360" y="560" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-179" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=11;startArrow=none;startFill=0;endArrow=classic;endFill=1;dashed=1;" parent="1" source="_4l3IvHe-3uS5yegyjGe-160" target="d4MCrwgoJ-HxTQabZ7jv-11" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="230" y="540" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-188" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=11;startArrow=none;startFill=0;endArrow=classic;endFill=1;dashed=1;" parent="1" source="_4l3IvHe-3uS5yegyjGe-163" edge="1" target="d4MCrwgoJ-HxTQabZ7jv-15">
<mxGeometry relative="1" as="geometry">
<mxPoint x="390" y="420" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-182" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=11;startArrow=none;startFill=0;endArrow=classic;endFill=1;dashed=1;" parent="1" source="_4l3IvHe-3uS5yegyjGe-168" target="d4MCrwgoJ-HxTQabZ7jv-13" edge="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="313" y="507" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-1" value="Branch" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;fontSize=12;size=10;position=0;position2=0.5;base=10;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;spacing=4;" vertex="1" parent="1">
<mxGeometry x="450" y="490" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-2" value="[FIX]" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;spacing=4;" vertex="1" parent="1">
<mxGeometry x="450" y="400" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-3" value="[IMP]" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#dae8fc;strokeColor=#6c8ebf;fontFamily=Helvetica;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;spacing=4;" vertex="1" parent="1">
<mxGeometry x="450" y="430" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-4" value="[REL]" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#d5e8d4;strokeColor=#82b366;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;spacing=4;" vertex="1" parent="1">
<mxGeometry x="450" y="460" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-5" value="Next commit" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=classic;endFill=1;fontSize=12;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;spacing=14;" edge="1" parent="1">
<mxGeometry relative="1" as="geometry">
<mxPoint x="450" y="520" as="sourcePoint" />
<mxPoint x="470" y="540" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-8" value="Commit" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;spacing=4;" vertex="1" parent="1">
<mxGeometry x="450" y="370" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-9" value="Repository" style="whiteSpace=wrap;html=1;aspect=fixed;spacing=4;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;" vertex="1" parent="1">
<mxGeometry x="450" y="580" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-13" value="Pull-Request" style="group;spacing=4;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;" vertex="1" connectable="0" parent="1">
<mxGeometry x="450" y="550" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-12" value="" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;dashed=1;" vertex="1" parent="UUBjyu-xDhq7s3pnQ-3j-13">
<mxGeometry x="10" y="10" width="10" height="10" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-6" value="" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=12;startArrow=none;startFill=0;endArrow=classic;endFill=1;dashed=1;spacing=14;labelPosition=right;verticalLabelPosition=middle;align=left;verticalAlign=middle;endSize=4;" edge="1" parent="UUBjyu-xDhq7s3pnQ-3j-13" target="UUBjyu-xDhq7s3pnQ-3j-12">
<mxGeometry relative="1" as="geometry">
<mxPoint x="10" y="10" as="targetPoint" />
<mxPoint as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-14" value="F" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="100" y="570" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-16" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=classic;endFill=1;" edge="1" parent="1" source="_4l3IvHe-3uS5yegyjGe-63" target="_4l3IvHe-3uS5yegyjGe-160">
<mxGeometry relative="1" as="geometry">
<mxPoint x="203" y="517" as="sourcePoint" />
<mxPoint x="127" y="583" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-17" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;fontSize=11;startArrow=none;startFill=0;endArrow=classic;endFill=1;dashed=1;" edge="1" parent="1" source="UUBjyu-xDhq7s3pnQ-3j-14" target="d4MCrwgoJ-HxTQabZ7jv-11">
<mxGeometry relative="1" as="geometry">
<mxPoint x="232" y="546" as="targetPoint" />
<mxPoint x="178" y="584" as="sourcePoint" />
</mxGeometry>
</mxCell>
<mxCell id="_4l3IvHe-3uS5yegyjGe-192" value="" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;fontSize=11;size=10;position=0;position2=0.5;base=10;" parent="1" vertex="1">
<mxGeometry x="140" y="560" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-18" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=classic;endFill=1;" edge="1" parent="1" source="_4l3IvHe-3uS5yegyjGe-162" target="_4l3IvHe-3uS5yegyjGe-163">
<mxGeometry relative="1" as="geometry">
<mxPoint x="299" y="490" as="sourcePoint" />
<mxPoint x="291" y="580" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="UUBjyu-xDhq7s3pnQ-3j-19" value="" style="shape=callout;whiteSpace=wrap;html=1;perimeter=calloutPerimeter;fontSize=11;size=10;position=0;position2=0.5;base=10;" vertex="1" parent="1">
<mxGeometry x="90" y="560" width="20" height="20" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -32,7 +32,7 @@ msgstr ""
"POT-Creation-Date: 2023-03-02 07:38+0000\n"
"PO-Revision-Date: 2020-09-22 14:40+0000\n"
"Last-Translator: Braulio D. López Vázquez <bdl@odoo.com>, 2023\n"
"Language-Team: Spanish (https://app.transifex.com/odoo/teams/41243/es/)\n"
"Language-Team: Spanish (https://www.transifex.com/odoo/teams/41243/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -18,7 +18,7 @@ msgstr ""
"POT-Creation-Date: 2023-01-03 07:53+0000\n"
"PO-Revision-Date: 2021-07-02 09:18+0000\n"
"Last-Translator: Braulio D. López Vázquez <bdl@odoo.com>, 2023\n"
"Language-Team: Spanish (https://app.transifex.com/odoo/teams/41243/es/)\n"
"Language-Team: Spanish (https://www.transifex.com/odoo/teams/41243/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -10,6 +10,7 @@
# Nicolás Broggi <rnbroggi@gmail.com>, 2021
# Jon Perez <jop@odoo.com>, 2021
# Leonardo J. Caballero G. <leonardocaballero@gmail.com>, 2021
# Pedro M. Baeza <pedro.baeza@tecnativa.com>, 2021
# Jesús Alan Ramos Rodríguez <alan.ramos@jarsa.com.mx>, 2021
# Lina Maria Avendaño Carvajal <lina8823@gmail.com>, 2021
# Alejandro Die Sanchis <marketing@domatix.com>, 2021
@@ -22,11 +23,11 @@
# jabelchi, 2021
# Francisco de la Peña <fran@fran.cr>, 2021
# Martin Trigaux, 2021
# Daniela Cervantes <dace@odoo.com>, 2021
# Marian Cuadra, 2022
# Patricia Gutiérrez Capetillo <pagc@odoo.com>, 2022
# Lucia Pacheco <lpo@odoo.com>, 2023
# Braulio D. López Vázquez <bdl@odoo.com>, 2023
# Pedro M. Baeza <pedro.baeza@tecnativa.com>, 2023
#
#, fuzzy
msgid ""
@@ -35,7 +36,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-02 07:38+0000\n"
"PO-Revision-Date: 2021-05-18 05:18+0000\n"
"Last-Translator: Pedro M. Baeza <pedro.baeza@tecnativa.com>, 2023\n"
"Last-Translator: Braulio D. López Vázquez <bdl@odoo.com>, 2023\n"
"Language-Team: Spanish (https://app.transifex.com/odoo/teams/41243/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -389,7 +390,7 @@ msgstr "Peso"
#: ../../content/applications/websites/ecommerce/managing_products/variants.rst:56
msgid "Cost"
msgstr "Coste"
msgstr "Costo"
#: ../../content/applications/websites/ecommerce/managing_products/variants.rst:59
msgid ""

View File

@@ -63,10 +63,10 @@
# Christelle Pinchart <cpi@odoo.com>, 2022
# Cécile Collart <cco@odoo.com>, 2022
# ae421c2293dd329c1e0f68f8f29fafa8_9d513c4, 2023
# jb78180 <jblum66@gmail.com>, 2023
# 5cad1b0f1319985f8413d48b70c3c192_b038c35, 2023
# Martin Trigaux, 2023
# Jolien De Paepe, 2023
# jb78180 <jblum66@gmail.com>, 2023
#
#, fuzzy
msgid ""
@@ -75,8 +75,8 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-02 07:38+0000\n"
"PO-Revision-Date: 2021-05-18 05:17+0000\n"
"Last-Translator: jb78180 <jblum66@gmail.com>, 2023\n"
"Language-Team: French (https://app.transifex.com/odoo/teams/41243/fr/)\n"
"Last-Translator: Jolien De Paepe, 2023\n"
"Language-Team: French (https://www.transifex.com/odoo/teams/41243/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -11334,8 +11334,6 @@ msgid ""
"In Odoo, payments can either be linked automatically to an invoice or bill "
"or be stand-alone records for use at a later date."
msgstr ""
"Dans Odoo, un paiement peut être soit directement lié à une facture ou être "
"un enregistrement autonome pour une utilisation ultérieure :"
#: ../../content/applications/finance/accounting/receivables/customer_payments/recording.rst:8
msgid ""

View File

@@ -35,7 +35,7 @@ msgstr ""
"POT-Creation-Date: 2023-03-02 07:38+0000\n"
"PO-Revision-Date: 2021-05-18 05:18+0000\n"
"Last-Translator: Jolien De Paepe, 2023\n"
"Language-Team: French (https://app.transifex.com/odoo/teams/41243/fr/)\n"
"Language-Team: French (https://www.transifex.com/odoo/teams/41243/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -25,7 +25,6 @@
# Martin Trigaux, 2023
# Сергей Шебанин <sergey@shebanin.ru>, 2023
# Alena Vlasova, 2023
# alenafairy, 2023
#
#, fuzzy
msgid ""
@@ -34,7 +33,7 @@ msgstr ""
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-03-02 07:38+0000\n"
"PO-Revision-Date: 2021-05-18 05:17+0000\n"
"Last-Translator: alenafairy, 2023\n"
"Last-Translator: Alena Vlasova, 2023\n"
"Language-Team: Russian (https://app.transifex.com/odoo/teams/41243/ru/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -22438,7 +22437,7 @@ msgstr ""
#: ../../content/applications/finance/fiscal_localizations/mexico.rstNone
msgid "Previous period"
msgstr "Предыдущий период"
msgstr ""
#: ../../content/applications/finance/fiscal_localizations/mexico.rst:932
msgid "This is how the Balance Sheet looks like:"

View File

@@ -48,7 +48,7 @@
# 老窦 北京 <2662059195@qq.com>, 2022
# Mandy Choy <mnc@odoo.com>, 2022
# Raymond Yu <cl_yu@hotmail.com>, 2023
# Jeffery CHEN <jeffery9@gmail.com>, 2023
# Jeffery CHEN Fan <jeffery9@gmail.com>, 2023
# Martin Trigaux, 2023
# Emily Jia <eji@odoo.com>, 2023
#
@@ -60,7 +60,7 @@ msgstr ""
"POT-Creation-Date: 2023-03-02 07:38+0000\n"
"PO-Revision-Date: 2021-05-18 05:17+0000\n"
"Last-Translator: Emily Jia <eji@odoo.com>, 2023\n"
"Language-Team: Chinese (China) (https://app.transifex.com/odoo/teams/41243/zh_CN/)\n"
"Language-Team: Chinese (China) (https://www.transifex.com/odoo/teams/41243/zh_CN/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

View File

@@ -62,7 +62,6 @@ applications/sales/point_of_sale/payment/adyen.rst applications/sales/point_of_s
applications/sales/point_of_sale/payment/ingenico.rst applications/sales/point_of_sale/payment_methods/terminals/ingenico.rst # /payment/* -> /payment_methods/terminals/*
applications/sales/point_of_sale/payment/six.rst applications/sales/point_of_sale/payment_methods/terminals/six.rst # /payment/* -> /payment_methods/terminals/*
applications/sales/point_of_sale/payment/vantiv.rst applications/sales/point_of_sale/payment_methods/terminals/vantiv.rst # /payment/* -> /payment_methods/terminals/*
applications/sales/point_of_sale/restaurant/fiscal_position.rst applications/sales/point_of_sale/pricing/fiscal_position.rst # /restaurant/* -> /pricing/*
applications/sales/point_of_sale/restaurant/restaurant.rst applications/sales/point_of_sale/restaurant/floors_tables.rst
applications/sales/point_of_sale/restaurant/split.rst applications/sales/point_of_sale/restaurant/bill_printing.rst
applications/sales/point_of_sale/shop/cash_rounding.rst applications/sales/point_of_sale/pricing/cash_rounding.rst # /shop/* -> /pricing/*
@@ -91,13 +90,6 @@ applications/websites/website/publish/multi_website.rst applications/websites/we
applications/websites/website/publish/on-premise_geo-ip-installation.rst applications/websites/website/configuration/on-premise_geo-ip-installation.rst # publish/* -> configuration/*
applications/websites/website/publish/translate.rst applications/websites/website/configuration/translate.rst # publish/* -> configuration/*
# applications/surveys
applications/marketing/surveys/overview.rst applications/marketing/surveys.rst # remove survey overview folder
applications/marketing/surveys/overview/create.rst applications/marketing/surveys/create.rst # remove survey overview folder
applications/marketing/surveys/overview/scoring.rst applications/marketing/surveys/scoring.rst # remove survey overview folder
applications/marketing/surveys/overview/time_random.rst applications/marketing/surveys/time_random.rst # remove survey overview folder
# developer/howtos
developer/api/external_api.rst developer/reference/external_api.rst # reorganize the developer doc
@@ -131,12 +123,6 @@ developer/howtos/web.rst developer/tutorials/web.rst
developer/howtos/website.rst developer/tutorials/website.rst # reorganize the developer doc
developer/iot.rst developer/howtos/connect_device.rst # reorganize the developer doc
# applications/marketing
applications/marketing/social_marketing/overview/livechat.rst applications/marketing/social_marketing/essentials/sms_essentials.rst
applications/marketing/social_marketing/overview/push_notifications.rst applications/marketing/social_marketing/essentials/sms_essentials.rst
applications/marketing/social_marketing/overview/create_posts.rst applications/marketing/social_marketing/essentials/sms_essentials.rst
# developer/misc
developer/misc/api/external_api.rst developer/api/external_api.rst # better location for misc/ content (#2350)