mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
Precommit V14
This commit is contained in:
13
.copier-answers.yml
Normal file
13
.copier-answers.yml
Normal 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
74
.gitignore
vendored
@@ -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
|
||||
|
||||
# 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/
|
||||
|
||||
@@ -10,4 +10,3 @@ known_odoo=odoo
|
||||
known_odoo_addons=odoo.addons
|
||||
sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER
|
||||
default_section=THIRDPARTY
|
||||
known_third_party=openerp,werkzeug
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
exclude: |
|
||||
(?x)
|
||||
# NOT INSTALLABLE ADDONS
|
||||
# END NOT INSTALLABLE ADDONS
|
||||
# Files and folders generated by bots, to avoid loops
|
||||
^setup/|/static/description/index\.html$|
|
||||
# Maybe reactivate this when all README files include prettier ignore tags?
|
||||
@@ -12,28 +14,42 @@ exclude: |
|
||||
(LICENSE.*|COPYING.*)
|
||||
default_language_version:
|
||||
python: python3
|
||||
node: "14.13.0"
|
||||
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
|
||||
rev: 19.10b0
|
||||
rev: 20.8b1
|
||||
hooks:
|
||||
- id: black
|
||||
- repo: https://github.com/prettier/prettier
|
||||
rev: "1.19.1"
|
||||
rev: 2.1.2
|
||||
hooks:
|
||||
- id: prettier
|
||||
# TODO Avoid awebdeveloper/pre-commit-prettier if possible
|
||||
# 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
|
||||
name: prettier + plugin-xml
|
||||
additional_dependencies:
|
||||
- "prettier@1.19.1"
|
||||
- "@prettier/plugin-xml@0.7.2"
|
||||
files: \.xml$
|
||||
- "@prettier/plugin-xml@0.12.0"
|
||||
args:
|
||||
- --plugin=@prettier/plugin-xml
|
||||
- repo: https://github.com/pre-commit/mirrors-eslint
|
||||
rev: v6.8.0
|
||||
rev: v7.8.1
|
||||
hooks:
|
||||
- id: eslint
|
||||
verbose: true
|
||||
@@ -41,7 +57,7 @@ repos:
|
||||
- --color
|
||||
- --fix
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v2.4.0
|
||||
rev: v3.2.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
# exclude autogenerated files
|
||||
@@ -62,41 +78,47 @@ repos:
|
||||
- id: check-xml
|
||||
- id: mixed-line-ending
|
||||
args: ["--fix=lf"]
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.7.9
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
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:
|
||||
- id: flake8
|
||||
name: flake8 except __init__.py
|
||||
exclude: /__init__\.py$
|
||||
additional_dependencies: ["flake8-bugbear==19.8.0"]
|
||||
additional_dependencies: ["flake8-bugbear==20.1.4"]
|
||||
- id: flake8
|
||||
name: flake8 only __init__.py
|
||||
args: ["--extend-ignore=F401"] # ignore unused imports in __init__.py
|
||||
files: /__init__\.py$
|
||||
additional_dependencies: ["flake8-bugbear==19.8.0"]
|
||||
- repo: https://github.com/pre-commit/mirrors-pylint
|
||||
rev: v2.3.1
|
||||
additional_dependencies: ["flake8-bugbear==20.1.4"]
|
||||
- repo: https://github.com/PyCQA/pylint
|
||||
rev: pylint-2.5.3
|
||||
hooks:
|
||||
- id: pylint
|
||||
name: pylint with optional checks
|
||||
args: ["--rcfile=.pylintrc", "--exit-zero"]
|
||||
args:
|
||||
- --rcfile=.pylintrc
|
||||
- --exit-zero
|
||||
verbose: true
|
||||
additional_dependencies: ["pylint-odoo==3.1.0"]
|
||||
additional_dependencies: &pylint_deps
|
||||
- pylint-odoo==3.5.0
|
||||
- id: pylint
|
||||
name: pylint with mandatory checks
|
||||
args: ["--rcfile=.pylintrc-mandatory"]
|
||||
additional_dependencies: ["pylint-odoo==3.1.0"]
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
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
|
||||
args:
|
||||
- --rcfile=.pylintrc-mandatory
|
||||
additional_dependencies: *pylint_deps
|
||||
|
||||
@@ -45,8 +45,6 @@ enable=anomalous-backslash-in-string,
|
||||
method-inverse,
|
||||
method-required-super,
|
||||
method-search,
|
||||
missing-import-error,
|
||||
missing-manifest-dependency,
|
||||
openerp-exception-warning,
|
||||
pointless-statement,
|
||||
pointless-string-statement,
|
||||
@@ -72,6 +70,7 @@ enable=anomalous-backslash-in-string,
|
||||
deprecated-module,
|
||||
file-not-used,
|
||||
invalid-commit,
|
||||
missing-manifest-dependency,
|
||||
missing-newline-extrafiles,
|
||||
missing-readme,
|
||||
no-utf8-coding-comment,
|
||||
@@ -81,6 +80,7 @@ enable=anomalous-backslash-in-string,
|
||||
too-complex,
|
||||
unnecessary-utf8-coding-comment
|
||||
|
||||
|
||||
[REPORTS]
|
||||
msg-template={path}:{line}: [{msg_id}({symbol}), {obj}] {msg}
|
||||
output-format=colorized
|
||||
|
||||
@@ -38,8 +38,6 @@ enable=anomalous-backslash-in-string,
|
||||
method-inverse,
|
||||
method-required-super,
|
||||
method-search,
|
||||
missing-import-error,
|
||||
missing-manifest-dependency,
|
||||
openerp-exception-warning,
|
||||
pointless-statement,
|
||||
pointless-string-statement,
|
||||
|
||||
57
.travis.yml
57
.travis.yml
@@ -1,49 +1,48 @@
|
||||
language: python
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.cache/pip
|
||||
- $HOME/.cache/pre-commit
|
||||
|
||||
python:
|
||||
- "3.5"
|
||||
|
||||
sudo: false
|
||||
cache: pip
|
||||
- "3.6"
|
||||
|
||||
addons:
|
||||
postgresql: "9.2" # minimal postgresql version for the daterange method
|
||||
postgresql: "9.6"
|
||||
apt:
|
||||
packages:
|
||||
- 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:
|
||||
global:
|
||||
- VERSION="11.0" TESTS="0" LINT_CHECK="0" TRANSIFEX="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"
|
||||
- VERSION="14.0" TESTS="0" LINT_CHECK="0" MAKEPOT="0"
|
||||
|
||||
install:
|
||||
- git clone https://github.com/OCA/maintainer-quality-tools.git
|
||||
${HOME}/maintainer-quality-tools --depth=1
|
||||
- git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git
|
||||
${HOME}/maintainer-quality-tools
|
||||
- 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
|
||||
|
||||
script:
|
||||
- travis_wait travis_run_tests
|
||||
- travis_run_tests
|
||||
|
||||
after_success:
|
||||
- travis_after_tests_success
|
||||
|
||||
10
CONTRIBUTING.md
Normal file
10
CONTRIBUTING.md
Normal 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
10
LICENSE
@@ -1,7 +1,7 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
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
|
||||
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>
|
||||
|
||||
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
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
@@ -658,4 +658,4 @@ specific requirements.
|
||||
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.
|
||||
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/>.
|
||||
|
||||
46
README.md
46
README.md
@@ -1,22 +1,36 @@
|
||||
[](https://travis-ci.org/hootel/hootel) [](https://codecov.io/gh/hootel/hootel) 
|
||||
[](https://runbot.odoo-community.org/runbot/repo/github-com-oca-pms-)
|
||||
[](https://travis-ci.com/OCA/pms)
|
||||
[](https://codecov.io/gh/OCA/pms)
|
||||
[](https://translation.odoo-community.org/engage/pms-14-0/?utm_source=widget)
|
||||
|
||||
# ROOMDOO
|
||||
All-in-One Property Management System (PMS) focused on medium-sized hotels for managing every aspect of your property's daily operations.
|
||||
<!-- /!\ do not modify above this line -->
|
||||
|
||||
You will find modules for:
|
||||
# Property Management System
|
||||
|
||||
- Manage hotel properties with multi-hotel and multi-company support.
|
||||
- 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.
|
||||
All-in-One Property Management System (PMS) focused on medium-sizeations.
|
||||
|
||||
<!-- /!\ do not modify below this line -->
|
||||
|
||||
Bug Tracker
|
||||
-----------
|
||||
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.
|
||||
<!-- prettier-ignore-start -->
|
||||
|
||||
Contributing
|
||||
------------
|
||||
Do you want to contribute? Please, do not hesitate to contact any of the current contributors :)
|
||||
[//]: # (addons)
|
||||
|
||||
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
1
oca_dependencies.txt
Normal file
@@ -0,0 +1 @@
|
||||
# See https://github.com/OCA/odoo-community.org/blob/master/website/Contribution/CONTRIBUTING.rst#oca_dependencies-txt
|
||||
@@ -1,4 +1,5 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from . import models
|
||||
|
||||
# from . import wizard
|
||||
|
||||
@@ -61,8 +61,14 @@
|
||||
"views/product_pricelist_views.xml",
|
||||
"views/product_template_views.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",],
|
||||
}
|
||||
|
||||
@@ -3,9 +3,17 @@
|
||||
<data noupdate="1">
|
||||
<!-- pms.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'))]" />
|
||||
</record>
|
||||
<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'))]" />
|
||||
</record>
|
||||
<!-- Basic pms -->
|
||||
@@ -26,17 +34,5 @@
|
||||
<field name="website">https://www.commitsun.com</field>
|
||||
<field name="folio_sequence_id" ref="pms.seq_pms_folio" />
|
||||
</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>
|
||||
</odoo>
|
||||
|
||||
@@ -286,15 +286,16 @@
|
||||
<!-- room.closure.reason -->
|
||||
<record id="pms_room_closure_reason_0" model="room.closure.reason">
|
||||
<field name="name">Maintenance</field>
|
||||
<field
|
||||
name="description"
|
||||
>Used for closing of rooms which require a maintenance. You can specify the reason in the own reservation.</field>
|
||||
<field name="description">
|
||||
Used for closing of rooms which require a maintenance. You can specify
|
||||
the reason in the own reservation.
|
||||
</field>
|
||||
</record>
|
||||
<record id="pms_room_closure_reason_1" model="room.closure.reason">
|
||||
<field name="name">VIP Privacy</field>
|
||||
<field
|
||||
name="description"
|
||||
>Used for closing of rooms for extra privacy.</field>
|
||||
<field name="description">
|
||||
Used for closing of rooms for extra privacy.
|
||||
</field>
|
||||
</record>
|
||||
<!-- Multi pms Demo -->
|
||||
<record id="demo_pms_room_type_restriction" model="pms.room.type.restriction">
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
<field name="checkin" eval="DateTime.today() + timedelta(8)" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(9)" />
|
||||
<field name="board_service_room_id" ref="pms_board_service_room_2" />
|
||||
|
||||
</record>
|
||||
<record id="pms_reservation_1" model="pms.reservation">
|
||||
<field name="reservation_type">"out"</field>
|
||||
@@ -61,7 +60,6 @@
|
||||
<field name="checkin" eval="DateTime.today()" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(3)" />
|
||||
<field name="board_service_room_id" ref="pms_board_service_room_2" />
|
||||
|
||||
</record>
|
||||
<record id="pms_reservation_7" model="pms.reservation">
|
||||
<field name="partner_id" ref="base.res_partner_address_10" />
|
||||
@@ -71,7 +69,6 @@
|
||||
<field name="checkin" eval="DateTime.today()" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(3)" />
|
||||
<field name="board_service_room_id" ref="pms_board_service_room_0" />
|
||||
|
||||
</record>
|
||||
<record id="pms_reservation_8" model="pms.reservation">
|
||||
<field name="partner_id" ref="base.res_partner_address_13" />
|
||||
@@ -81,7 +78,6 @@
|
||||
<field name="checkin" eval="DateTime.today() + timedelta(7)" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(8)" />
|
||||
<field name="board_service_room_id" ref="pms_board_service_room_1" />
|
||||
|
||||
</record>
|
||||
<record id="pms_reservation_9" model="pms.reservation">
|
||||
<field name="partner_id" ref="base.res_partner_address_15" />
|
||||
@@ -108,7 +104,6 @@
|
||||
<field name="checkin" eval="DateTime.today()" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(4)" />
|
||||
<field name="board_service_room_id" ref="pms_board_service_room_2" />
|
||||
|
||||
</record>
|
||||
<record id="pms_reservation_12" model="pms.reservation">
|
||||
<field name="partner_id" ref="base.res_partner_address_10" />
|
||||
@@ -127,7 +122,6 @@
|
||||
<field name="checkin" eval="DateTime.today() + timedelta(11)" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(13)" />
|
||||
<field name="board_service_room_id" ref="pms_board_service_room_0" />
|
||||
|
||||
</record>
|
||||
<record id="pms_reservation_14" model="pms.reservation">
|
||||
<field name="partner_id" ref="base.res_partner_address_33" />
|
||||
@@ -163,7 +157,6 @@
|
||||
<field name="checkin" eval="DateTime.today()" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(4)" />
|
||||
<field name="board_service_room_id" ref="pms_board_service_room_2" />
|
||||
|
||||
</record>
|
||||
<record id="pms_reservation_18" model="pms.reservation">
|
||||
<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="checkin" eval="DateTime.today() + timedelta(10)" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(12)" />
|
||||
|
||||
</record>
|
||||
<record id="pms_reservation_29" model="pms.reservation">
|
||||
<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="checkin" eval="DateTime.today() + timedelta(1)" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(4)" />
|
||||
|
||||
</record>
|
||||
<record id="pms_reservation_30" model="pms.reservation">
|
||||
<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="checkin" eval="DateTime.today() + timedelta(6)" />
|
||||
<field name="checkout" eval="DateTime.today() + timedelta(8)" />
|
||||
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
from . import ir_http
|
||||
from . import ir_sequence
|
||||
|
||||
# from . import payment_return
|
||||
from . import pms_board_service_room_type
|
||||
from . import pms_property
|
||||
@@ -28,7 +29,8 @@ from . import pms_reservation_line
|
||||
from . import pms_checkin_partner
|
||||
from . import product_pricelist
|
||||
from . import res_partner
|
||||
from . import mail_compose_message
|
||||
|
||||
# from . import mail_compose_message
|
||||
from . import pms_room_type_class
|
||||
from . import pms_room_closure_reason
|
||||
from . import pms_service_line
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
|
||||
import json
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo import _, fields, models
|
||||
from odoo.tools import float_is_zero
|
||||
|
||||
|
||||
@@ -12,18 +12,20 @@ class AccountMove(models.Model):
|
||||
|
||||
# Field Declarations
|
||||
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")
|
||||
from_folio = fields.Boolean(compute="_computed_folio_origin")
|
||||
from_folio = fields.Boolean(compute="_compute_folio_origin")
|
||||
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
|
||||
|
||||
def _computed_folio_origin(self):
|
||||
def _compute_folio_origin(self):
|
||||
for inv in self:
|
||||
inv.from_folio = False
|
||||
inv.folio_ids = False
|
||||
@@ -53,7 +55,7 @@ class AccountMove(models.Model):
|
||||
}
|
||||
|
||||
# Business methods
|
||||
def _get_outstanding_folios_JSON(self):
|
||||
def _compute_get_outstanding_folios_JSON(self):
|
||||
self.ensure_one()
|
||||
self.outstanding_folios_debits_widget = json.dumps(False)
|
||||
if self.from_folio:
|
||||
|
||||
@@ -10,7 +10,9 @@ class AccountPayment(models.Model):
|
||||
# Fields declaration
|
||||
folio_id = fields.Many2one("pms.folio", string="Folio")
|
||||
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_date = fields.Date()
|
||||
@@ -53,8 +55,6 @@ class AccountPayment(models.Model):
|
||||
self.save_date = self._origin.payment_date
|
||||
|
||||
# Action methods
|
||||
"""WIP"""
|
||||
|
||||
# def return_payment_folio(self):
|
||||
# journal = self.journal_id
|
||||
# partner = self.partner_id
|
||||
@@ -129,18 +129,15 @@ class AccountPayment(models.Model):
|
||||
if rec and not self._context.get("ignore_notification_post", False):
|
||||
for pay in self:
|
||||
if pay.folio_id:
|
||||
msg = (
|
||||
_(
|
||||
msg = _(
|
||||
"Payment of %s %s registered from %s \
|
||||
using %s payment method"
|
||||
)
|
||||
% (
|
||||
) % (
|
||||
pay.amount,
|
||||
pay.currency_id.symbol,
|
||||
pay.communication,
|
||||
pay.journal_id.name,
|
||||
)
|
||||
)
|
||||
pay.folio_id.message_post(subject=_("Payment"), body=msg)
|
||||
|
||||
def modify_payment(self):
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
# Copyright 2019 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import _, models
|
||||
from odoo.exceptions import MissingError
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
@@ -21,7 +20,8 @@ class IrHttp(models.AbstractModel):
|
||||
user.pms_property_id.id,
|
||||
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": [
|
||||
(property.id, property.name)
|
||||
for property in user.pms_property_ids
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# 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):
|
||||
@@ -13,12 +13,12 @@ class MailComposeMessage(models.TransientModel):
|
||||
and self._context.get("default_res_id")
|
||||
and self._context.get("mark_so_as_sent")
|
||||
):
|
||||
folio = self.env["pms.folio"].browse([self._context["default_res_id"]])
|
||||
# TODO: WorkFlow Mails
|
||||
# if folio:
|
||||
# cmds = [
|
||||
# (1, lid, {"to_send": False}) for lid in folio.reservation_ids.ids
|
||||
# ]
|
||||
# if any(cmds):
|
||||
# folio.reservation_ids = cmds
|
||||
folio = self.env["pms.folio"].browse([self._context["default_res_id"]])
|
||||
if folio:
|
||||
cmds = [
|
||||
(1, lid, {"to_send": False}) for lid in folio.reservation_ids.ids
|
||||
]
|
||||
if any(cmds):
|
||||
folio.reservation_ids = cmds
|
||||
return super(MailComposeMessage, self).send_mail(auto_commit=auto_commit)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# 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):
|
||||
|
||||
@@ -18,7 +18,8 @@ class PmsBoardServiceRoomType(models.Model):
|
||||
for res in self:
|
||||
if res.pricelist_id:
|
||||
name = u"{} ({})".format(
|
||||
res.pms_board_service_id.name, res.pricelist_id.name,
|
||||
res.pms_board_service_id.name,
|
||||
res.pricelist_id.name,
|
||||
)
|
||||
else:
|
||||
name = u"{} ({})".format(res.pms_board_service_id.name, _("Generic"))
|
||||
|
||||
@@ -21,7 +21,7 @@ class PmsFolio(models.Model):
|
||||
for folio in self:
|
||||
name = folio.name
|
||||
if len(folio.reservation_ids) > 1:
|
||||
name += ' (%s)' % len(folio.reservation_ids)
|
||||
name += " (%s)" % len(folio.reservation_ids)
|
||||
result.append((folio.id, name))
|
||||
return result
|
||||
|
||||
@@ -39,7 +39,9 @@ class PmsFolio(models.Model):
|
||||
|
||||
@api.model
|
||||
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
|
||||
name = fields.Char(
|
||||
@@ -59,7 +61,9 @@ class PmsFolio(models.Model):
|
||||
help="Room reservation detail.",
|
||||
)
|
||||
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(
|
||||
"pms.service",
|
||||
@@ -70,7 +74,10 @@ class PmsFolio(models.Model):
|
||||
"include in main Invoice.",
|
||||
)
|
||||
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(
|
||||
"account.analytic.account",
|
||||
@@ -108,7 +115,10 @@ class PmsFolio(models.Model):
|
||||
readonly=False,
|
||||
)
|
||||
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)
|
||||
# return_ids = fields.One2many("payment.return", "folio_id", readonly=True)
|
||||
@@ -125,7 +135,7 @@ class PmsFolio(models.Model):
|
||||
move_ids = fields.Many2many(
|
||||
"account.move",
|
||||
string="Invoices",
|
||||
compute="_get_invoiced",
|
||||
compute="_compute_get_invoiced",
|
||||
readonly=True,
|
||||
copy=False,
|
||||
)
|
||||
@@ -155,7 +165,10 @@ class PmsFolio(models.Model):
|
||||
default=lambda *a: "normal",
|
||||
)
|
||||
channel_type = fields.Selection(
|
||||
[("direct", "Direct"), ("agency", "Agency"),],
|
||||
[
|
||||
("direct", "Direct"),
|
||||
("agency", "Agency"),
|
||||
],
|
||||
string="Sales Channel",
|
||||
compute="_compute_channel_type",
|
||||
store=True,
|
||||
@@ -203,13 +216,13 @@ class PmsFolio(models.Model):
|
||||
|
||||
# Amount Fields------------------------------------------------------
|
||||
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(
|
||||
# compute="compute_amount", store=True, string="Payment Returns"
|
||||
# compute="_compute_amount", store=True, string="Payment Returns"
|
||||
# )
|
||||
invoices_paid = fields.Monetary(
|
||||
compute="compute_amount",
|
||||
compute="_compute_amount",
|
||||
store=True,
|
||||
track_visibility="onchange",
|
||||
string="Payments",
|
||||
@@ -218,17 +231,17 @@ class PmsFolio(models.Model):
|
||||
string="Untaxed Amount",
|
||||
store=True,
|
||||
readonly=True,
|
||||
compute="_amount_all",
|
||||
compute="_compute_amount_all",
|
||||
track_visibility="onchange",
|
||||
)
|
||||
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(
|
||||
string="Total",
|
||||
store=True,
|
||||
readonly=True,
|
||||
compute="_amount_all",
|
||||
compute="_compute_amount_all",
|
||||
track_visibility="always",
|
||||
)
|
||||
# Checkin Fields-----------------------------------------------------
|
||||
@@ -249,7 +262,7 @@ class PmsFolio(models.Model):
|
||||
("no", "Nothing to Invoice"),
|
||||
],
|
||||
string="Invoice Status",
|
||||
compute="_get_invoiced",
|
||||
compute="_compute_get_invoiced",
|
||||
store=True,
|
||||
readonly=True,
|
||||
default="no",
|
||||
@@ -300,9 +313,9 @@ class PmsFolio(models.Model):
|
||||
def _compute_channel_type(self):
|
||||
for folio in self:
|
||||
if folio.agency_id:
|
||||
folio.channel_type = 'agency'
|
||||
folio.channel_type = "agency"
|
||||
else:
|
||||
folio.channel_type = 'direct'
|
||||
folio.channel_type = "direct"
|
||||
|
||||
@api.depends("partner_id")
|
||||
def _compute_payment_term_id(self):
|
||||
@@ -317,7 +330,7 @@ class PmsFolio(models.Model):
|
||||
@api.depends(
|
||||
"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:
|
||||
- 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")
|
||||
def _amount_all(self):
|
||||
def _compute_amount_all(self):
|
||||
"""
|
||||
Compute the total amounts of the SO.
|
||||
"""
|
||||
@@ -432,10 +445,8 @@ class PmsFolio(models.Model):
|
||||
)
|
||||
|
||||
# TODO: Add return_ids to depends
|
||||
@api.depends(
|
||||
"amount_total", "payment_ids", "reservation_type", "state"
|
||||
)
|
||||
def compute_amount(self):
|
||||
@api.depends("amount_total", "payment_ids", "reservation_type", "state")
|
||||
def _compute_amount(self):
|
||||
acc_pay_obj = self.env["account.payment"]
|
||||
for record in self:
|
||||
if record.reservation_type in ("staff", "out"):
|
||||
@@ -455,7 +466,9 @@ class PmsFolio(models.Model):
|
||||
# ("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
|
||||
# REVIEW: Must We ignored services in cancelled folios
|
||||
# pending amount?
|
||||
@@ -548,10 +561,14 @@ class PmsFolio(models.Model):
|
||||
# TODO: Make sequence from property, not company
|
||||
if vals.get("name", _("New")) == _("New") or "name" not in vals:
|
||||
# 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"]
|
||||
vals["name"] = self.env["ir.sequence"].search([
|
||||
('pms_property_id', '=', pms_property_id)
|
||||
]).next_by_code("pms.folio") or _("New")
|
||||
pms_property_id = (
|
||||
self.env.user.pms_property_id.id
|
||||
if "pms_property_id" not in vals
|
||||
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)
|
||||
return result
|
||||
|
||||
@@ -569,7 +586,9 @@ class PmsFolio(models.Model):
|
||||
):
|
||||
reservation.action_cancel()
|
||||
self.write(
|
||||
{"state": "cancel",}
|
||||
{
|
||||
"state": "cancel",
|
||||
}
|
||||
)
|
||||
return True
|
||||
|
||||
@@ -589,9 +608,7 @@ class PmsFolio(models.Model):
|
||||
# self._create_analytic_account()
|
||||
return True
|
||||
|
||||
"""
|
||||
CHECKIN/OUT PROCESS
|
||||
"""
|
||||
# CHECKIN/OUT PROCESS
|
||||
|
||||
def _compute_checkin_partner_count(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:
|
||||
res[group]["amount"] += t["amount"]
|
||||
res[group]["base"] += t["base"]
|
||||
res = sorted(res.items(), key=lambda l: l[0].sequence)
|
||||
res = [(l[0].name, l[1]["amount"], l[1]["base"], len(res)) for l in res]
|
||||
res = sorted(res.items(), key=lambda line: line[0].sequence)
|
||||
res = [
|
||||
(line[0].name, line[1]["amount"], line[1]["base"], len(res)) for line in res
|
||||
]
|
||||
return res
|
||||
|
||||
@@ -53,8 +53,8 @@ class PmsProperty(models.Model):
|
||||
default_cancel_policy_days = fields.Integer("Cancellation Days")
|
||||
default_cancel_policy_percent = fields.Float("Percent to pay")
|
||||
folio_sequence_id = fields.Many2one(
|
||||
'ir.sequence', 'Folio Sequence',
|
||||
check_company=True, copy=False)
|
||||
"ir.sequence", "Folio Sequence", check_company=True, copy=False
|
||||
)
|
||||
|
||||
# Constraints and onchanges
|
||||
@api.constrains("default_arrival_hour", "default_departure_hour")
|
||||
|
||||
@@ -118,13 +118,19 @@ class PmsReservation(models.Model):
|
||||
domain="[('id', 'in', allowed_room_ids)]",
|
||||
)
|
||||
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(
|
||||
"pms.folio", string="Folio", track_visibility="onchange", ondelete="restrict",
|
||||
"pms.folio",
|
||||
string="Folio",
|
||||
track_visibility="onchange",
|
||||
ondelete="restrict",
|
||||
)
|
||||
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(
|
||||
"pms.room.type",
|
||||
@@ -157,7 +163,8 @@ class PmsReservation(models.Model):
|
||||
related="folio_id.company_id", string="Company", store=True, readonly=True
|
||||
)
|
||||
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(
|
||||
"pms.reservation.line",
|
||||
@@ -247,7 +254,11 @@ class PmsReservation(models.Model):
|
||||
reservation_type = fields.Selection(
|
||||
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")
|
||||
cancelled_reason = fields.Selection(
|
||||
@@ -283,14 +294,21 @@ class PmsReservation(models.Model):
|
||||
)
|
||||
overbooking = fields.Boolean("Is Overbooking", 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(
|
||||
selection=[("direct", "Direct"), ("agency", "Agency"),],
|
||||
selection=[
|
||||
("direct", "Direct"),
|
||||
("agency", "Agency"),
|
||||
],
|
||||
string="Sales Channel",
|
||||
default="direct",
|
||||
)
|
||||
subchannel_direct = fields.Selection(
|
||||
selection=[("door", "Door"), ("mail", "Mail"), ("phone", "Phone"),],
|
||||
selection=[
|
||||
("door", "Door"),
|
||||
("mail", "Mail"),
|
||||
("phone", "Phone"),
|
||||
],
|
||||
string="Direct Channel",
|
||||
)
|
||||
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
|
||||
)
|
||||
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
|
||||
email = fields.Char("E-mail", related="partner_id.email")
|
||||
mobile = fields.Char("Mobile", related="partner_id.mobile")
|
||||
@@ -323,14 +341,14 @@ class PmsReservation(models.Model):
|
||||
default="no",
|
||||
)
|
||||
qty_to_invoice = fields.Float(
|
||||
compute="_get_to_invoice_qty",
|
||||
compute="_compute_get_to_invoice_qty",
|
||||
string="To Invoice",
|
||||
store=True,
|
||||
readonly=True,
|
||||
digits=("Product Unit of Measure"),
|
||||
)
|
||||
qty_invoiced = fields.Float(
|
||||
compute="_get_invoice_qty",
|
||||
compute="_compute_get_invoice_qty",
|
||||
string="Invoiced",
|
||||
store=True,
|
||||
readonly=True,
|
||||
@@ -468,14 +486,22 @@ class PmsReservation(models.Model):
|
||||
lambda r: r.date == idate
|
||||
)
|
||||
if not old_line:
|
||||
cmds.append((0, False, {"date": idate},))
|
||||
reservation.reservation_line_ids -= reservation.reservation_line_ids.filtered_domain(
|
||||
cmds.append(
|
||||
(
|
||||
0,
|
||||
False,
|
||||
{"date": idate},
|
||||
)
|
||||
)
|
||||
reservation.reservation_line_ids -= (
|
||||
reservation.reservation_line_ids.filtered_domain(
|
||||
[
|
||||
"|",
|
||||
("date", ">=", reservation.checkout),
|
||||
("date", "<", reservation.checkin),
|
||||
]
|
||||
)
|
||||
)
|
||||
reservation.reservation_line_ids = cmds
|
||||
|
||||
@api.depends("board_service_room_id")
|
||||
@@ -483,7 +509,9 @@ class PmsReservation(models.Model):
|
||||
for reservation in self:
|
||||
board_services = []
|
||||
old_board_lines = reservation.service_ids.filtered_domain(
|
||||
[("is_board_service", "=", True),]
|
||||
[
|
||||
("is_board_service", "=", True),
|
||||
]
|
||||
)
|
||||
if reservation.board_service_room_id:
|
||||
board = self.env["pms.board.service.room.type"].browse(
|
||||
@@ -522,7 +550,7 @@ class PmsReservation(models.Model):
|
||||
if reservation.room_id:
|
||||
if reservation.adults == 0:
|
||||
reservation.adults = reservation.room_id.capacity
|
||||
elif reservation.adults == False:
|
||||
elif not reservation.adults:
|
||||
reservation.adults = 0
|
||||
|
||||
@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
|
||||
if the conditions of no other status is met.
|
||||
- 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.
|
||||
- invoiced: the quantity invoiced is larger or equal to the
|
||||
quantity ordered.
|
||||
@@ -567,7 +595,7 @@ class PmsReservation(models.Model):
|
||||
line.invoice_status = "no"
|
||||
|
||||
@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,
|
||||
the quantity to invoice is calculated from the ordered quantity.
|
||||
@@ -580,7 +608,7 @@ class PmsReservation(models.Model):
|
||||
line.qty_to_invoice = 0
|
||||
|
||||
@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
|
||||
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
|
||||
|
||||
@api.depends("reservation_line_ids")
|
||||
def _computed_nights(self):
|
||||
def _compute_nights(self):
|
||||
for res in self:
|
||||
res.nights = len(res.reservation_line_ids)
|
||||
|
||||
@@ -657,7 +685,11 @@ class PmsReservation(models.Model):
|
||||
)
|
||||
else:
|
||||
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
|
||||
@@ -690,16 +722,21 @@ class PmsReservation(models.Model):
|
||||
@api.constrains("reservation_type", "partner_id")
|
||||
def _check_partner_reservation(self):
|
||||
for reservation in self:
|
||||
if reservation.reservation_type == "out" and \
|
||||
reservation.partner_id != reservation.pms_property_id.partner_id.id:
|
||||
raise models.ValidationError(_("The partner on out reservations must be a property partner"))
|
||||
if (
|
||||
reservation.reservation_type == "out"
|
||||
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")
|
||||
def _check_partner_reservation(self):
|
||||
def _check_clousure_reservation(self):
|
||||
for reservation in self:
|
||||
if reservation.closure_reason_id and \
|
||||
reservation.reservation_type != 'out':
|
||||
raise models.ValidationError(_("Only the out reservations can has a clousure reason"))
|
||||
if reservation.closure_reason_id and reservation.reservation_type != "out":
|
||||
raise models.ValidationError(
|
||||
_("Only the out reservations can has a clousure reason")
|
||||
)
|
||||
|
||||
# @api.onchange("checkin_partner_ids")
|
||||
# def onchange_checkin_partner_ids(self):
|
||||
@@ -811,7 +848,7 @@ class PmsReservation(models.Model):
|
||||
|
||||
# Business methods
|
||||
|
||||
def _computed_shared(self):
|
||||
def _compute_shared(self):
|
||||
# Has this reservation more charges associates in folio?,
|
||||
# Yes?, then, this is share folio ;)
|
||||
for record in self:
|
||||
@@ -884,8 +921,6 @@ class PmsReservation(models.Model):
|
||||
@param self: object pointer
|
||||
"""
|
||||
_logger.info("confirm")
|
||||
pms_reserv_obj = self.env["pms.reservation"]
|
||||
user = self.env["res.users"].browse(self.env.uid)
|
||||
for record in self:
|
||||
vals = {}
|
||||
if record.checkin_partner_ids:
|
||||
@@ -961,8 +996,6 @@ class PmsReservation(models.Model):
|
||||
lines = self.env["pms.reservation.line"].search(domain)
|
||||
reservations_dates = {}
|
||||
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(
|
||||
[record.reservation_id, record.reservation_id.room_type_id]
|
||||
)
|
||||
@@ -994,8 +1027,6 @@ class PmsReservation(models.Model):
|
||||
if reservation.channel_type in ["direct", "agency"]:
|
||||
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):
|
||||
self.ensure_one()
|
||||
recs = self.search([]).filtered(lambda x: x.checkin_partner_pending_count > 0)
|
||||
|
||||
@@ -84,14 +84,16 @@ class PmsReservationLine(models.Model):
|
||||
_sql_constraints = [
|
||||
(
|
||||
"rule_availability",
|
||||
"EXCLUDE (room_id WITH =, date WITH =) WHERE (occupies_availability = True)",
|
||||
"EXCLUDE (room_id WITH =, date WITH =) \
|
||||
WHERE (occupies_availability = True)",
|
||||
"Room Occupied",
|
||||
),
|
||||
]
|
||||
|
||||
# Compute and Search methods
|
||||
@api.depends(
|
||||
"reservation_id.adults", "reservation_id.room_type_id",
|
||||
"reservation_id.adults",
|
||||
"reservation_id.room_type_id",
|
||||
)
|
||||
def _compute_room_id(self):
|
||||
for line in self:
|
||||
@@ -160,7 +162,7 @@ class PmsReservationLine(models.Model):
|
||||
for line in self:
|
||||
if (
|
||||
line.reservation_id.state == "cancelled"
|
||||
or line.reservation_id.overbooking == True
|
||||
or line.reservation_id.overbooking
|
||||
):
|
||||
line.occupies_availability = False
|
||||
else:
|
||||
|
||||
@@ -22,7 +22,7 @@ class PmsRoom(models.Model):
|
||||
for room in self:
|
||||
name = room.name
|
||||
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))
|
||||
return result
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# Copyright 2017 Alexandre Díaz
|
||||
# Copyright 2017 Dario Lodeiros
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
@@ -51,7 +50,10 @@ class PmsRoomType(models.Model):
|
||||
string="Room Type 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", default=False, help="This room type is reservation by beds"
|
||||
)
|
||||
@@ -91,7 +93,10 @@ class PmsRoomType(models.Model):
|
||||
def create(self, vals):
|
||||
""" Add room types as not purchase services. """
|
||||
vals.update(
|
||||
{"purchase_ok": False, "type": "service",}
|
||||
{
|
||||
"purchase_ok": False,
|
||||
"type": "service",
|
||||
}
|
||||
)
|
||||
return super().create(vals)
|
||||
|
||||
@@ -119,27 +124,30 @@ class PmsRoomType(models.Model):
|
||||
Return Dict Code Room Types: subdict with day, discount, price
|
||||
"""
|
||||
vals = {}
|
||||
room_type_ids = kwargs.get("room_type_ids", False)
|
||||
room_types = (
|
||||
self.env["pms.room.type"].browse(room_type_ids)
|
||||
if room_type_ids
|
||||
else self.env["pms.room.type"].search([])
|
||||
)
|
||||
# room_type_ids = kwargs.get("room_type_ids", False)
|
||||
# room_types = (
|
||||
# self.env["pms.room.type"].browse(room_type_ids)
|
||||
# if room_type_ids
|
||||
# else self.env["pms.room.type"].search([])
|
||||
# )
|
||||
date_from = kwargs.get("date_from", False)
|
||||
days = kwargs.get("days", False)
|
||||
discount = kwargs.get("discount", False)
|
||||
if not date_from or not days:
|
||||
raise ValidationError(_("Date From and days are mandatory"))
|
||||
partner_id = kwargs.get("partner_id", False)
|
||||
partner = self.env["res.partner"].browse(partner_id)
|
||||
pricelist_id = kwargs.get(
|
||||
"pricelist_id",
|
||||
partner.property_product_pricelist.id
|
||||
and partner.property_product_pricelist.id
|
||||
or self.env.user.pms_property_id.default_pricelist_id.id,
|
||||
)
|
||||
# partner = self.env["res.partner"].browse(partner_id)
|
||||
# pricelist_id = kwargs.get(
|
||||
# "pricelist_id",
|
||||
# partner.property_product_pricelist.id
|
||||
# and partner.property_product_pricelist.id
|
||||
# or self.env.user.pms_property_id.default_pricelist_id.id,
|
||||
# )
|
||||
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 = {}
|
||||
# TODO: Now it is computed field, We need other way to return rates
|
||||
@@ -155,7 +163,9 @@ class PmsRoomType(models.Model):
|
||||
# rate_vals.update(
|
||||
# {
|
||||
# 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]
|
||||
# ]
|
||||
# }
|
||||
# )
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import _, api, fields, models
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
class PmsRoomTypeAvailability(models.Model):
|
||||
@@ -62,7 +61,9 @@ class PmsRoomTypeAvailability(models.Model):
|
||||
self, checkin, checkout, room_type_id=False, current_lines=False
|
||||
):
|
||||
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)
|
||||
reservations_rooms = reservation_lines.mapped("room_id.id")
|
||||
|
||||
@@ -5,7 +5,7 @@ import logging
|
||||
from datetime import timedelta
|
||||
|
||||
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__)
|
||||
|
||||
@@ -43,7 +43,10 @@ class PmsService(models.Model):
|
||||
|
||||
# Fields declaration
|
||||
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.product", "Service", ondelete="restrict", required=True
|
||||
@@ -91,7 +94,10 @@ class PmsService(models.Model):
|
||||
state = fields.Selection(related="folio_id.state")
|
||||
per_day = fields.Boolean(related="product_id.per_day", related_sudo=True)
|
||||
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()
|
||||
# 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)
|
||||
qty_to_invoice = fields.Float(
|
||||
compute="_get_to_invoice_qty",
|
||||
compute="_compute_get_to_invoice_qty",
|
||||
string="To Invoice",
|
||||
store=True,
|
||||
readonly=True,
|
||||
digits=("Product Unit of Measure"),
|
||||
)
|
||||
qty_invoiced = fields.Float(
|
||||
compute="_get_invoice_qty",
|
||||
compute="_compute_get_invoice_qty",
|
||||
string="Invoiced",
|
||||
store=True,
|
||||
readonly=True,
|
||||
@@ -203,18 +209,27 @@ class PmsService(models.Model):
|
||||
if idate in [
|
||||
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
|
||||
elif not old_line:
|
||||
lines.append(
|
||||
(0, False, {"date": idate, "day_qty": day_qty,})
|
||||
(
|
||||
0,
|
||||
False,
|
||||
{
|
||||
"date": idate,
|
||||
"day_qty": day_qty,
|
||||
},
|
||||
)
|
||||
)
|
||||
else:
|
||||
lines.append((4, old_line.id))
|
||||
move_day = 0
|
||||
if consumed_on == "after":
|
||||
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(lines)
|
||||
service.service_line_ids = lines
|
||||
@@ -239,7 +255,10 @@ class PmsService(models.Model):
|
||||
(
|
||||
0,
|
||||
False,
|
||||
{"date": fields.Date.today(), "day_qty": day_qty,},
|
||||
{
|
||||
"date": fields.Date.today(),
|
||||
"day_qty": day_qty,
|
||||
},
|
||||
)
|
||||
]
|
||||
else:
|
||||
@@ -250,7 +269,10 @@ class PmsService(models.Model):
|
||||
(
|
||||
0,
|
||||
False,
|
||||
{"date": fields.Date.today(), "day_qty": day_qty,},
|
||||
{
|
||||
"date": fields.Date.today(),
|
||||
"day_qty": day_qty,
|
||||
},
|
||||
)
|
||||
]
|
||||
else:
|
||||
@@ -258,7 +280,6 @@ class PmsService(models.Model):
|
||||
|
||||
def _search_old_lines(self, date):
|
||||
self.ensure_one()
|
||||
old_lines = self.env["pms.service.line"]
|
||||
if isinstance(self._origin.id, int):
|
||||
old_line = self._origin.service_line_ids.filtered(lambda r: r.date == date)
|
||||
return old_line
|
||||
@@ -366,7 +387,7 @@ class PmsService(models.Model):
|
||||
return False
|
||||
|
||||
@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,
|
||||
the quantity to invoice is calculated from the ordered quantity.
|
||||
@@ -379,7 +400,7 @@ class PmsService(models.Model):
|
||||
line.qty_to_invoice = 0
|
||||
|
||||
@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 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
|
||||
)
|
||||
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
|
||||
)
|
||||
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
|
||||
status is met.
|
||||
- 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.
|
||||
- upselling: this is possible only for a product invoiced on ordered
|
||||
quantities for which we delivered more than expected.
|
||||
|
||||
@@ -33,7 +33,10 @@ class PmsSharedRoom(models.Model):
|
||||
help="At which floor the room is located.",
|
||||
)
|
||||
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)
|
||||
sequence = fields.Integer("Sequence", required=True)
|
||||
@@ -85,29 +88,39 @@ class PmsSharedRoom(models.Model):
|
||||
@api.constrains("active")
|
||||
def _constrain_active(self):
|
||||
self.bed_ids.write(
|
||||
{"active": self.active,}
|
||||
{
|
||||
"active": self.active,
|
||||
}
|
||||
)
|
||||
|
||||
@api.constrains("room_type_id")
|
||||
def _constrain_room_type_id(self):
|
||||
self.bed_ids.write(
|
||||
{"room_type_id": self.room_type_id.id,}
|
||||
{
|
||||
"room_type_id": self.room_type_id.id,
|
||||
}
|
||||
)
|
||||
|
||||
@api.constrains("floor_id")
|
||||
def _constrain_floor_id(self):
|
||||
self.bed_ids.write(
|
||||
{"floor_id": self.floor_id.id,}
|
||||
{
|
||||
"floor_id": self.floor_id.id,
|
||||
}
|
||||
)
|
||||
|
||||
@api.constrains("sequence")
|
||||
def _constrain_sequence(self):
|
||||
self.bed_ids.write(
|
||||
{"sequence": self.sequence,}
|
||||
{
|
||||
"sequence": self.sequence,
|
||||
}
|
||||
)
|
||||
|
||||
@api.constrains("descrition_sale")
|
||||
def _constrain_descrition_sale(self):
|
||||
self.bed_ids.write(
|
||||
{"description_sale": self.descrition_sale,}
|
||||
{
|
||||
"description_sale": self.descrition_sale,
|
||||
}
|
||||
)
|
||||
|
||||
@@ -49,7 +49,10 @@ class ResPartner(models.Model):
|
||||
("mobile", operator, name),
|
||||
("email", operator, name),
|
||||
]
|
||||
partners = self.search(domain + args, limit=limit,)
|
||||
partners = self.search(
|
||||
domain + args,
|
||||
limit=limit,
|
||||
)
|
||||
res = partners.name_get()
|
||||
if limit:
|
||||
limit_rest = limit - len(partners)
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
t-field="doc.partner_id"
|
||||
t-options='{"widget": "contact", "fields": ["address", "name"], "no_marker": True}'
|
||||
/>
|
||||
<p t-if="doc.partner_id.vat"><t
|
||||
t-esc="doc.company_id.country_id.vat_label or 'TIN'"
|
||||
/>: <span t-field="doc.partner_id.vat" /></p>
|
||||
<p t-if="doc.partner_id.vat">
|
||||
<t t-esc="doc.company_id.country_id.vat_label or 'TIN'" />
|
||||
:
|
||||
<span t-field="doc.partner_id.vat" />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<h2>
|
||||
@@ -75,16 +77,22 @@
|
||||
t-if="display_discount"
|
||||
class="text-right"
|
||||
groups="sale.group_discount_per_so_line"
|
||||
>Disc.(%)</th>
|
||||
>
|
||||
Disc.(%)
|
||||
</th>
|
||||
<th class="text-right">Taxes</th>
|
||||
<th
|
||||
class="text-right"
|
||||
groups="sale.group_show_price_subtotal"
|
||||
>Amount</th>
|
||||
>
|
||||
Amount
|
||||
</th>
|
||||
<th
|
||||
class="text-right price_tax_included"
|
||||
groups="sale.group_show_price_total"
|
||||
>Total Price</th>
|
||||
>
|
||||
Total Price
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="sale_tbody">
|
||||
@@ -196,7 +204,8 @@
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
-<t
|
||||
-
|
||||
<t
|
||||
t-foreach="doc._get_tax_amount_by_group()"
|
||||
t-as="amount_by_group"
|
||||
>
|
||||
@@ -206,8 +215,9 @@
|
||||
>
|
||||
<td>
|
||||
<span t-esc="amount_by_group[0]" />
|
||||
<span>&nbsp;<span
|
||||
>on</span>&nbsp;<t
|
||||
<span>&nbsp;<span>
|
||||
on
|
||||
</span>&nbsp;<t
|
||||
t-esc="amount_by_group[2]"
|
||||
t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'
|
||||
/></span>
|
||||
|
||||
@@ -21,17 +21,17 @@
|
||||
<field name="name">PMS Folio Company Rule</field>
|
||||
<field name="model_id" ref="model_pms_folio" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
|
||||
<field name="domain_force">
|
||||
['|',('company_id','=',False),('company_id', 'in', company_ids)]
|
||||
</field>
|
||||
</record>
|
||||
<record id="pms_reservation_company_rule" model="ir.rule">
|
||||
<field name="name">PMS Reservation Company Rule</field>
|
||||
<field name="model_id" ref="model_pms_reservation" />
|
||||
<field name="global" eval="True" />
|
||||
<field
|
||||
name="domain_force"
|
||||
>['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
|
||||
<field name="domain_force">
|
||||
['|',('company_id','=',False),('company_id', 'in', company_ids)]
|
||||
</field>
|
||||
</record>
|
||||
<!-- Property Rules -->
|
||||
<!--<record id="pms_folio_property_rule" model="ir.rule">
|
||||
|
||||
@@ -8,12 +8,12 @@ odoo.define("web.SwitchPmsMenu", function(require) {
|
||||
*/
|
||||
|
||||
var config = require("web.config");
|
||||
var core = require("web.core");
|
||||
// Var core = require("web.core");
|
||||
var session = require("pms.session");
|
||||
var SystrayMenu = require("web.SystrayMenu");
|
||||
var Widget = require("web.Widget");
|
||||
|
||||
var _t = core._t;
|
||||
// Var _t = core._t;
|
||||
|
||||
var SwitchPmsMenu = Widget.extend({
|
||||
template: "SwitchPmsMenu",
|
||||
|
||||
@@ -6,14 +6,17 @@
|
||||
<div class="row">
|
||||
<div class="col-sm-4">
|
||||
<t t-esc="object.pms_property_id.street" />
|
||||
<t t-if="object.pms_property_id.street2">- <t
|
||||
t-esc="object.pms_property_id.street2"
|
||||
/></t> <br />
|
||||
<t t-if="object.pms_property_id.street2">
|
||||
-
|
||||
<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.city" />,
|
||||
<t t-esc="object.pms_property_id.state_id.name" /> <br />
|
||||
<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.country_id.name" />
|
||||
|
||||
</div>
|
||||
<div class="col-sm-4">
|
||||
<i class="glyphicon glyphicon-phone-alt" />
|
||||
@@ -38,9 +41,10 @@
|
||||
<th scope="col">Room Type</th>
|
||||
<th scope="col">Checkin</th>
|
||||
<th scope="col">Nights</th>
|
||||
<th scope="col">Price <t
|
||||
t-esc="object.currency_id.name"
|
||||
/></th>
|
||||
<th scope="col">
|
||||
Price
|
||||
<t t-esc="object.currency_id.name" />
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -71,19 +75,30 @@
|
||||
<template id="template_reservation">
|
||||
<div class="row" style="padding-top: 20px;">
|
||||
<div class="col-sm-12">
|
||||
<p>Dear <span t-field="object.partner_id.name" />,<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>
|
||||
Dear
|
||||
<span t-field="object.partner_id.name" />
|
||||
,
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<t t-call="pms.template_reservation_details" />
|
||||
<div class="row" style="padding-top: 20px;">
|
||||
<div class="col-sm-12">
|
||||
If you have any questions, please do not hesitate to contact with the property's staff. <br
|
||||
/>
|
||||
Looking forward to seeing you at our property, <br />
|
||||
If you have any questions, please do not hesitate to contact with
|
||||
the property's staff.
|
||||
<br />
|
||||
Looking forward to seeing you at our property,
|
||||
<br />
|
||||
Best regards.
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,8 +106,10 @@
|
||||
<template id="template_footer">
|
||||
<div class="row" style="padding-top: 20px;">
|
||||
<div class="col-sm-12">
|
||||
Privacy Policy: We use your Personal Information only for managing your reservation. By using the property, you
|
||||
agree to the collection and use of information in accordance with this policy.
|
||||
Privacy Policy: We use your Personal Information only for managing
|
||||
your reservation. By using the property, you
|
||||
agree to the collection and use of information in accordance with this
|
||||
policy.
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -128,9 +145,9 @@
|
||||
<field name="email_to">${(object.email or '')|safe}</field>
|
||||
<field name="partner_to">${(object.partner_id.id or '')}</field>
|
||||
<field name="lang">${object.partner_id.lang}</field>
|
||||
<field
|
||||
name="subject"
|
||||
>Your reservation ${object.name} has been confirmed by the property staff</field>
|
||||
<field name="subject">
|
||||
Your reservation ${object.name} has been confirmed by the property staff
|
||||
</field>
|
||||
<field name="auto_delete" eval="True" />
|
||||
<field name="body_type">qweb</field>
|
||||
<field name="body_view_id" ref="pms.template_reservation_confirmed" />
|
||||
|
||||
@@ -20,11 +20,8 @@
|
||||
#
|
||||
##############################################################################
|
||||
import logging
|
||||
from datetime import timedelta
|
||||
|
||||
from odoo import api, fields
|
||||
from odoo.tests import common
|
||||
from odoo.tools import DEFAULT_SERVER_DATE_FORMAT, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -5,25 +5,17 @@
|
||||
<field name="inherit_id" ref="base.sequence_view" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='company_id']" position="after">
|
||||
<field
|
||||
string="Property"
|
||||
name="pms_property_id"
|
||||
/>
|
||||
<field string="Property" name="pms_property_id" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="ir_sequence_view_tree" model="ir.ui.view">
|
||||
<field name="model">ir.sequence</field>
|
||||
<field name="inherit_id" ref="base.sequence_view_tree" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='company_id']" position="after">
|
||||
<field
|
||||
string="Property"
|
||||
name="pms_property_id"
|
||||
/>
|
||||
<field string="Property" name="pms_property_id" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -178,7 +178,10 @@
|
||||
role="alert"
|
||||
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>
|
||||
<group>
|
||||
<field
|
||||
@@ -366,6 +369,7 @@
|
||||
<field name="model">pms.folio</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph type="bar">
|
||||
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<notebook>
|
||||
<page string="General Information" name="property_general">
|
||||
<group>
|
||||
|
||||
</group>
|
||||
</page>
|
||||
<page string="Settings" name="property_settings">
|
||||
|
||||
@@ -41,10 +41,7 @@
|
||||
class="oe_highlight"
|
||||
type="object"
|
||||
/>
|
||||
<field
|
||||
name="state"
|
||||
widget="statusbar"
|
||||
/>
|
||||
<field name="state" widget="statusbar" />
|
||||
</header>
|
||||
<div
|
||||
class="alert alert-info"
|
||||
@@ -52,7 +49,8 @@
|
||||
style="margin-bottom:0px;"
|
||||
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>
|
||||
<button
|
||||
class="alert-link"
|
||||
@@ -68,7 +66,8 @@
|
||||
style="margin-bottom:0px;"
|
||||
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>
|
||||
<button
|
||||
class="alert-link"
|
||||
@@ -151,11 +150,15 @@
|
||||
<span
|
||||
class="label label-danger"
|
||||
attrs="{'invisible': [('state', 'not in', ('cancelled'))]}"
|
||||
>Cancelled Reservation!</span>
|
||||
>
|
||||
Cancelled Reservation!
|
||||
</span>
|
||||
<span
|
||||
class="label label-warning"
|
||||
attrs="{'invisible': [('overbooking', '=', False)]}"
|
||||
>OverBooking!</span>
|
||||
>
|
||||
OverBooking!
|
||||
</span>
|
||||
<h1>
|
||||
<field
|
||||
name="room_id"
|
||||
@@ -526,22 +529,25 @@
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Calendar -->
|
||||
<record id="pms_reservation_view_calendar" model="ir.ui.view">
|
||||
<field name="name">pms.reservation.view.calendar</field>
|
||||
<field name="model">pms.reservation</field>
|
||||
<field name="arch" type="xml">
|
||||
<calendar date_start="checkin" date_stop="checkout"
|
||||
string="Reservations" quick_add="False"
|
||||
mode="month" scales="month,year">
|
||||
<calendar
|
||||
date_start="checkin"
|
||||
date_stop="checkout"
|
||||
string="Reservations"
|
||||
quick_add="False"
|
||||
mode="month"
|
||||
scales="month,year"
|
||||
>
|
||||
<field name="partner_id" avatar_field="image_128" />
|
||||
<field name="room_type_id" />
|
||||
<field name="room_id" />
|
||||
</calendar>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Form view Checkin Partners from reservation -->
|
||||
<record model="ir.ui.view" id="pms_reservation_checkin_view_form">
|
||||
<field name="name">pms.reservation.checkin.form</field>
|
||||
@@ -562,7 +568,8 @@
|
||||
style="margin-bottom:0px;"
|
||||
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>
|
||||
<button
|
||||
class="alert-link"
|
||||
@@ -578,11 +585,15 @@
|
||||
<span
|
||||
class="label label-danger"
|
||||
attrs="{'invisible': [('state', 'not in', ('cancelled'))]}"
|
||||
>Cancelled Reservation!</span>
|
||||
>
|
||||
Cancelled Reservation!
|
||||
</span>
|
||||
<span
|
||||
class="label label-warning"
|
||||
attrs="{'invisible': [('overbooking', '=', False)]}"
|
||||
>OverBooking!</span>
|
||||
>
|
||||
OverBooking!
|
||||
</span>
|
||||
<h2>
|
||||
<field
|
||||
name="room_id"
|
||||
@@ -607,7 +618,8 @@
|
||||
attrs="{'invisible': [('reservation_type','not in',('staff'))]}"
|
||||
/> -->
|
||||
<h3>
|
||||
From <span class="fa-sign-in" style="margin: 5px;" />
|
||||
From
|
||||
<span class="fa-sign-in" style="margin: 5px;" />
|
||||
<field
|
||||
name="checkin"
|
||||
style="margin-right: 10px;"
|
||||
@@ -642,15 +654,16 @@
|
||||
<field name="name">pms.reservation.tree</field>
|
||||
<field name="model">pms.reservation</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree
|
||||
string="Reservation"
|
||||
multi_edit="1" sample="1"
|
||||
class="o_sale_order"
|
||||
>
|
||||
<tree string="Reservation" multi_edit="1" sample="1" class="o_sale_order">
|
||||
<field name="splitted" invisible="1" />
|
||||
<field name="pricelist_id" invisible="1" />
|
||||
<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="nights" />
|
||||
<button
|
||||
@@ -666,7 +679,11 @@
|
||||
<field name="adults" string="Persons" />
|
||||
<field name="overbooking" invisible="1" />
|
||||
<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="checkin_partner_ids" invisible="1" />
|
||||
<field name="to_assign" invisible="1" />
|
||||
@@ -675,8 +692,19 @@
|
||||
<field name="price_subtotal" invisible="1" />
|
||||
<field name="price_total" />
|
||||
<field name="folio_pending_amount" string="Folio Pending Amount" />
|
||||
<field 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"/>
|
||||
<field
|
||||
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>
|
||||
</field>
|
||||
</record>
|
||||
@@ -866,7 +894,12 @@
|
||||
<searchpanel>
|
||||
<field name="room_type_id" string="Room Type" 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>
|
||||
</search>
|
||||
</field>
|
||||
|
||||
@@ -119,13 +119,15 @@
|
||||
<field name="name" />
|
||||
</strong>
|
||||
</li>
|
||||
<li class="mb4">Room Type: <field
|
||||
name="room_type_id"
|
||||
/></li>
|
||||
<li class="mb4">
|
||||
Room Type:
|
||||
<field name="room_type_id" />
|
||||
</li>
|
||||
<li class="badge mb4">
|
||||
<strong>Capacity <field
|
||||
name="capacity"
|
||||
/></strong>
|
||||
<strong>
|
||||
Capacity
|
||||
<field name="capacity" />
|
||||
</strong>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -74,11 +74,15 @@
|
||||
<field name="name" />
|
||||
</strong>
|
||||
</li>
|
||||
<li class="mb4">Room Type: <field
|
||||
name="room_type_id"
|
||||
/></li>
|
||||
<li class="mb4">
|
||||
Room Type:
|
||||
<field name="room_type_id" />
|
||||
</li>
|
||||
<li class="badge mb4">
|
||||
<strong>Beds <field name="beds" /></strong>
|
||||
<strong>
|
||||
Beds
|
||||
<field name="beds" />
|
||||
</strong>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user