Precommit V14

This commit is contained in:
Darío Lodeiros
2020-10-21 12:54:21 +02:00
parent a2ead12060
commit 9554737792
50 changed files with 740 additions and 458 deletions

13
.copier-answers.yml Normal file
View File

@@ -0,0 +1,13 @@
# Do NOT update manually; changes here will be overwritten by Copier
_commit: v1.0.2
_src_path: https://github.com/OCA/oca-addons-repo-template.git
dependency_installation_mode: OCA
include_wkhtmltopdf: false
odoo_version: 14.0
rebel_module_groups: []
repo_description:
All-in-One Property Management System (PMS) focused on medium-sizeations.
repo_name: Property Management System
repo_slug: pms
travis_apt_packages: []
travis_apt_sources: []

74
.gitignore vendored
View File

@@ -1,5 +1,75 @@
*.pyc # Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
/.venv
/.pytest_cache
.settings/ # C extensions
*.so
# Distribution / packaging
.Python
env/
bin/
build/
develop-eggs/
dist/
eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg
*.eggs
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.cache
nosetests.xml
coverage.xml
# Translations
*.mo
# Pycharm
.idea .idea
# Eclipse
.settings
# Visual Studio cache/options directory
.vs/
.vscode
# OSX Files
.DS_Store
# Django stuff:
*.log
# Mr Developer
.mr.developer.cfg
.project
.pydevproject
# Rope
.ropeproject
# Sphinx documentation
docs/_build/
# Backup files
*~
*.swp
# OCA rules
!static/lib/

View File

@@ -10,4 +10,3 @@ known_odoo=odoo
known_odoo_addons=odoo.addons known_odoo_addons=odoo.addons
sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER
default_section=THIRDPARTY default_section=THIRDPARTY
known_third_party=openerp,werkzeug

View File

@@ -1,5 +1,7 @@
exclude: | exclude: |
(?x) (?x)
# NOT INSTALLABLE ADDONS
# END NOT INSTALLABLE ADDONS
# Files and folders generated by bots, to avoid loops # Files and folders generated by bots, to avoid loops
^setup/|/static/description/index\.html$| ^setup/|/static/description/index\.html$|
# Maybe reactivate this when all README files include prettier ignore tags? # Maybe reactivate this when all README files include prettier ignore tags?
@@ -12,28 +14,42 @@ exclude: |
(LICENSE.*|COPYING.*) (LICENSE.*|COPYING.*)
default_language_version: default_language_version:
python: python3 python: python3
node: "14.13.0"
repos: repos:
- repo: local
hooks:
# These files are most likely copier diff rejection junks; if found,
# review them manually, fix the problem (if needed) and remove them
- id: forbidden-files
name: forbidden files
entry: found forbidden files; remove them
language: fail
files: "\\.rej$"
- repo: https://github.com/oca/maintainer-tools
rev: 2c66e72
hooks:
# update the NOT INSTALLABLE ADDONS section above
- id: oca-update-pre-commit-excluded-addons
- repo: https://github.com/myint/autoflake
rev: v1.4
hooks:
- id: autoflake
args: ["-i", "--ignore-init-module-imports"]
- repo: https://github.com/psf/black - repo: https://github.com/psf/black
rev: 19.10b0 rev: 20.8b1
hooks: hooks:
- id: black - id: black
- repo: https://github.com/prettier/prettier - repo: https://github.com/prettier/prettier
rev: "1.19.1" rev: 2.1.2
hooks: hooks:
- id: prettier - id: prettier
# TODO Avoid awebdeveloper/pre-commit-prettier if possible name: prettier + plugin-xml
# HACK https://github.com/prettier/prettier/issues/7407
- repo: https://github.com/awebdeveloper/pre-commit-prettier
rev: v0.0.1
hooks:
- id: prettier
name: prettier xml plugin
additional_dependencies: additional_dependencies:
- "prettier@1.19.1" - "@prettier/plugin-xml@0.12.0"
- "@prettier/plugin-xml@0.7.2" args:
files: \.xml$ - --plugin=@prettier/plugin-xml
- repo: https://github.com/pre-commit/mirrors-eslint - repo: https://github.com/pre-commit/mirrors-eslint
rev: v6.8.0 rev: v7.8.1
hooks: hooks:
- id: eslint - id: eslint
verbose: true verbose: true
@@ -41,7 +57,7 @@ repos:
- --color - --color
- --fix - --fix
- repo: https://github.com/pre-commit/pre-commit-hooks - repo: https://github.com/pre-commit/pre-commit-hooks
rev: v2.4.0 rev: v3.2.0
hooks: hooks:
- id: trailing-whitespace - id: trailing-whitespace
# exclude autogenerated files # exclude autogenerated files
@@ -62,41 +78,47 @@ repos:
- id: check-xml - id: check-xml
- id: mixed-line-ending - id: mixed-line-ending
args: ["--fix=lf"] args: ["--fix=lf"]
- repo: https://gitlab.com/pycqa/flake8 - repo: https://github.com/asottile/pyupgrade
rev: 3.7.9 rev: v2.7.2
hooks:
- id: pyupgrade
- repo: https://github.com/PyCQA/isort
rev: 5.5.1
hooks:
- id: isort
name: isort except __init__.py
args:
- --settings=.
exclude: /__init__\.py$
- repo: https://github.com/acsone/setuptools-odoo
rev: 2.5.10
hooks:
- id: setuptools-odoo-make-default
- repo: https://gitlab.com/PyCQA/flake8
rev: 3.8.3
hooks: hooks:
- id: flake8 - id: flake8
name: flake8 except __init__.py name: flake8 except __init__.py
exclude: /__init__\.py$ exclude: /__init__\.py$
additional_dependencies: ["flake8-bugbear==19.8.0"] additional_dependencies: ["flake8-bugbear==20.1.4"]
- id: flake8 - id: flake8
name: flake8 only __init__.py name: flake8 only __init__.py
args: ["--extend-ignore=F401"] # ignore unused imports in __init__.py args: ["--extend-ignore=F401"] # ignore unused imports in __init__.py
files: /__init__\.py$ files: /__init__\.py$
additional_dependencies: ["flake8-bugbear==19.8.0"] additional_dependencies: ["flake8-bugbear==20.1.4"]
- repo: https://github.com/pre-commit/mirrors-pylint - repo: https://github.com/PyCQA/pylint
rev: v2.3.1 rev: pylint-2.5.3
hooks: hooks:
- id: pylint - id: pylint
name: pylint with optional checks name: pylint with optional checks
args: ["--rcfile=.pylintrc", "--exit-zero"] args:
- --rcfile=.pylintrc
- --exit-zero
verbose: true verbose: true
additional_dependencies: ["pylint-odoo==3.1.0"] additional_dependencies: &pylint_deps
- pylint-odoo==3.5.0
- id: pylint - id: pylint
name: pylint with mandatory checks name: pylint with mandatory checks
args: ["--rcfile=.pylintrc-mandatory"] args:
additional_dependencies: ["pylint-odoo==3.1.0"] - --rcfile=.pylintrc-mandatory
- repo: https://github.com/asottile/pyupgrade additional_dependencies: *pylint_deps
rev: v1.26.2
hooks:
- id: pyupgrade
- repo: https://github.com/pre-commit/mirrors-isort
rev: v4.3.21
hooks:
- id: isort
name: isort except __init__.py
exclude: /__init__\.py$
- repo: https://github.com/acsone/setuptools-odoo
rev: 2.5.2
hooks:
- id: setuptools-odoo-make-default

View File

@@ -45,8 +45,6 @@ enable=anomalous-backslash-in-string,
method-inverse, method-inverse,
method-required-super, method-required-super,
method-search, method-search,
missing-import-error,
missing-manifest-dependency,
openerp-exception-warning, openerp-exception-warning,
pointless-statement, pointless-statement,
pointless-string-statement, pointless-string-statement,
@@ -72,6 +70,7 @@ enable=anomalous-backslash-in-string,
deprecated-module, deprecated-module,
file-not-used, file-not-used,
invalid-commit, invalid-commit,
missing-manifest-dependency,
missing-newline-extrafiles, missing-newline-extrafiles,
missing-readme, missing-readme,
no-utf8-coding-comment, no-utf8-coding-comment,
@@ -81,6 +80,7 @@ enable=anomalous-backslash-in-string,
too-complex, too-complex,
unnecessary-utf8-coding-comment unnecessary-utf8-coding-comment
[REPORTS] [REPORTS]
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg} msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
output-format=colorized output-format=colorized

View File

@@ -38,8 +38,6 @@ enable=anomalous-backslash-in-string,
method-inverse, method-inverse,
method-required-super, method-required-super,
method-search, method-search,
missing-import-error,
missing-manifest-dependency,
openerp-exception-warning, openerp-exception-warning,
pointless-statement, pointless-statement,
pointless-string-statement, pointless-string-statement,

View File

@@ -1,49 +1,48 @@
language: python language: python
cache:
directories:
- $HOME/.cache/pip
- $HOME/.cache/pre-commit
python: python:
- "3.5" - "3.6"
sudo: false
cache: pip
addons: addons:
postgresql: "9.2" # minimal postgresql version for the daterange method postgresql: "9.6"
apt: apt:
packages: packages:
- expect-dev # provides unbuffer utility - expect-dev # provides unbuffer utility
- python-lxml # because pip installation is slow
stages:
- linting
- test
jobs:
include:
- stage: linting
name: "pre-commit"
install: pip install pre-commit
script: pre-commit run --all --show-diff-on-failure --verbose --color always
after_success:
before_install:
- stage: test
env:
- TESTS=1 ODOO_REPO="odoo/odoo" MAKEPOT="1"
- stage: test
env:
- TESTS=1 ODOO_REPO="OCA/OCB"
env: env:
global: global:
- VERSION="11.0" TESTS="0" LINT_CHECK="0" TRANSIFEX="0" MAKEPOT="0" - VERSION="14.0" TESTS="0" LINT_CHECK="0" MAKEPOT="0"
# - TRANSIFEX_USER='transbot@odoo-community.org'
# - secure: "XLhGdCIh86zcqww9qBpnk8Xqsf1Pcgw9SKr7X0KYBHJofHj4Z6Kq/oVFjpZ1LSjadsaABKbwY7h4hvKEpxZwptCv+fNTOKYy7hXFLGYnDeNeWu4zA4LI7TA5uPvyZjZ+g2xc+9dzR/VbfRHNqjvmgiEidxxqLeOnNFZ5CHdOdCw="
matrix:
# Option temporarily disabled
#- LINT_CHECK="1"
- TESTS="1" ODOO_REPO="odoo/odoo"
- TESTS="1" ODOO_REPO="OCA/OCB"
install: install:
- git clone https://github.com/OCA/maintainer-quality-tools.git - git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git
${HOME}/maintainer-quality-tools --depth=1 ${HOME}/maintainer-quality-tools
- export PATH=${HOME}/maintainer-quality-tools/travis:${PATH} - export PATH=${HOME}/maintainer-quality-tools/travis:${PATH}
- git clone -b ${VERSION} https://github.com/OCA/web.git ${HOME}/dependencies/web
--depth=1
- git clone -b ${VERSION} https://github.com/OCA/partner-contact.git
${HOME}/dependencies/partner-contact --depth=1
- git clone -b ${VERSION} https://github.com/OCA/account-payment.git
${HOME}/dependencies/account-payment --depth=1
- git clone -b ${VERSION} https://github.com/OCA/connector.git
${HOME}/dependencies/connector --depth=1
- git clone -b ${VERSION} https://github.com/OCA/queue.git ${HOME}/dependencies/queue
--depth=1
- pip install odoorpc
- pip install cachetools>=2.0.1
- travis_install_nightly - travis_install_nightly
script: script:
- travis_wait travis_run_tests - travis_run_tests
after_success: after_success:
- travis_after_tests_success - travis_after_tests_success

10
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,10 @@
# OCA Guidelines
Please follow the official guide from the
[OCA Guidelines page](https://odoo-community.org/page/contributing).
## Project Specific Guidelines
<!-- /!\ do not modify above this line -->
This project does not have specific coding guidelines.

10
LICENSE
View File

@@ -1,7 +1,7 @@
GNU AFFERO GENERAL PUBLIC LICENSE GNU AFFERO GENERAL PUBLIC LICENSE
Version 3, 19 November 2007 Version 3, 19 November 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@@ -633,8 +633,8 @@ the "copyright" line and a pointer to where the full notice is found.
Copyright (C) <year> <name of author> Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published it under the terms of the GNU Affero General Public License as published by
by the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
@@ -643,7 +643,7 @@ the "copyright" line and a pointer to where the full notice is found.
GNU Affero General Public License for more details. GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
@@ -658,4 +658,4 @@ specific requirements.
You should also get your employer (if you work as a programmer) or school, You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary. if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>. <https://www.gnu.org/licenses/>.

View File

@@ -1,22 +1,36 @@
[![Build Status](https://travis-ci.org/hootel/hootel.svg?branch=11.0)](https://travis-ci.org/hootel/hootel) [![codecov](https://codecov.io/gh/hootel/hootel/branch/11.0/graph/badge.svg)](https://codecov.io/gh/hootel/hootel) ![Unstable](https://img.shields.io/badge/stability-unstable-yellow.svg) [![Runbot Status](https://runbot.odoo-community.org/runbot/badge/flat//14.0.svg)](https://runbot.odoo-community.org/runbot/repo/github-com-oca-pms-)
[![Build Status](https://travis-ci.com/OCA/pms.svg?branch=14.0)](https://travis-ci.com/OCA/pms)
[![codecov](https://codecov.io/gh/OCA/pms/branch/14.0/graph/badge.svg)](https://codecov.io/gh/OCA/pms)
[![Translation Status](https://translation.odoo-community.org/widgets/pms-14-0/-/svg-badge.svg)](https://translation.odoo-community.org/engage/pms-14-0/?utm_source=widget)
# ROOMDOO <!-- /!\ do not modify above this line -->
All-in-One Property Management System (PMS) focused on medium-sized hotels for managing every aspect of your property's daily operations.
You will find modules for: # Property Management System
- Manage hotel properties with multi-hotel and multi-company support. All-in-One Property Management System (PMS) focused on medium-sizeations.
- Manage your rooms inventory, reservations, check-in, daily reports, board services, rate and restriction plans.
- Handle reservations in a user friendly calendar management view.
- Connect your hotel with a channel manager for booking though Online Travel Agencies, such as, Booking.com, Expedia, Hotelbeds, ...
- Revenue management tools for daily pricing and availability strategies.
<!-- /!\ do not modify below this line -->
Bug Tracker <!-- prettier-ignore-start -->
-----------
Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback here.
Contributing [//]: # (addons)
------------
Do you want to contribute? Please, do not hesitate to contact any of the current contributors :) This part will be replaced when running the oca-gen-addons-table script from OCA/maintainer-tools.
[//]: # (end addons)
<!-- prettier-ignore-end -->
## Licenses
This repository is licensed under [AGPL-3.0](LICENSE).
However, each module can have a totally different license, as long as they adhere to OCA
policy. Consult each module's `__manifest__.py` file, which contains a `license` key
that explains its license.
----
OCA, or the [Odoo Community Association](http://odoo-community.org/), is a nonprofit
organization whose mission is to support the collaborative development of Odoo features
and promote its widespread use.

1
oca_dependencies.txt Normal file
View File

@@ -0,0 +1 @@
# See https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#oca_dependencies-txt

View File

@@ -1,4 +1,5 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import models from . import models
# from . import wizard # from . import wizard

View File

@@ -61,8 +61,14 @@
"views/product_pricelist_views.xml", "views/product_pricelist_views.xml",
"views/product_template_views.xml", "views/product_template_views.xml",
"views/webclient_templates.xml", "views/webclient_templates.xml",
"views/ir_sequence_views.xml" "views/ir_sequence_views.xml",
],
"demo": [
"demo/pms_master_data.xml",
"demo/pms_folio.xml",
"demo/pms_reservation.xml",
],
"qweb": [
"static/src/xml/pms_base_templates.xml",
], ],
"demo": ["demo/pms_master_data.xml", "demo/pms_folio.xml"],
"qweb": ["static/src/xml/pms_base_templates.xml",],
} }

View File

@@ -3,9 +3,17 @@
<data noupdate="1"> <data noupdate="1">
<!-- pms.users --> <!-- pms.users -->
<record id="base.user_root" model="res.users"> <record id="base.user_root" model="res.users">
<field name="company_id" ref="base.main_company" />
<field name="company_ids" eval="[(4, ref('base.main_company'))]" />
<field name="pms_property_id" ref="main_pms_property" />
<field name="pms_property_ids" eval="[(4, ref('main_pms_property'))]" />
<field name="groups_id" eval="[(4,ref('pms.group_pms_manager'))]" /> <field name="groups_id" eval="[(4,ref('pms.group_pms_manager'))]" />
</record> </record>
<record id="base.user_admin" model="res.users"> <record id="base.user_admin" model="res.users">
<field name="company_id" ref="base.main_company" />
<field name="company_ids" eval="[(4, ref('base.main_company'))]" />
<field name="pms_property_id" ref="main_pms_property" />
<field name="pms_property_ids" eval="[(4, ref('main_pms_property'))]" />
<field name="groups_id" eval="[(4,ref('pms.group_pms_manager'))]" /> <field name="groups_id" eval="[(4,ref('pms.group_pms_manager'))]" />
</record> </record>
<!-- Basic pms --> <!-- Basic pms -->
@@ -26,17 +34,5 @@
<field name="website">https://www.commitsun.com</field> <field name="website">https://www.commitsun.com</field>
<field name="folio_sequence_id" ref="pms.seq_pms_folio" /> <field name="folio_sequence_id" ref="pms.seq_pms_folio" />
</record> </record>
<record model="res.users" id="base.user_root">
<field name="company_id" ref="base.main_company" />
<field name="company_ids" eval="[(4, ref('base.main_company'))]" />
<field name="pms_property_id" ref="main_pms_property" />
<field name="pms_property_ids" eval="[(4, ref('main_pms_property'))]" />
</record>
<record model="res.users" id="base.user_admin">
<field name="company_id" ref="base.main_company" />
<field name="company_ids" eval="[(4, ref('base.main_company'))]" />
<field name="pms_property_id" ref="main_pms_property" />
<field name="pms_property_ids" eval="[(4, ref('main_pms_property'))]" />
</record>
</data> </data>
</odoo> </odoo>

View File

@@ -286,15 +286,16 @@
<!-- room.closure.reason --> <!-- room.closure.reason -->
<record id="pms_room_closure_reason_0" model="room.closure.reason"> <record id="pms_room_closure_reason_0" model="room.closure.reason">
<field name="name">Maintenance</field> <field name="name">Maintenance</field>
<field <field name="description">
name="description" Used for closing of rooms which require a maintenance. You can specify
>Used for closing of rooms which require a maintenance. You can specify the reason in the own reservation.</field> the reason in the own reservation.
</field>
</record> </record>
<record id="pms_room_closure_reason_1" model="room.closure.reason"> <record id="pms_room_closure_reason_1" model="room.closure.reason">
<field name="name">VIP Privacy</field> <field name="name">VIP Privacy</field>
<field <field name="description">
name="description" Used for closing of rooms for extra privacy.
>Used for closing of rooms for extra privacy.</field> </field>
</record> </record>
<!-- Multi pms Demo --> <!-- Multi pms Demo -->
<record id="demo_pms_room_type_restriction" model="pms.room.type.restriction"> <record id="demo_pms_room_type_restriction" model="pms.room.type.restriction">

View File

@@ -10,7 +10,6 @@
<field name="checkin" eval="DateTime.today() + timedelta(8)" /> <field name="checkin" eval="DateTime.today() + timedelta(8)" />
<field name="checkout" eval="DateTime.today() + timedelta(9)" /> <field name="checkout" eval="DateTime.today() + timedelta(9)" />
<field name="board_service_room_id" ref="pms_board_service_room_2" /> <field name="board_service_room_id" ref="pms_board_service_room_2" />
</record> </record>
<record id="pms_reservation_1" model="pms.reservation"> <record id="pms_reservation_1" model="pms.reservation">
<field name="reservation_type">"out"</field> <field name="reservation_type">"out"</field>
@@ -61,7 +60,6 @@
<field name="checkin" eval="DateTime.today()" /> <field name="checkin" eval="DateTime.today()" />
<field name="checkout" eval="DateTime.today() + timedelta(3)" /> <field name="checkout" eval="DateTime.today() + timedelta(3)" />
<field name="board_service_room_id" ref="pms_board_service_room_2" /> <field name="board_service_room_id" ref="pms_board_service_room_2" />
</record> </record>
<record id="pms_reservation_7" model="pms.reservation"> <record id="pms_reservation_7" model="pms.reservation">
<field name="partner_id" ref="base.res_partner_address_10" /> <field name="partner_id" ref="base.res_partner_address_10" />
@@ -71,7 +69,6 @@
<field name="checkin" eval="DateTime.today()" /> <field name="checkin" eval="DateTime.today()" />
<field name="checkout" eval="DateTime.today() + timedelta(3)" /> <field name="checkout" eval="DateTime.today() + timedelta(3)" />
<field name="board_service_room_id" ref="pms_board_service_room_0" /> <field name="board_service_room_id" ref="pms_board_service_room_0" />
</record> </record>
<record id="pms_reservation_8" model="pms.reservation"> <record id="pms_reservation_8" model="pms.reservation">
<field name="partner_id" ref="base.res_partner_address_13" /> <field name="partner_id" ref="base.res_partner_address_13" />
@@ -81,7 +78,6 @@
<field name="checkin" eval="DateTime.today() + timedelta(7)" /> <field name="checkin" eval="DateTime.today() + timedelta(7)" />
<field name="checkout" eval="DateTime.today() + timedelta(8)" /> <field name="checkout" eval="DateTime.today() + timedelta(8)" />
<field name="board_service_room_id" ref="pms_board_service_room_1" /> <field name="board_service_room_id" ref="pms_board_service_room_1" />
</record> </record>
<record id="pms_reservation_9" model="pms.reservation"> <record id="pms_reservation_9" model="pms.reservation">
<field name="partner_id" ref="base.res_partner_address_15" /> <field name="partner_id" ref="base.res_partner_address_15" />
@@ -108,7 +104,6 @@
<field name="checkin" eval="DateTime.today()" /> <field name="checkin" eval="DateTime.today()" />
<field name="checkout" eval="DateTime.today() + timedelta(4)" /> <field name="checkout" eval="DateTime.today() + timedelta(4)" />
<field name="board_service_room_id" ref="pms_board_service_room_2" /> <field name="board_service_room_id" ref="pms_board_service_room_2" />
</record> </record>
<record id="pms_reservation_12" model="pms.reservation"> <record id="pms_reservation_12" model="pms.reservation">
<field name="partner_id" ref="base.res_partner_address_10" /> <field name="partner_id" ref="base.res_partner_address_10" />
@@ -127,7 +122,6 @@
<field name="checkin" eval="DateTime.today() + timedelta(11)" /> <field name="checkin" eval="DateTime.today() + timedelta(11)" />
<field name="checkout" eval="DateTime.today() + timedelta(13)" /> <field name="checkout" eval="DateTime.today() + timedelta(13)" />
<field name="board_service_room_id" ref="pms_board_service_room_0" /> <field name="board_service_room_id" ref="pms_board_service_room_0" />
</record> </record>
<record id="pms_reservation_14" model="pms.reservation"> <record id="pms_reservation_14" model="pms.reservation">
<field name="partner_id" ref="base.res_partner_address_33" /> <field name="partner_id" ref="base.res_partner_address_33" />
@@ -163,7 +157,6 @@
<field name="checkin" eval="DateTime.today()" /> <field name="checkin" eval="DateTime.today()" />
<field name="checkout" eval="DateTime.today() + timedelta(4)" /> <field name="checkout" eval="DateTime.today() + timedelta(4)" />
<field name="board_service_room_id" ref="pms_board_service_room_2" /> <field name="board_service_room_id" ref="pms_board_service_room_2" />
</record> </record>
<record id="pms_reservation_18" model="pms.reservation"> <record id="pms_reservation_18" model="pms.reservation">
<field name="partner_id" ref="base.res_partner_12" /> <field name="partner_id" ref="base.res_partner_12" />
@@ -262,7 +255,6 @@
<field name="room_type_id" ref="pms_room_type_4" /> <field name="room_type_id" ref="pms_room_type_4" />
<field name="checkin" eval="DateTime.today() + timedelta(10)" /> <field name="checkin" eval="DateTime.today() + timedelta(10)" />
<field name="checkout" eval="DateTime.today() + timedelta(12)" /> <field name="checkout" eval="DateTime.today() + timedelta(12)" />
</record> </record>
<record id="pms_reservation_29" model="pms.reservation"> <record id="pms_reservation_29" model="pms.reservation">
<field name="partner_id" ref="base.res_partner_address_32" /> <field name="partner_id" ref="base.res_partner_address_32" />
@@ -270,7 +262,6 @@
<field name="room_type_id" ref="pms_room_type_4" /> <field name="room_type_id" ref="pms_room_type_4" />
<field name="checkin" eval="DateTime.today() + timedelta(1)" /> <field name="checkin" eval="DateTime.today() + timedelta(1)" />
<field name="checkout" eval="DateTime.today() + timedelta(4)" /> <field name="checkout" eval="DateTime.today() + timedelta(4)" />
</record> </record>
<record id="pms_reservation_30" model="pms.reservation"> <record id="pms_reservation_30" model="pms.reservation">
<field name="partner_id" ref="base.res_partner_address_33" /> <field name="partner_id" ref="base.res_partner_address_33" />
@@ -278,7 +269,6 @@
<field name="room_type_id" ref="pms_room_type_4" /> <field name="room_type_id" ref="pms_room_type_4" />
<field name="checkin" eval="DateTime.today() + timedelta(6)" /> <field name="checkin" eval="DateTime.today() + timedelta(6)" />
<field name="checkout" eval="DateTime.today() + timedelta(8)" /> <field name="checkout" eval="DateTime.today() + timedelta(8)" />
</record> </record>
</data> </data>
</odoo> </odoo>

View File

@@ -4,6 +4,7 @@
from . import ir_http from . import ir_http
from . import ir_sequence from . import ir_sequence
# from . import payment_return # from . import payment_return
from . import pms_board_service_room_type from . import pms_board_service_room_type
from . import pms_property from . import pms_property
@@ -28,7 +29,8 @@ from . import pms_reservation_line
from . import pms_checkin_partner from . import pms_checkin_partner
from . import product_pricelist from . import product_pricelist
from . import res_partner from . import res_partner
from . import mail_compose_message
# from . import mail_compose_message
from . import pms_room_type_class from . import pms_room_type_class
from . import pms_room_closure_reason from . import pms_room_closure_reason
from . import pms_service_line from . import pms_service_line

View File

@@ -3,7 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
import json import json
from odoo import _, api, fields, models from odoo import _, fields, models
from odoo.tools import float_is_zero from odoo.tools import float_is_zero
@@ -12,18 +12,20 @@ class AccountMove(models.Model):
# Field Declarations # Field Declarations
folio_ids = fields.Many2many( folio_ids = fields.Many2many(
comodel_name="pms.folio", compute="_computed_folio_origin" comodel_name="pms.folio", compute="_compute_folio_origin"
) )
pms_property_id = fields.Many2one("pms.property") pms_property_id = fields.Many2one("pms.property")
from_folio = fields.Boolean(compute="_computed_folio_origin") from_folio = fields.Boolean(compute="_compute_folio_origin")
outstanding_folios_debits_widget = fields.Text( outstanding_folios_debits_widget = fields.Text(
compute="_get_outstanding_folios_JSON" compute="_compute_get_outstanding_folios_JSON"
)
has_folios_outstanding = fields.Boolean(
compute="_compute_get_outstanding_folios_JSON"
) )
has_folios_outstanding = fields.Boolean(compute="_get_outstanding_folios_JSON")
# Compute and Search methods # Compute and Search methods
def _computed_folio_origin(self): def _compute_folio_origin(self):
for inv in self: for inv in self:
inv.from_folio = False inv.from_folio = False
inv.folio_ids = False inv.folio_ids = False
@@ -53,7 +55,7 @@ class AccountMove(models.Model):
} }
# Business methods # Business methods
def _get_outstanding_folios_JSON(self): def _compute_get_outstanding_folios_JSON(self):
self.ensure_one() self.ensure_one()
self.outstanding_folios_debits_widget = json.dumps(False) self.outstanding_folios_debits_widget = json.dumps(False)
if self.from_folio: if self.from_folio:

View File

@@ -10,7 +10,9 @@ class AccountPayment(models.Model):
# Fields declaration # Fields declaration
folio_id = fields.Many2one("pms.folio", string="Folio") folio_id = fields.Many2one("pms.folio", string="Folio")
amount_total_folio = fields.Float( amount_total_folio = fields.Float(
compute="_compute_folio_amount", store=True, string="Total amount in folio", compute="_compute_folio_amount",
store=True,
string="Total amount in folio",
) )
save_amount = fields.Monetary(string="onchange_amount") save_amount = fields.Monetary(string="onchange_amount")
save_date = fields.Date() save_date = fields.Date()
@@ -53,8 +55,6 @@ class AccountPayment(models.Model):
self.save_date = self._origin.payment_date self.save_date = self._origin.payment_date
# Action methods # Action methods
"""WIP"""
# def return_payment_folio(self): # def return_payment_folio(self):
# journal = self.journal_id # journal = self.journal_id
# partner = self.partner_id # partner = self.partner_id
@@ -129,18 +129,15 @@ class AccountPayment(models.Model):
if rec and not self._context.get("ignore_notification_post", False): if rec and not self._context.get("ignore_notification_post", False):
for pay in self: for pay in self:
if pay.folio_id: if pay.folio_id:
msg = ( msg = _(
_(
"Payment of %s %s registered from %s \ "Payment of %s %s registered from %s \
using %s payment method" using %s payment method"
) ) % (
% (
pay.amount, pay.amount,
pay.currency_id.symbol, pay.currency_id.symbol,
pay.communication, pay.communication,
pay.journal_id.name, pay.journal_id.name,
) )
)
pay.folio_id.message_post(subject=_("Payment"), body=msg) pay.folio_id.message_post(subject=_("Payment"), body=msg)
def modify_payment(self): def modify_payment(self):

View File

@@ -2,8 +2,7 @@
# Copyright 2019 Dario Lodeiros # Copyright 2019 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import _, models from odoo import models
from odoo.exceptions import MissingError
from odoo.http import request from odoo.http import request
@@ -21,7 +20,8 @@ class IrHttp(models.AbstractModel):
user.pms_property_id.id, user.pms_property_id.id,
user.pms_property_id.name, user.pms_property_id.name,
), ),
# TODO: filter all properties based on the current set of active companies # TODO: filter all properties based on
# the current set of active companies
"allowed_pms_properties": [ "allowed_pms_properties": [
(property.id, property.name) (property.id, property.name)
for property in user.pms_property_ids for property in user.pms_property_ids

View File

@@ -1,7 +1,7 @@
# Copyright 2017 Alexandre Díaz # Copyright 2017 Alexandre Díaz
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, models from odoo import models
class MailComposeMessage(models.TransientModel): class MailComposeMessage(models.TransientModel):
@@ -13,12 +13,12 @@ class MailComposeMessage(models.TransientModel):
and self._context.get("default_res_id") and self._context.get("default_res_id")
and self._context.get("mark_so_as_sent") and self._context.get("mark_so_as_sent")
): ):
folio = self.env["pms.folio"].browse([self._context["default_res_id"]])
# TODO: WorkFlow Mails # TODO: WorkFlow Mails
# if folio: folio = self.env["pms.folio"].browse([self._context["default_res_id"]])
# cmds = [ if folio:
# (1, lid, {"to_send": False}) for lid in folio.reservation_ids.ids cmds = [
# ] (1, lid, {"to_send": False}) for lid in folio.reservation_ids.ids
# if any(cmds): ]
# folio.reservation_ids = cmds if any(cmds):
folio.reservation_ids = cmds
return super(MailComposeMessage, self).send_mail(auto_commit=auto_commit) return super(MailComposeMessage, self).send_mail(auto_commit=auto_commit)

View File

@@ -1,6 +1,6 @@
# Copyright 2017 Dario Lodeiros # Copyright 2017 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import _, api, fields, models from openerp import fields, models
class PaymentReturn(models.Model): class PaymentReturn(models.Model):

View File

@@ -18,7 +18,8 @@ class PmsBoardServiceRoomType(models.Model):
for res in self: for res in self:
if res.pricelist_id: if res.pricelist_id:
name = u"{} ({})".format( name = u"{} ({})".format(
res.pms_board_service_id.name, res.pricelist_id.name, res.pms_board_service_id.name,
res.pricelist_id.name,
) )
else: else:
name = u"{} ({})".format(res.pms_board_service_id.name, _("Generic")) name = u"{} ({})".format(res.pms_board_service_id.name, _("Generic"))

View File

@@ -21,7 +21,7 @@ class PmsFolio(models.Model):
for folio in self: for folio in self:
name = folio.name name = folio.name
if len(folio.reservation_ids) > 1: if len(folio.reservation_ids) > 1:
name += ' (%s)' % len(folio.reservation_ids) name += " (%s)" % len(folio.reservation_ids)
result.append((folio.id, name)) result.append((folio.id, name))
return result return result
@@ -39,7 +39,9 @@ class PmsFolio(models.Model):
@api.model @api.model
def _get_default_pms_property(self): def _get_default_pms_property(self):
return self.env.user.pms_property_id #TODO: Change by property env variable (like company) return (
self.env.user.pms_property_id
) # TODO: Change by property env variable (like company)
# Fields declaration # Fields declaration
name = fields.Char( name = fields.Char(
@@ -59,7 +61,9 @@ class PmsFolio(models.Model):
help="Room reservation detail.", help="Room reservation detail.",
) )
number_of_rooms = fields.Integer( number_of_rooms = fields.Integer(
"Number of Rooms", compute="_compute_number_of_rooms", store="True", "Number of Rooms",
compute="_compute_number_of_rooms",
store="True",
) )
service_ids = fields.One2many( service_ids = fields.One2many(
"pms.service", "pms.service",
@@ -70,7 +74,10 @@ class PmsFolio(models.Model):
"include in main Invoice.", "include in main Invoice.",
) )
company_id = fields.Many2one( company_id = fields.Many2one(
"res.company", "Company", required=True, default=lambda self: self.env.company, "res.company",
"Company",
required=True,
default=lambda self: self.env.company,
) )
analytic_account_id = fields.Many2one( analytic_account_id = fields.Many2one(
"account.analytic.account", "account.analytic.account",
@@ -108,7 +115,10 @@ class PmsFolio(models.Model):
readonly=False, readonly=False,
) )
agency_id = fields.Many2one( agency_id = fields.Many2one(
"res.partner", "Agency", ondelete="restrict", domain=[("is_agency", "=", True)], "res.partner",
"Agency",
ondelete="restrict",
domain=[("is_agency", "=", True)],
) )
payment_ids = fields.One2many("account.payment", "folio_id", readonly=True) payment_ids = fields.One2many("account.payment", "folio_id", readonly=True)
# return_ids = fields.One2many("payment.return", "folio_id", readonly=True) # return_ids = fields.One2many("payment.return", "folio_id", readonly=True)
@@ -125,7 +135,7 @@ class PmsFolio(models.Model):
move_ids = fields.Many2many( move_ids = fields.Many2many(
"account.move", "account.move",
string="Invoices", string="Invoices",
compute="_get_invoiced", compute="_compute_get_invoiced",
readonly=True, readonly=True,
copy=False, copy=False,
) )
@@ -155,7 +165,10 @@ class PmsFolio(models.Model):
default=lambda *a: "normal", default=lambda *a: "normal",
) )
channel_type = fields.Selection( channel_type = fields.Selection(
[("direct", "Direct"), ("agency", "Agency"),], [
("direct", "Direct"),
("agency", "Agency"),
],
string="Sales Channel", string="Sales Channel",
compute="_compute_channel_type", compute="_compute_channel_type",
store=True, store=True,
@@ -203,13 +216,13 @@ class PmsFolio(models.Model):
# Amount Fields------------------------------------------------------ # Amount Fields------------------------------------------------------
pending_amount = fields.Monetary( pending_amount = fields.Monetary(
compute="compute_amount", store=True, string="Pending in Folio" compute="_compute_amount", store=True, string="Pending in Folio"
) )
# refund_amount = fields.Monetary( # refund_amount = fields.Monetary(
# compute="compute_amount", store=True, string="Payment Returns" # compute="_compute_amount", store=True, string="Payment Returns"
# ) # )
invoices_paid = fields.Monetary( invoices_paid = fields.Monetary(
compute="compute_amount", compute="_compute_amount",
store=True, store=True,
track_visibility="onchange", track_visibility="onchange",
string="Payments", string="Payments",
@@ -218,17 +231,17 @@ class PmsFolio(models.Model):
string="Untaxed Amount", string="Untaxed Amount",
store=True, store=True,
readonly=True, readonly=True,
compute="_amount_all", compute="_compute_amount_all",
track_visibility="onchange", track_visibility="onchange",
) )
amount_tax = fields.Monetary( amount_tax = fields.Monetary(
string="Taxes", store=True, readonly=True, compute="_amount_all" string="Taxes", store=True, readonly=True, compute="_compute_amount_all"
) )
amount_total = fields.Monetary( amount_total = fields.Monetary(
string="Total", string="Total",
store=True, store=True,
readonly=True, readonly=True,
compute="_amount_all", compute="_compute_amount_all",
track_visibility="always", track_visibility="always",
) )
# Checkin Fields----------------------------------------------------- # Checkin Fields-----------------------------------------------------
@@ -249,7 +262,7 @@ class PmsFolio(models.Model):
("no", "Nothing to Invoice"), ("no", "Nothing to Invoice"),
], ],
string="Invoice Status", string="Invoice Status",
compute="_get_invoiced", compute="_compute_get_invoiced",
store=True, store=True,
readonly=True, readonly=True,
default="no", default="no",
@@ -300,9 +313,9 @@ class PmsFolio(models.Model):
def _compute_channel_type(self): def _compute_channel_type(self):
for folio in self: for folio in self:
if folio.agency_id: if folio.agency_id:
folio.channel_type = 'agency' folio.channel_type = "agency"
else: else:
folio.channel_type = 'direct' folio.channel_type = "direct"
@api.depends("partner_id") @api.depends("partner_id")
def _compute_payment_term_id(self): def _compute_payment_term_id(self):
@@ -317,7 +330,7 @@ class PmsFolio(models.Model):
@api.depends( @api.depends(
"state", "reservation_ids.invoice_status", "service_ids.invoice_status" "state", "reservation_ids.invoice_status", "service_ids.invoice_status"
) )
def _get_invoiced(self): def _compute_get_invoiced(self):
""" """
Compute the invoice status of a Folio. Possible statuses: Compute the invoice status of a Folio. Possible statuses:
- no: if the Folio is not in status 'sale' or 'done', we - no: if the Folio is not in status 'sale' or 'done', we
@@ -409,7 +422,7 @@ class PmsFolio(models.Model):
) )
@api.depends("reservation_ids.price_total", "service_ids.price_total") @api.depends("reservation_ids.price_total", "service_ids.price_total")
def _amount_all(self): def _compute_amount_all(self):
""" """
Compute the total amounts of the SO. Compute the total amounts of the SO.
""" """
@@ -432,10 +445,8 @@ class PmsFolio(models.Model):
) )
# TODO: Add return_ids to depends # TODO: Add return_ids to depends
@api.depends( @api.depends("amount_total", "payment_ids", "reservation_type", "state")
"amount_total", "payment_ids", "reservation_type", "state" def _compute_amount(self):
)
def compute_amount(self):
acc_pay_obj = self.env["account.payment"] acc_pay_obj = self.env["account.payment"]
for record in self: for record in self:
if record.reservation_type in ("staff", "out"): if record.reservation_type in ("staff", "out"):
@@ -455,7 +466,9 @@ class PmsFolio(models.Model):
# ("return_id.state", "=", "done"), # ("return_id.state", "=", "done"),
# ] # ]
# ) # )
# total_inv_refund = sum(pay_return.amount for pay_return in return_lines) # total_inv_refund = sum(
# pay_return.amount for pay_return in return_lines
# )
total = record.amount_total total = record.amount_total
# REVIEW: Must We ignored services in cancelled folios # REVIEW: Must We ignored services in cancelled folios
# pending amount? # pending amount?
@@ -548,10 +561,14 @@ class PmsFolio(models.Model):
# TODO: Make sequence from property, not company # TODO: Make sequence from property, not company
if vals.get("name", _("New")) == _("New") or "name" not in vals: if vals.get("name", _("New")) == _("New") or "name" not in vals:
# TODO: change for property env variable # TODO: change for property env variable
pms_property_id = self.env.user.pms_property_id.id if "pms_property_id" not in vals else vals["pms_property_id"] pms_property_id = (
vals["name"] = self.env["ir.sequence"].search([ self.env.user.pms_property_id.id
('pms_property_id', '=', pms_property_id) if "pms_property_id" not in vals
]).next_by_code("pms.folio") or _("New") else vals["pms_property_id"]
)
vals["name"] = self.env["ir.sequence"].search(
[("pms_property_id", "=", pms_property_id)]
).next_by_code("pms.folio") or _("New")
result = super(PmsFolio, self).create(vals) result = super(PmsFolio, self).create(vals)
return result return result
@@ -569,7 +586,9 @@ class PmsFolio(models.Model):
): ):
reservation.action_cancel() reservation.action_cancel()
self.write( self.write(
{"state": "cancel",} {
"state": "cancel",
}
) )
return True return True
@@ -589,9 +608,7 @@ class PmsFolio(models.Model):
# self._create_analytic_account() # self._create_analytic_account()
return True return True
""" # CHECKIN/OUT PROCESS
CHECKIN/OUT PROCESS
"""
def _compute_checkin_partner_count(self): def _compute_checkin_partner_count(self):
for record in self: for record in self:
@@ -636,6 +653,8 @@ class PmsFolio(models.Model):
if t["id"] == tax.id or t["id"] in tax.children_tax_ids.ids: if t["id"] == tax.id or t["id"] in tax.children_tax_ids.ids:
res[group]["amount"] += t["amount"] res[group]["amount"] += t["amount"]
res[group]["base"] += t["base"] res[group]["base"] += t["base"]
res = sorted(res.items(), key=lambda l: l[0].sequence) res = sorted(res.items(), key=lambda line: line[0].sequence)
res = [(l[0].name, l[1]["amount"], l[1]["base"], len(res)) for l in res] res = [
(line[0].name, line[1]["amount"], line[1]["base"], len(res)) for line in res
]
return res return res

View File

@@ -53,8 +53,8 @@ class PmsProperty(models.Model):
default_cancel_policy_days = fields.Integer("Cancellation Days") default_cancel_policy_days = fields.Integer("Cancellation Days")
default_cancel_policy_percent = fields.Float("Percent to pay") default_cancel_policy_percent = fields.Float("Percent to pay")
folio_sequence_id = fields.Many2one( folio_sequence_id = fields.Many2one(
'ir.sequence', 'Folio Sequence', "ir.sequence", "Folio Sequence", check_company=True, copy=False
check_company=True, copy=False) )
# Constraints and onchanges # Constraints and onchanges
@api.constrains("default_arrival_hour", "default_departure_hour") @api.constrains("default_arrival_hour", "default_departure_hour")

View File

@@ -118,13 +118,19 @@ class PmsReservation(models.Model):
domain="[('id', 'in', allowed_room_ids)]", domain="[('id', 'in', allowed_room_ids)]",
) )
allowed_room_ids = fields.Many2many( allowed_room_ids = fields.Many2many(
"pms.room", string="Allowed Rooms", compute="_compute_allowed_room_ids", "pms.room",
string="Allowed Rooms",
compute="_compute_allowed_room_ids",
) )
folio_id = fields.Many2one( folio_id = fields.Many2one(
"pms.folio", string="Folio", track_visibility="onchange", ondelete="restrict", "pms.folio",
string="Folio",
track_visibility="onchange",
ondelete="restrict",
) )
board_service_room_id = fields.Many2one( board_service_room_id = fields.Many2one(
"pms.board.service.room.type", string="Board Service", "pms.board.service.room.type",
string="Board Service",
) )
room_type_id = fields.Many2one( room_type_id = fields.Many2one(
"pms.room.type", "pms.room.type",
@@ -157,7 +163,8 @@ class PmsReservation(models.Model):
related="folio_id.company_id", string="Company", store=True, readonly=True related="folio_id.company_id", string="Company", store=True, readonly=True
) )
pms_property_id = fields.Many2one( pms_property_id = fields.Many2one(
"pms.property", default=_get_default_pms_property, #required=True "pms.property",
default=_get_default_pms_property, # required=True
) )
reservation_line_ids = fields.One2many( reservation_line_ids = fields.One2many(
"pms.reservation.line", "pms.reservation.line",
@@ -247,7 +254,11 @@ class PmsReservation(models.Model):
reservation_type = fields.Selection( reservation_type = fields.Selection(
related="folio_id.reservation_type", default=lambda *a: "normal" related="folio_id.reservation_type", default=lambda *a: "normal"
) )
splitted = fields.Boolean("Splitted", compute="_compute_splitted", store=True,) splitted = fields.Boolean(
"Splitted",
compute="_compute_splitted",
store=True,
)
credit_card_details = fields.Text(related="folio_id.credit_card_details") credit_card_details = fields.Text(related="folio_id.credit_card_details")
cancelled_reason = fields.Selection( cancelled_reason = fields.Selection(
@@ -283,14 +294,21 @@ class PmsReservation(models.Model):
) )
overbooking = fields.Boolean("Is Overbooking", default=False) overbooking = fields.Boolean("Is Overbooking", default=False)
reselling = fields.Boolean("Is Reselling", default=False) reselling = fields.Boolean("Is Reselling", default=False)
nights = fields.Integer("Nights", compute="_computed_nights", store=True) nights = fields.Integer("Nights", compute="_compute_nights", store=True)
channel_type = fields.Selection( channel_type = fields.Selection(
selection=[("direct", "Direct"), ("agency", "Agency"),], selection=[
("direct", "Direct"),
("agency", "Agency"),
],
string="Sales Channel", string="Sales Channel",
default="direct", default="direct",
) )
subchannel_direct = fields.Selection( subchannel_direct = fields.Selection(
selection=[("door", "Door"), ("mail", "Mail"), ("phone", "Phone"),], selection=[
("door", "Door"),
("mail", "Mail"),
("phone", "Phone"),
],
string="Direct Channel", string="Direct Channel",
) )
origin = fields.Char("Origin", compute="_compute_origin", store=True) origin = fields.Char("Origin", compute="_compute_origin", store=True)
@@ -298,7 +316,7 @@ class PmsReservation(models.Model):
"Detail Origin", compute="_compute_detail_origin", store=True "Detail Origin", compute="_compute_detail_origin", store=True
) )
folio_pending_amount = fields.Monetary(related="folio_id.pending_amount") folio_pending_amount = fields.Monetary(related="folio_id.pending_amount")
shared_folio = fields.Boolean(compute="_computed_shared") shared_folio = fields.Boolean(compute="_compute_shared")
# Used to notify is the reservation folio has other reservations/services # Used to notify is the reservation folio has other reservations/services
email = fields.Char("E-mail", related="partner_id.email") email = fields.Char("E-mail", related="partner_id.email")
mobile = fields.Char("Mobile", related="partner_id.mobile") mobile = fields.Char("Mobile", related="partner_id.mobile")
@@ -323,14 +341,14 @@ class PmsReservation(models.Model):
default="no", default="no",
) )
qty_to_invoice = fields.Float( qty_to_invoice = fields.Float(
compute="_get_to_invoice_qty", compute="_compute_get_to_invoice_qty",
string="To Invoice", string="To Invoice",
store=True, store=True,
readonly=True, readonly=True,
digits=("Product Unit of Measure"), digits=("Product Unit of Measure"),
) )
qty_invoiced = fields.Float( qty_invoiced = fields.Float(
compute="_get_invoice_qty", compute="_compute_get_invoice_qty",
string="Invoiced", string="Invoiced",
store=True, store=True,
readonly=True, readonly=True,
@@ -468,14 +486,22 @@ class PmsReservation(models.Model):
lambda r: r.date == idate lambda r: r.date == idate
) )
if not old_line: if not old_line:
cmds.append((0, False, {"date": idate},)) cmds.append(
reservation.reservation_line_ids -= reservation.reservation_line_ids.filtered_domain( (
0,
False,
{"date": idate},
)
)
reservation.reservation_line_ids -= (
reservation.reservation_line_ids.filtered_domain(
[ [
"|", "|",
("date", ">=", reservation.checkout), ("date", ">=", reservation.checkout),
("date", "<", reservation.checkin), ("date", "<", reservation.checkin),
] ]
) )
)
reservation.reservation_line_ids = cmds reservation.reservation_line_ids = cmds
@api.depends("board_service_room_id") @api.depends("board_service_room_id")
@@ -483,7 +509,9 @@ class PmsReservation(models.Model):
for reservation in self: for reservation in self:
board_services = [] board_services = []
old_board_lines = reservation.service_ids.filtered_domain( old_board_lines = reservation.service_ids.filtered_domain(
[("is_board_service", "=", True),] [
("is_board_service", "=", True),
]
) )
if reservation.board_service_room_id: if reservation.board_service_room_id:
board = self.env["pms.board.service.room.type"].browse( board = self.env["pms.board.service.room.type"].browse(
@@ -522,7 +550,7 @@ class PmsReservation(models.Model):
if reservation.room_id: if reservation.room_id:
if reservation.adults == 0: if reservation.adults == 0:
reservation.adults = reservation.room_id.capacity reservation.adults = reservation.room_id.capacity
elif reservation.adults == False: elif not reservation.adults:
reservation.adults = 0 reservation.adults = 0
@api.depends("reservation_line_ids", "reservation_line_ids.room_id") @api.depends("reservation_line_ids", "reservation_line_ids.room_id")
@@ -541,7 +569,7 @@ class PmsReservation(models.Model):
that there is nothing to invoice. This is also hte default value that there is nothing to invoice. This is also hte default value
if the conditions of no other status is met. if the conditions of no other status is met.
- to invoice: we refer to the quantity to invoice of the line. - to invoice: we refer to the quantity to invoice of the line.
Refer to method `_get_to_invoice_qty()` for more information Refer to method `_compute_get_to_invoice_qty()` for more information
on how this quantity is calculated. on how this quantity is calculated.
- invoiced: the quantity invoiced is larger or equal to the - invoiced: the quantity invoiced is larger or equal to the
quantity ordered. quantity ordered.
@@ -567,7 +595,7 @@ class PmsReservation(models.Model):
line.invoice_status = "no" line.invoice_status = "no"
@api.depends("qty_invoiced", "nights", "folio_id.state") @api.depends("qty_invoiced", "nights", "folio_id.state")
def _get_to_invoice_qty(self): def _compute_get_to_invoice_qty(self):
""" """
Compute the quantity to invoice. If the invoice policy is order, Compute the quantity to invoice. If the invoice policy is order,
the quantity to invoice is calculated from the ordered quantity. the quantity to invoice is calculated from the ordered quantity.
@@ -580,7 +608,7 @@ class PmsReservation(models.Model):
line.qty_to_invoice = 0 line.qty_to_invoice = 0
@api.depends("move_line_ids.move_id.state", "move_line_ids.quantity") @api.depends("move_line_ids.move_id.state", "move_line_ids.quantity")
def _get_invoice_qty(self): def _compute_get_invoice_qty(self):
""" """
Compute the quantity invoiced. If case of a refund, the quantity Compute the quantity invoiced. If case of a refund, the quantity
invoiced is decreased. We must check day per day and sum or invoiced is decreased. We must check day per day and sum or
@@ -600,7 +628,7 @@ class PmsReservation(models.Model):
line.qty_invoiced = qty_invoiced line.qty_invoiced = qty_invoiced
@api.depends("reservation_line_ids") @api.depends("reservation_line_ids")
def _computed_nights(self): def _compute_nights(self):
for res in self: for res in self:
res.nights = len(res.reservation_line_ids) res.nights = len(res.reservation_line_ids)
@@ -657,7 +685,11 @@ class PmsReservation(models.Model):
) )
else: else:
record.update( record.update(
{"price_tax": 0, "price_total": 0, "price_subtotal": 0,} {
"price_tax": 0,
"price_total": 0,
"price_subtotal": 0,
}
) )
# TODO: Use default values on checkin /checkout is empty # TODO: Use default values on checkin /checkout is empty
@@ -690,16 +722,21 @@ class PmsReservation(models.Model):
@api.constrains("reservation_type", "partner_id") @api.constrains("reservation_type", "partner_id")
def _check_partner_reservation(self): def _check_partner_reservation(self):
for reservation in self: for reservation in self:
if reservation.reservation_type == "out" and \ if (
reservation.partner_id != reservation.pms_property_id.partner_id.id: reservation.reservation_type == "out"
raise models.ValidationError(_("The partner on out reservations must be a property partner")) and reservation.partner_id != reservation.pms_property_id.partner_id.id
):
raise models.ValidationError(
_("The partner on out reservations must be a property partner")
)
@api.constrains("closure_reason_id", "reservation_type") @api.constrains("closure_reason_id", "reservation_type")
def _check_partner_reservation(self): def _check_clousure_reservation(self):
for reservation in self: for reservation in self:
if reservation.closure_reason_id and \ if reservation.closure_reason_id and reservation.reservation_type != "out":
reservation.reservation_type != 'out': raise models.ValidationError(
raise models.ValidationError(_("Only the out reservations can has a clousure reason")) _("Only the out reservations can has a clousure reason")
)
# @api.onchange("checkin_partner_ids") # @api.onchange("checkin_partner_ids")
# def onchange_checkin_partner_ids(self): # def onchange_checkin_partner_ids(self):
@@ -811,7 +848,7 @@ class PmsReservation(models.Model):
# Business methods # Business methods
def _computed_shared(self): def _compute_shared(self):
# Has this reservation more charges associates in folio?, # Has this reservation more charges associates in folio?,
# Yes?, then, this is share folio ;) # Yes?, then, this is share folio ;)
for record in self: for record in self:
@@ -884,8 +921,6 @@ class PmsReservation(models.Model):
@param self: object pointer @param self: object pointer
""" """
_logger.info("confirm") _logger.info("confirm")
pms_reserv_obj = self.env["pms.reservation"]
user = self.env["res.users"].browse(self.env.uid)
for record in self: for record in self:
vals = {} vals = {}
if record.checkin_partner_ids: if record.checkin_partner_ids:
@@ -961,8 +996,6 @@ class PmsReservation(models.Model):
lines = self.env["pms.reservation.line"].search(domain) lines = self.env["pms.reservation.line"].search(domain)
reservations_dates = {} reservations_dates = {}
for record in lines: for record in lines:
# kumari.net/index.php/programming/programmingcat/22-python-making-a-dictionary-of-lists-a-hash-of-arrays
# reservations_dates.setdefault(record.date,[]).append(record.reservation_id.room_type_id)
reservations_dates.setdefault(record.date, []).append( reservations_dates.setdefault(record.date, []).append(
[record.reservation_id, record.reservation_id.room_type_id] [record.reservation_id, record.reservation_id.room_type_id]
) )
@@ -994,8 +1027,6 @@ class PmsReservation(models.Model):
if reservation.channel_type in ["direct", "agency"]: if reservation.channel_type in ["direct", "agency"]:
reservation.detail_origin = reservation.sudo().create_uid.name reservation.detail_origin = reservation.sudo().create_uid.name
# https://www.odoo.com/es_ES/forum/ayuda-1/question/calculated-fields-in-search-filter-possible-118501
def _search_checkin_partner_pending(self, operator, value): def _search_checkin_partner_pending(self, operator, value):
self.ensure_one() self.ensure_one()
recs = self.search([]).filtered(lambda x: x.checkin_partner_pending_count > 0) recs = self.search([]).filtered(lambda x: x.checkin_partner_pending_count > 0)

View File

@@ -84,14 +84,16 @@ class PmsReservationLine(models.Model):
_sql_constraints = [ _sql_constraints = [
( (
"rule_availability", "rule_availability",
"EXCLUDE (room_id WITH =, date WITH =) WHERE (occupies_availability = True)", "EXCLUDE (room_id WITH =, date WITH =) \
WHERE (occupies_availability = True)",
"Room Occupied", "Room Occupied",
), ),
] ]
# Compute and Search methods # Compute and Search methods
@api.depends( @api.depends(
"reservation_id.adults", "reservation_id.room_type_id", "reservation_id.adults",
"reservation_id.room_type_id",
) )
def _compute_room_id(self): def _compute_room_id(self):
for line in self: for line in self:
@@ -160,7 +162,7 @@ class PmsReservationLine(models.Model):
for line in self: for line in self:
if ( if (
line.reservation_id.state == "cancelled" line.reservation_id.state == "cancelled"
or line.reservation_id.overbooking == True or line.reservation_id.overbooking
): ):
line.occupies_availability = False line.occupies_availability = False
else: else:

View File

@@ -22,7 +22,7 @@ class PmsRoom(models.Model):
for room in self: for room in self:
name = room.name name = room.name
if room.room_type_id: if room.room_type_id:
name += ' [%s]' % room.room_type_id.code_type name += " [%s]" % room.room_type_id.code_type
result.append((room.id, name)) result.append((room.id, name))
return result return result

View File

@@ -1,7 +1,6 @@
# Copyright 2017 Alexandre Díaz # Copyright 2017 Alexandre Díaz
# Copyright 2017 Dario Lodeiros # Copyright 2017 Dario Lodeiros
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from datetime import timedelta
from odoo import _, api, fields, models from odoo import _, api, fields, models
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
@@ -51,7 +50,10 @@ class PmsRoomType(models.Model):
string="Room Type Amenities", string="Room Type Amenities",
help="List of Amenities.", help="List of Amenities.",
) )
code_type = fields.Char("Code", required=True,) code_type = fields.Char(
"Code",
required=True,
)
shared_room = fields.Boolean( shared_room = fields.Boolean(
"Shared Room", default=False, help="This room type is reservation by beds" "Shared Room", default=False, help="This room type is reservation by beds"
) )
@@ -91,7 +93,10 @@ class PmsRoomType(models.Model):
def create(self, vals): def create(self, vals):
""" Add room types as not purchase services. """ """ Add room types as not purchase services. """
vals.update( vals.update(
{"purchase_ok": False, "type": "service",} {
"purchase_ok": False,
"type": "service",
}
) )
return super().create(vals) return super().create(vals)
@@ -119,27 +124,30 @@ class PmsRoomType(models.Model):
Return Dict Code Room Types: subdict with day, discount, price Return Dict Code Room Types: subdict with day, discount, price
""" """
vals = {} vals = {}
room_type_ids = kwargs.get("room_type_ids", False) # room_type_ids = kwargs.get("room_type_ids", False)
room_types = ( # room_types = (
self.env["pms.room.type"].browse(room_type_ids) # self.env["pms.room.type"].browse(room_type_ids)
if room_type_ids # if room_type_ids
else self.env["pms.room.type"].search([]) # else self.env["pms.room.type"].search([])
) # )
date_from = kwargs.get("date_from", False) date_from = kwargs.get("date_from", False)
days = kwargs.get("days", False) days = kwargs.get("days", False)
discount = kwargs.get("discount", False) discount = kwargs.get("discount", False)
if not date_from or not days: if not date_from or not days:
raise ValidationError(_("Date From and days are mandatory")) raise ValidationError(_("Date From and days are mandatory"))
partner_id = kwargs.get("partner_id", False) partner_id = kwargs.get("partner_id", False)
partner = self.env["res.partner"].browse(partner_id) # partner = self.env["res.partner"].browse(partner_id)
pricelist_id = kwargs.get( # pricelist_id = kwargs.get(
"pricelist_id", # "pricelist_id",
partner.property_product_pricelist.id # partner.property_product_pricelist.id
and partner.property_product_pricelist.id # and partner.property_product_pricelist.id
or self.env.user.pms_property_id.default_pricelist_id.id, # or self.env.user.pms_property_id.default_pricelist_id.id,
) # )
vals.update( vals.update(
{"partner_id": partner_id if partner_id else False, "discount": discount,} {
"partner_id": partner_id if partner_id else False,
"discount": discount,
}
) )
rate_vals = {} rate_vals = {}
# TODO: Now it is computed field, We need other way to return rates # TODO: Now it is computed field, We need other way to return rates
@@ -155,7 +163,9 @@ class PmsRoomType(models.Model):
# rate_vals.update( # rate_vals.update(
# { # {
# room_type.id: [ # room_type.id: [
# item[2] for item in room_vals["reservation_line_ids"] if item[2] # item[2] for item in room_vals[
# "reservation_line_ids"
# ] if item[2]
# ] # ]
# } # }
# ) # )

View File

@@ -4,8 +4,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from datetime import timedelta from datetime import timedelta
from odoo import _, api, fields, models from odoo import api, fields, models
from odoo.exceptions import ValidationError
class PmsRoomTypeAvailability(models.Model): class PmsRoomTypeAvailability(models.Model):
@@ -62,7 +61,9 @@ class PmsRoomTypeAvailability(models.Model):
self, checkin, checkout, room_type_id=False, current_lines=False self, checkin, checkout, room_type_id=False, current_lines=False
): ):
domain = self._get_domain_reservations_occupation( domain = self._get_domain_reservations_occupation(
dfrom=checkin, dto=checkout - timedelta(1), current_lines=current_lines, dfrom=checkin,
dto=checkout - timedelta(1),
current_lines=current_lines,
) )
reservation_lines = self.env["pms.reservation.line"].search(domain) reservation_lines = self.env["pms.reservation.line"].search(domain)
reservations_rooms = reservation_lines.mapped("room_id.id") reservations_rooms = reservation_lines.mapped("room_id.id")

View File

@@ -5,7 +5,7 @@ import logging
from datetime import timedelta from datetime import timedelta
from odoo import _, api, fields, models from odoo import _, api, fields, models
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, float_compare, float_is_zero from odoo.tools import float_compare, float_is_zero
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@@ -43,7 +43,10 @@ class PmsService(models.Model):
# Fields declaration # Fields declaration
name = fields.Char( name = fields.Char(
"Service description", compute="_compute_name", store=True, readonly=False, "Service description",
compute="_compute_name",
store=True,
readonly=False,
) )
product_id = fields.Many2one( product_id = fields.Many2one(
"product.product", "Service", ondelete="restrict", required=True "product.product", "Service", ondelete="restrict", required=True
@@ -91,7 +94,10 @@ class PmsService(models.Model):
state = fields.Selection(related="folio_id.state") state = fields.Selection(related="folio_id.state")
per_day = fields.Boolean(related="product_id.per_day", related_sudo=True) per_day = fields.Boolean(related="product_id.per_day", related_sudo=True)
product_qty = fields.Integer( product_qty = fields.Integer(
"Quantity", compute="_compute_product_qty", store=True, readonly=False, "Quantity",
compute="_compute_product_qty",
store=True,
readonly=False,
) )
is_board_service = fields.Boolean() is_board_service = fields.Boolean()
# Non-stored related field to allow portal user to # Non-stored related field to allow portal user to
@@ -130,14 +136,14 @@ class PmsService(models.Model):
) )
discount = fields.Float(string="Discount (%)", digits=("Discount"), default=0.0) discount = fields.Float(string="Discount (%)", digits=("Discount"), default=0.0)
qty_to_invoice = fields.Float( qty_to_invoice = fields.Float(
compute="_get_to_invoice_qty", compute="_compute_get_to_invoice_qty",
string="To Invoice", string="To Invoice",
store=True, store=True,
readonly=True, readonly=True,
digits=("Product Unit of Measure"), digits=("Product Unit of Measure"),
) )
qty_invoiced = fields.Float( qty_invoiced = fields.Float(
compute="_get_invoice_qty", compute="_compute_get_invoice_qty",
string="Invoiced", string="Invoiced",
store=True, store=True,
readonly=True, readonly=True,
@@ -203,18 +209,27 @@ class PmsService(models.Model):
if idate in [ if idate in [
line.date for line in service.service_line_ids line.date for line in service.service_line_ids
]: ]:
# REVIEW: If the date is already cached (otherwise double the date) # REVIEW: If the date is already
# cached (otherwise double the date)
pass pass
elif not old_line: elif not old_line:
lines.append( lines.append(
(0, False, {"date": idate, "day_qty": day_qty,}) (
0,
False,
{
"date": idate,
"day_qty": day_qty,
},
)
) )
else: else:
lines.append((4, old_line.id)) lines.append((4, old_line.id))
move_day = 0 move_day = 0
if consumed_on == "after": if consumed_on == "after":
move_day = 1 move_day = 1
service.service_line_ids -= service.service_line_ids.filtered_domain( service.service_line_ids -= (
service.service_line_ids.filtered_domain(
[ [
"|", "|",
( (
@@ -229,6 +244,7 @@ class PmsService(models.Model):
), ),
] ]
) )
)
_logger.info(service) _logger.info(service)
_logger.info(lines) _logger.info(lines)
service.service_line_ids = lines service.service_line_ids = lines
@@ -239,7 +255,10 @@ class PmsService(models.Model):
( (
0, 0,
False, False,
{"date": fields.Date.today(), "day_qty": day_qty,}, {
"date": fields.Date.today(),
"day_qty": day_qty,
},
) )
] ]
else: else:
@@ -250,7 +269,10 @@ class PmsService(models.Model):
( (
0, 0,
False, False,
{"date": fields.Date.today(), "day_qty": day_qty,}, {
"date": fields.Date.today(),
"day_qty": day_qty,
},
) )
] ]
else: else:
@@ -258,7 +280,6 @@ class PmsService(models.Model):
def _search_old_lines(self, date): def _search_old_lines(self, date):
self.ensure_one() self.ensure_one()
old_lines = self.env["pms.service.line"]
if isinstance(self._origin.id, int): if isinstance(self._origin.id, int):
old_line = self._origin.service_line_ids.filtered(lambda r: r.date == date) old_line = self._origin.service_line_ids.filtered(lambda r: r.date == date)
return old_line return old_line
@@ -366,7 +387,7 @@ class PmsService(models.Model):
return False return False
@api.depends("qty_invoiced", "product_qty", "folio_id.state") @api.depends("qty_invoiced", "product_qty", "folio_id.state")
def _get_to_invoice_qty(self): def _compute_get_to_invoice_qty(self):
""" """
Compute the quantity to invoice. If the invoice policy is order, Compute the quantity to invoice. If the invoice policy is order,
the quantity to invoice is calculated from the ordered quantity. the quantity to invoice is calculated from the ordered quantity.
@@ -379,7 +400,7 @@ class PmsService(models.Model):
line.qty_to_invoice = 0 line.qty_to_invoice = 0
@api.depends("move_line_ids.move_id.state", "move_line_ids.quantity") @api.depends("move_line_ids.move_id.state", "move_line_ids.quantity")
def _get_invoice_qty(self): def _compute_get_invoice_qty(self):
""" """
Compute the quantity invoiced. If case of a refund, Compute the quantity invoiced. If case of a refund,
the quantity invoiced is decreased. Note that this is the case only the quantity invoiced is decreased. Note that this is the case only
@@ -398,7 +419,7 @@ class PmsService(models.Model):
invoice_line.quantity, line.product_id.uom_id invoice_line.quantity, line.product_id.uom_id
) )
elif invoice_line.move_id.type == "out_refund": elif invoice_line.move_id.type == "out_refund":
qty_invoiced -= move_line.uom_id._compute_quantity( qty_invoiced -= invoice_line.uom_id._compute_quantity(
invoice_line.quantity, line.product_id.uom_id invoice_line.quantity, line.product_id.uom_id
) )
line.qty_invoiced = qty_invoiced line.qty_invoiced = qty_invoiced
@@ -412,7 +433,7 @@ class PmsService(models.Model):
This is also hte default value if the conditions of no other This is also hte default value if the conditions of no other
status is met. status is met.
- to invoice: we refer to the quantity to invoice of the line. - to invoice: we refer to the quantity to invoice of the line.
Refer to method `_get_to_invoice_qty()` for more information on Refer to method `_compute_get_to_invoice_qty()` for more information on
how this quantity is calculated. how this quantity is calculated.
- upselling: this is possible only for a product invoiced on ordered - upselling: this is possible only for a product invoiced on ordered
quantities for which we delivered more than expected. quantities for which we delivered more than expected.

View File

@@ -33,7 +33,10 @@ class PmsSharedRoom(models.Model):
help="At which floor the room is located.", help="At which floor the room is located.",
) )
bed_ids = fields.One2many( bed_ids = fields.One2many(
"pms.room", "shared_room_id", readonly=True, ondelete="restrict", "pms.room",
"shared_room_id",
readonly=True,
ondelete="restrict",
) )
active = fields.Boolean("Active", default=True) active = fields.Boolean("Active", default=True)
sequence = fields.Integer("Sequence", required=True) sequence = fields.Integer("Sequence", required=True)
@@ -85,29 +88,39 @@ class PmsSharedRoom(models.Model):
@api.constrains("active") @api.constrains("active")
def _constrain_active(self): def _constrain_active(self):
self.bed_ids.write( self.bed_ids.write(
{"active": self.active,} {
"active": self.active,
}
) )
@api.constrains("room_type_id") @api.constrains("room_type_id")
def _constrain_room_type_id(self): def _constrain_room_type_id(self):
self.bed_ids.write( self.bed_ids.write(
{"room_type_id": self.room_type_id.id,} {
"room_type_id": self.room_type_id.id,
}
) )
@api.constrains("floor_id") @api.constrains("floor_id")
def _constrain_floor_id(self): def _constrain_floor_id(self):
self.bed_ids.write( self.bed_ids.write(
{"floor_id": self.floor_id.id,} {
"floor_id": self.floor_id.id,
}
) )
@api.constrains("sequence") @api.constrains("sequence")
def _constrain_sequence(self): def _constrain_sequence(self):
self.bed_ids.write( self.bed_ids.write(
{"sequence": self.sequence,} {
"sequence": self.sequence,
}
) )
@api.constrains("descrition_sale") @api.constrains("descrition_sale")
def _constrain_descrition_sale(self): def _constrain_descrition_sale(self):
self.bed_ids.write( self.bed_ids.write(
{"description_sale": self.descrition_sale,} {
"description_sale": self.descrition_sale,
}
) )

View File

@@ -49,7 +49,10 @@ class ResPartner(models.Model):
("mobile", operator, name), ("mobile", operator, name),
("email", operator, name), ("email", operator, name),
] ]
partners = self.search(domain + args, limit=limit,) partners = self.search(
domain + args,
limit=limit,
)
res = partners.name_get() res = partners.name_get()
if limit: if limit:
limit_rest = limit - len(partners) limit_rest = limit - len(partners)

View File

@@ -19,9 +19,11 @@
t-field="doc.partner_id" t-field="doc.partner_id"
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}' t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'
/> />
<p t-if="doc.partner_id.vat"><t <p t-if="doc.partner_id.vat">
t-esc="doc.company_id.country_id.vat_label or 'TIN'" <t t-esc="doc.company_id.country_id.vat_label or 'TIN'" />
/>: <span t-field="doc.partner_id.vat" /></p> :
<span t-field="doc.partner_id.vat" />
</p>
</div> </div>
</div> </div>
<h2> <h2>
@@ -75,16 +77,22 @@
t-if="display_discount" t-if="display_discount"
class="text-right" class="text-right"
groups="sale.group_discount_per_so_line" groups="sale.group_discount_per_so_line"
>Disc.(%)</th> >
Disc.(%)
</th>
<th class="text-right">Taxes</th> <th class="text-right">Taxes</th>
<th <th
class="text-right" class="text-right"
groups="sale.group_show_price_subtotal" groups="sale.group_show_price_subtotal"
>Amount</th> >
Amount
</th>
<th <th
class="text-right price_tax_included" class="text-right price_tax_included"
groups="sale.group_show_price_total" groups="sale.group_show_price_total"
>Total Price</th> >
Total Price
</th>
</tr> </tr>
</thead> </thead>
<tbody class="sale_tbody"> <tbody class="sale_tbody">
@@ -196,7 +204,8 @@
/> />
</td> </td>
</tr> </tr>
-<t -
<t
t-foreach="doc._get_tax_amount_by_group()" t-foreach="doc._get_tax_amount_by_group()"
t-as="amount_by_group" t-as="amount_by_group"
> >
@@ -206,8 +215,9 @@
> >
<td> <td>
<span t-esc="amount_by_group[0]" /> <span t-esc="amount_by_group[0]" />
<span>&amp;nbsp;<span <span>&amp;nbsp;<span>
>on</span>&amp;nbsp;<t on
</span>&amp;nbsp;<t
t-esc="amount_by_group[2]" t-esc="amount_by_group[2]"
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}' t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'
/></span> /></span>

View File

@@ -21,17 +21,17 @@
<field name="name">PMS Folio Company Rule</field> <field name="name">PMS Folio Company Rule</field>
<field name="model_id" ref="model_pms_folio" /> <field name="model_id" ref="model_pms_folio" />
<field name="global" eval="True" /> <field name="global" eval="True" />
<field <field name="domain_force">
name="domain_force" ['|',('company_id','=',False),('company_id', 'in', company_ids)]
>['|',('company_id','=',False),('company_id', 'in', company_ids)]</field> </field>
</record> </record>
<record id="pms_reservation_company_rule" model="ir.rule"> <record id="pms_reservation_company_rule" model="ir.rule">
<field name="name">PMS Reservation Company Rule</field> <field name="name">PMS Reservation Company Rule</field>
<field name="model_id" ref="model_pms_reservation" /> <field name="model_id" ref="model_pms_reservation" />
<field name="global" eval="True" /> <field name="global" eval="True" />
<field <field name="domain_force">
name="domain_force" ['|',('company_id','=',False),('company_id', 'in', company_ids)]
>['|',('company_id','=',False),('company_id', 'in', company_ids)]</field> </field>
</record> </record>
<!-- Property Rules --> <!-- Property Rules -->
<!--<record id="pms_folio_property_rule" model="ir.rule"> <!--<record id="pms_folio_property_rule" model="ir.rule">

View File

@@ -8,12 +8,12 @@ odoo.define("web.SwitchPmsMenu", function(require) {
*/ */
var config = require("web.config"); var config = require("web.config");
var core = require("web.core"); // Var core = require("web.core");
var session = require("pms.session"); var session = require("pms.session");
var SystrayMenu = require("web.SystrayMenu"); var SystrayMenu = require("web.SystrayMenu");
var Widget = require("web.Widget"); var Widget = require("web.Widget");
var _t = core._t; // Var _t = core._t;
var SwitchPmsMenu = Widget.extend({ var SwitchPmsMenu = Widget.extend({
template: "SwitchPmsMenu", template: "SwitchPmsMenu",

View File

@@ -6,14 +6,17 @@
<div class="row"> <div class="row">
<div class="col-sm-4"> <div class="col-sm-4">
<t t-esc="object.pms_property_id.street" /> <t t-esc="object.pms_property_id.street" />
<t t-if="object.pms_property_id.street2">- <t <t t-if="object.pms_property_id.street2">
t-esc="object.pms_property_id.street2" -
/></t> <br /> <t t-esc="object.pms_property_id.street2" />
</t>
<br />
<t t-esc="object.pms_property_id.zip" /> <t t-esc="object.pms_property_id.zip" />
<t t-esc="object.pms_property_id.city" />, <t t-esc="object.pms_property_id.city" />
<t t-esc="object.pms_property_id.state_id.name" /> <br /> ,
<t t-esc="object.pms_property_id.state_id.name" />
<br />
<t t-esc="object.pms_property_id.country_id.name" /> <t t-esc="object.pms_property_id.country_id.name" />
</div> </div>
<div class="col-sm-4"> <div class="col-sm-4">
<i class="glyphicon glyphicon-phone-alt" /> <i class="glyphicon glyphicon-phone-alt" />
@@ -38,9 +41,10 @@
<th scope="col">Room Type</th> <th scope="col">Room Type</th>
<th scope="col">Checkin</th> <th scope="col">Checkin</th>
<th scope="col">Nights</th> <th scope="col">Nights</th>
<th scope="col">Price <t <th scope="col">
t-esc="object.currency_id.name" Price
/></th> <t t-esc="object.currency_id.name" />
</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@@ -71,19 +75,30 @@
<template id="template_reservation"> <template id="template_reservation">
<div class="row" style="padding-top: 20px;"> <div class="row" style="padding-top: 20px;">
<div class="col-sm-12"> <div class="col-sm-12">
<p>Dear <span t-field="object.partner_id.name" />,<br /> <p>
Thank you for your reservation.</p> Dear
<p>Here is your confirmation code: <b t-esc="object.name" />. <span t-field="object.partner_id.name" />
Keep this code for any question about your booking order.</p> ,
<br />
Thank you for your reservation.
</p>
<p>
Here is your confirmation code:
<b t-esc="object.name" />
.
Keep this code for any question about your booking order.
</p>
<p>You can find the reservation details below:</p> <p>You can find the reservation details below:</p>
</div> </div>
</div> </div>
<t t-call="pms.template_reservation_details" /> <t t-call="pms.template_reservation_details" />
<div class="row" style="padding-top: 20px;"> <div class="row" style="padding-top: 20px;">
<div class="col-sm-12"> <div class="col-sm-12">
If you have any questions, please do not hesitate to contact with the property's staff. <br If you have any questions, please do not hesitate to contact with
/> the property's staff.
Looking forward to seeing you at our property, <br /> <br />
Looking forward to seeing you at our property,
<br />
Best regards. Best regards.
</div> </div>
</div> </div>
@@ -91,8 +106,10 @@
<template id="template_footer"> <template id="template_footer">
<div class="row" style="padding-top: 20px;"> <div class="row" style="padding-top: 20px;">
<div class="col-sm-12"> <div class="col-sm-12">
Privacy Policy: We use your Personal Information only for managing your reservation. By using the property, you Privacy Policy: We use your Personal Information only for managing
agree to the collection and use of information in accordance with this policy. your reservation. By using the property, you
agree to the collection and use of information in accordance with this
policy.
</div> </div>
</div> </div>
</template> </template>
@@ -128,9 +145,9 @@
<field name="email_to">${(object.email or '')|safe}</field> <field name="email_to">${(object.email or '')|safe}</field>
<field name="partner_to">${(object.partner_id.id or '')}</field> <field name="partner_to">${(object.partner_id.id or '')}</field>
<field name="lang">${object.partner_id.lang}</field> <field name="lang">${object.partner_id.lang}</field>
<field <field name="subject">
name="subject" Your reservation ${object.name} has been confirmed by the property staff
>Your reservation ${object.name} has been confirmed by the property staff</field> </field>
<field name="auto_delete" eval="True" /> <field name="auto_delete" eval="True" />
<field name="body_type">qweb</field> <field name="body_type">qweb</field>
<field name="body_view_id" ref="pms.template_reservation_confirmed" /> <field name="body_view_id" ref="pms.template_reservation_confirmed" />

View File

@@ -20,11 +20,8 @@
# #
############################################################################## ##############################################################################
import logging import logging
from datetime import timedelta
from odoo import api, fields
from odoo.tests import common from odoo.tests import common
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)

View File

@@ -5,25 +5,17 @@
<field name="inherit_id" ref="base.sequence_view" /> <field name="inherit_id" ref="base.sequence_view" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='company_id']" position="after"> <xpath expr="//field[@name='company_id']" position="after">
<field <field string="Property" name="pms_property_id" />
string="Property"
name="pms_property_id"
/>
</xpath> </xpath>
</field> </field>
</record> </record>
<record id="ir_sequence_view_tree" model="ir.ui.view"> <record id="ir_sequence_view_tree" model="ir.ui.view">
<field name="model">ir.sequence</field> <field name="model">ir.sequence</field>
<field name="inherit_id" ref="base.sequence_view_tree" /> <field name="inherit_id" ref="base.sequence_view_tree" />
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//field[@name='company_id']" position="after"> <xpath expr="//field[@name='company_id']" position="after">
<field <field string="Property" name="pms_property_id" />
string="Property"
name="pms_property_id"
/>
</xpath> </xpath>
</field> </field>
</record> </record>
</odoo> </odoo>

View File

@@ -178,7 +178,10 @@
role="alert" role="alert"
style="margin-bottom:0px;" style="margin-bottom:0px;"
> >
these are the billing information associated with the booking client or the company (if a company is assigned). If you want to bill an independent contact, you can select it in the billing assistant these are the billing information associated with the
booking client or the company (if a company is
assigned). If you want to bill an independent contact,
you can select it in the billing assistant
</div> </div>
<group> <group>
<field <field
@@ -366,6 +369,7 @@
<field name="model">pms.folio</field> <field name="model">pms.folio</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<graph type="bar"> <graph type="bar">
</graph> </graph>
</field> </field>
</record> </record>

View File

@@ -14,6 +14,7 @@
<notebook> <notebook>
<page string="General Information" name="property_general"> <page string="General Information" name="property_general">
<group> <group>
</group> </group>
</page> </page>
<page string="Settings" name="property_settings"> <page string="Settings" name="property_settings">

View File

@@ -41,10 +41,7 @@
class="oe_highlight" class="oe_highlight"
type="object" type="object"
/> />
<field <field name="state" widget="statusbar" />
name="state"
widget="statusbar"
/>
</header> </header>
<div <div
class="alert alert-info" class="alert alert-info"
@@ -52,7 +49,8 @@
style="margin-bottom:0px;" style="margin-bottom:0px;"
attrs="{'invisible': ['|',('shared_folio','=',False),('splitted', '=', True)]}" attrs="{'invisible': ['|',('shared_folio','=',False),('splitted', '=', True)]}"
> >
This reservation has other reservantions and/or services in the folio, you can check it in the This reservation has other reservantions and/or services in the
folio, you can check it in the
<bold> <bold>
<button <button
class="alert-link" class="alert-link"
@@ -68,7 +66,8 @@
style="margin-bottom:0px;" style="margin-bottom:0px;"
attrs="{'invisible': [('splitted','=',False)]}" attrs="{'invisible': [('splitted','=',False)]}"
> >
This reservation is part of splitted reservation!, you can check it in the This reservation is part of splitted reservation!, you can check it
in the
<bold> <bold>
<button <button
class="alert-link" class="alert-link"
@@ -151,11 +150,15 @@
<span <span
class="label label-danger" class="label label-danger"
attrs="{'invisible': [('state', 'not in', ('cancelled'))]}" attrs="{'invisible': [('state', 'not in', ('cancelled'))]}"
>Cancelled Reservation!</span> >
Cancelled Reservation!
</span>
<span <span
class="label label-warning" class="label label-warning"
attrs="{'invisible': [('overbooking', '=', False)]}" attrs="{'invisible': [('overbooking', '=', False)]}"
>OverBooking!</span> >
OverBooking!
</span>
<h1> <h1>
<field <field
name="room_id" name="room_id"
@@ -526,22 +529,25 @@
</form> </form>
</field> </field>
</record> </record>
<!-- Calendar --> <!-- Calendar -->
<record id="pms_reservation_view_calendar" model="ir.ui.view"> <record id="pms_reservation_view_calendar" model="ir.ui.view">
<field name="name">pms.reservation.view.calendar</field> <field name="name">pms.reservation.view.calendar</field>
<field name="model">pms.reservation</field> <field name="model">pms.reservation</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<calendar date_start="checkin" date_stop="checkout" <calendar
string="Reservations" quick_add="False" date_start="checkin"
mode="month" scales="month,year"> date_stop="checkout"
string="Reservations"
quick_add="False"
mode="month"
scales="month,year"
>
<field name="partner_id" avatar_field="image_128" /> <field name="partner_id" avatar_field="image_128" />
<field name="room_type_id" /> <field name="room_type_id" />
<field name="room_id" /> <field name="room_id" />
</calendar> </calendar>
</field> </field>
</record> </record>
<!-- Form view Checkin Partners from reservation --> <!-- Form view Checkin Partners from reservation -->
<record model="ir.ui.view" id="pms_reservation_checkin_view_form"> <record model="ir.ui.view" id="pms_reservation_checkin_view_form">
<field name="name">pms.reservation.checkin.form</field> <field name="name">pms.reservation.checkin.form</field>
@@ -562,7 +568,8 @@
style="margin-bottom:0px;" style="margin-bottom:0px;"
attrs="{'invisible': ['|',('shared_folio','=',False),('splitted', '=', True)]}" attrs="{'invisible': ['|',('shared_folio','=',False),('splitted', '=', True)]}"
> >
This reservation has other reservantions and/or services in the folio, you can check it in the This reservation has other reservantions and/or services in the
folio, you can check it in the
<bold> <bold>
<button <button
class="alert-link" class="alert-link"
@@ -578,11 +585,15 @@
<span <span
class="label label-danger" class="label label-danger"
attrs="{'invisible': [('state', 'not in', ('cancelled'))]}" attrs="{'invisible': [('state', 'not in', ('cancelled'))]}"
>Cancelled Reservation!</span> >
Cancelled Reservation!
</span>
<span <span
class="label label-warning" class="label label-warning"
attrs="{'invisible': [('overbooking', '=', False)]}" attrs="{'invisible': [('overbooking', '=', False)]}"
>OverBooking!</span> >
OverBooking!
</span>
<h2> <h2>
<field <field
name="room_id" name="room_id"
@@ -607,7 +618,8 @@
attrs="{'invisible': [('reservation_type','not in',('staff'))]}" attrs="{'invisible': [('reservation_type','not in',('staff'))]}"
/> --> /> -->
<h3> <h3>
From <span class="fa-sign-in" style="margin: 5px;" /> From
<span class="fa-sign-in" style="margin: 5px;" />
<field <field
name="checkin" name="checkin"
style="margin-right: 10px;" style="margin-right: 10px;"
@@ -642,15 +654,16 @@
<field name="name">pms.reservation.tree</field> <field name="name">pms.reservation.tree</field>
<field name="model">pms.reservation</field> <field name="model">pms.reservation</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree <tree string="Reservation" multi_edit="1" sample="1" class="o_sale_order">
string="Reservation"
multi_edit="1" sample="1"
class="o_sale_order"
>
<field name="splitted" invisible="1" /> <field name="splitted" invisible="1" />
<field name="pricelist_id" invisible="1" /> <field name="pricelist_id" invisible="1" />
<field name="room_id" options="{'no_create': True,'no_open': True}" /> <field name="room_id" options="{'no_create': True,'no_open': True}" />
<field name="checkin" widget="daterange" class="oe_inline" options="{'related_end_date': 'checkout'}"/> <field
name="checkin"
widget="daterange"
class="oe_inline"
options="{'related_end_date': 'checkout'}"
/>
<field name="checkout" widget="date" /> <field name="checkout" widget="date" />
<field name="nights" /> <field name="nights" />
<button <button
@@ -666,7 +679,11 @@
<field name="adults" string="Persons" /> <field name="adults" string="Persons" />
<field name="overbooking" invisible="1" /> <field name="overbooking" invisible="1" />
<field name="activity_ids" widget="list_activity" optional="show" /> <field name="activity_ids" widget="list_activity" optional="show" />
<field name="create_uid" optional="show" widget="many2one_avatar_user"/> <field
name="create_uid"
optional="show"
widget="many2one_avatar_user"
/>
<field name="origin" /> <field name="origin" />
<field name="checkin_partner_ids" invisible="1" /> <field name="checkin_partner_ids" invisible="1" />
<field name="to_assign" invisible="1" /> <field name="to_assign" invisible="1" />
@@ -675,8 +692,19 @@
<field name="price_subtotal" invisible="1" /> <field name="price_subtotal" invisible="1" />
<field name="price_total" /> <field name="price_total" />
<field name="folio_pending_amount" string="Folio Pending Amount" /> <field name="folio_pending_amount" string="Folio Pending Amount" />
<field name="company_id" groups="base.group_multi_company" optional="show" readonly="1" /> <field
<field name="state" decoration-success="state == 'done'" decoration-info="state == 'confirm'" widget="badge" optional="show"/> name="company_id"
groups="base.group_multi_company"
optional="show"
readonly="1"
/>
<field
name="state"
decoration-success="state == 'done'"
decoration-info="state == 'confirm'"
widget="badge"
optional="show"
/>
</tree> </tree>
</field> </field>
</record> </record>
@@ -866,7 +894,12 @@
<searchpanel> <searchpanel>
<field name="room_type_id" string="Room Type" enable_counters="1" /> <field name="room_type_id" string="Room Type" enable_counters="1" />
<field name="pricelist_id" string="Pricelist" enable_counters="1" /> <field name="pricelist_id" string="Pricelist" enable_counters="1" />
<field name="state" string="State" enable_counters="1" select="multi" /> <field
name="state"
string="State"
enable_counters="1"
select="multi"
/>
</searchpanel> </searchpanel>
</search> </search>
</field> </field>

View File

@@ -119,13 +119,15 @@
<field name="name" /> <field name="name" />
</strong> </strong>
</li> </li>
<li class="mb4">Room Type: <field <li class="mb4">
name="room_type_id" Room Type:
/></li> <field name="room_type_id" />
</li>
<li class="badge mb4"> <li class="badge mb4">
<strong>Capacity <field <strong>
name="capacity" Capacity
/></strong> <field name="capacity" />
</strong>
</li> </li>
</ul> </ul>
</div> </div>

View File

@@ -74,11 +74,15 @@
<field name="name" /> <field name="name" />
</strong> </strong>
</li> </li>
<li class="mb4">Room Type: <field <li class="mb4">
name="room_type_id" Room Type:
/></li> <field name="room_type_id" />
</li>
<li class="badge mb4"> <li class="badge mb4">
<strong>Beds <field name="beds" /></strong> <strong>
Beds
<field name="beds" />
</strong>
</li> </li>
</ul> </ul>
</div> </div>