[RFC] Code review (#91)

* [REF] Refactor wizard models

* [REF] Refactor in pms models
This commit is contained in:
Sara
2021-05-22 08:45:24 +02:00
committed by GitHub
parent 75f8a2e81a
commit f85a11e0ae
22 changed files with 1935 additions and 1618 deletions

View File

@@ -4,7 +4,14 @@ from odoo import fields, models
class AccountBankStatement(models.Model):
_inherit = "account.bank.statement"
property_id = fields.Many2one("pms.property", string="Property", copy=False)
property_id = fields.Many2one(
string="Property",
help="Properties with access to the element",
copy=False,
comodel_name="pms.property",
)
company_id = fields.Many2one(
string="Company",
help="The company for Account Bank Statement",
check_pms_properties=True,
)

View File

@@ -5,12 +5,31 @@ class AccountBankStatementLine(models.Model):
_inherit = "account.bank.statement.line"
statement_folio_ids = fields.Many2many(
"pms.folio", string="Folios", ondelete="cascade"
string="Folios",
comodel_name="pms.folio",
ondelete="cascade",
relation="account_bank_statement_statement_folio_ids_rel",
column1="account_journal_id",
column2="statement_folio_ids_id",
)
reservation_ids = fields.Many2many(
"pms.reservation", string="Reservations", ondelete="cascade"
string="Reservations",
help="Reservations in which the Account Bank Statement Lines are included",
comodel_name="pms.reservation",
ondelete="cascade",
relation="account_bank_statement_reservation_ids_rel",
column1="account_bank_statement_id",
column2="reservation_ids_id",
)
service_ids = fields.Many2many(
string="Services",
help="Services in which the Account Bank Statement Lines are included",
comodel_name="pms.service",
ondelete="cascade",
relation="account_bank_statement_service_ids_rel",
column1="account_bank_statement_id",
column2="service_ids_id",
)
service_ids = fields.Many2many("pms.service", string="Services", ondelete="cascade")
@api.model
def _prepare_move_line_default_vals(self, counterpart_account_id=None):

View File

@@ -16,5 +16,7 @@ class AccountJournal(models.Model):
check_pms_properties=True,
)
company_id = fields.Many2one(
string="Company",
help="The company for Account Jouarnal",
check_pms_properties=True,
)

View File

@@ -11,9 +11,19 @@ class AccountMove(models.Model):
# Field Declarations
folio_ids = fields.Many2many(
comodel_name="pms.folio", compute="_compute_folio_origin"
string="Folios",
help="Folios where the account move are included",
comodel_name="pms.folio",
compute="_compute_folio_origin",
relation="account_move_folio_ids_rel",
column1="account_move_id",
column2="folio_ids_id",
)
pms_property_id = fields.Many2one(
string="Property",
help="Property with access to the element",
comodel_name="pms.property",
)
pms_property_id = fields.Many2one("pms.property")
outstanding_folios_debits_widget = fields.Text(
compute="_compute_get_outstanding_folios_JSON"
)
@@ -21,8 +31,6 @@ class AccountMove(models.Model):
compute="_compute_get_outstanding_folios_JSON"
)
# Compute and Search methods
def _compute_folio_origin(self):
for inv in self:
inv.folio_ids = False
@@ -30,27 +38,6 @@ class AccountMove(models.Model):
if folios:
inv.folio_ids = [(6, 0, folios.ids)]
# Action methods
def action_folio_payments(self):
self.ensure_one()
sales = self.mapped("invoice_line_ids.sale_line_ids.order_id")
folios = self.env["pms.folio"].search([("order_id.id", "in", sales.ids)])
payments_obj = self.env["account.payment"]
payments = payments_obj.search([("folio_id", "in", folios.ids)])
payment_ids = payments.mapped("id")
return {
"name": _("Payments"),
"view_type": "form",
"view_mode": "tree,form",
"res_model": "account.payment",
"target": "new",
"type": "ir.actions.act_window",
"domain": [("id", "in", payment_ids)],
}
# Business methods
def _compute_get_outstanding_folios_JSON(self):
self.ensure_one()
self.outstanding_folios_debits_widget = json.dumps(False)
@@ -120,3 +107,20 @@ class AccountMove(models.Model):
info["title"] = type_payment
self.outstanding_folios_debits_widget = json.dumps(info)
self.has_folio_outstanding = True
def action_folio_payments(self):
self.ensure_one()
sales = self.mapped("invoice_line_ids.sale_line_ids.order_id")
folios = self.env["pms.folio"].search([("order_id.id", "in", sales.ids)])
payments_obj = self.env["account.payment"]
payments = payments_obj.search([("folio_id", "in", folios.ids)])
payment_ids = payments.mapped("id")
return {
"name": _("Payments"),
"view_type": "form",
"view_mode": "tree,form",
"res_model": "account.payment",
"target": "new",
"type": "ir.actions.act_window",
"domain": [("id", "in", payment_ids)],
}

View File

@@ -10,25 +10,26 @@ class AccountMoveLine(models.Model):
# Fields declaration
# TODO: REVIEW why not a Many2one?
folio_line_ids = fields.Many2many(
"folio.sale.line",
"folio_sale_line_invoice_rel",
"invoice_line_id",
"sale_line_id",
string="Folio Lines",
help="The folio lines in the account move lines",
copy=False,
comodel_name="folio.sale.line",
relation="folio_sale_line_invoice_rel",
column1="invoice_line_id",
column2="sale_line_id",
)
folio_ids = fields.Many2many(
"pms.folio",
"payment_folio_rel",
"move_id",
"folio_id",
string="Folios",
comodel_name="pms.folio",
relation="payment_folio_rel",
column1="move_id",
column2="folio_id",
)
name_changed_by_user = fields.Boolean(
default=False,
readonly=False,
store=True,
string="Custom label",
readonly=False,
default=False,
store=True,
compute="_compute_name_changed_by_user",
)

View File

@@ -7,7 +7,11 @@ class AccountPayment(models.Model):
_inherit = "account.payment"
# Fields declaration
folio_id = fields.Many2one("pms.folio", string="Folio Reference")
folio_id = fields.Many2one(
string="Folio Reference",
help="Folio in account payment",
comodel_name="pms.folio",
)
# Business methods

File diff suppressed because it is too large Load Diff

View File

@@ -7,16 +7,23 @@ class PaymentReturn(models.Model):
_inherit = "payment.return"
# Fields declaration
folio_id = fields.Many2one("pms.folio", string="Folio")
folio_id = fields.Many2one(
string="Folio", help="Folio in payment return", comodel_name="pms.folio"
)
pms_property_id = fields.Many2one(
"pms.property", store=True, readonly=True, related="folio_id.pms_property_id"
string="Property",
help="Property with access to the element",
store=True,
readonly=True,
comodel_name="pms.property",
related="folio_id.pms_property_id",
)
company_id = fields.Many2one(
string="Company",
help="The company for Payment Return",
check_pms_properties=True,
)
# Business methods
def action_confirm(self):
pay = super(PaymentReturn, self).action_confirm()
if pay:

View File

@@ -4,18 +4,21 @@
from odoo import fields, models
# TODO: refactoring to cancellation.rule
class PmsCancelationRule(models.Model):
_name = "pms.cancelation.rule"
_description = "Cancelation Rules"
_check_pms_properties_auto = True
# Fields declaration
name = fields.Char(string="Cancelation Rule", translate=True, required=True)
name = fields.Char(
string="Cancelation Rule",
required=True,
translate=True,
)
pricelist_ids = fields.One2many(
"product.pricelist",
"cancelation_rule_id",
"Pricelist that use this rule",
string="Pricelist",
help="Pricelist that use this rule",
comodel_name="product.pricelist",
inverse_name="cancelation_rule_id",
check_pms_properties=True,
)
pms_property_ids = fields.Many2many(
@@ -23,28 +26,63 @@ class PmsCancelationRule(models.Model):
help="Properties with access to the element;"
" if not set, all properties can access",
required=False,
ondelete="restrict",
comodel_name="pms.property",
relation="pms_cancelation_rule_pms_property_rel",
column1="pms_cancelation_rule_id",
column2="pms_property_id",
ondelete="restrict",
check_pms_properties=True,
)
active = fields.Boolean("Active", default=True)
active = fields.Boolean(
string="Active", help="Determines if cancelation rule is active", default=True
)
days_intime = fields.Integer(
"Days Late", help="Maximum number of days for free cancellation before Checkin"
string="Days Late",
help="Maximum number of days for free cancellation before Checkin",
)
penalty_late = fields.Integer(
string="% Penalty Late",
help="Percentage of the total price that partner has "
"to pay in case of late arrival",
default="100",
)
penalty_late = fields.Integer("% Penalty Late", default="100")
apply_on_late = fields.Selection(
[("first", "First Day"), ("all", "All Days"), ("days", "Specify days")],
"Late apply on",
string="Late apply on",
help="Days on which the cancelation rule applies when "
"the reason is late arrival. "
"Can be first, all days or specify the days.",
default="first",
selection=[
("first", "First Day"),
("all", "All Days"),
("days", "Specify days"),
],
)
days_late = fields.Integer(
string="Late first days",
help="Is number of days late in the cancelation rule "
"if the value of the apply_on_late field is specify days.",
default="2",
)
penalty_noshow = fields.Integer(
string="% Penalty No Show",
help="Percentage of the total price that partner has to pay in case of no show",
default="100",
)
days_late = fields.Integer("Late first days", default="2")
penalty_noshow = fields.Integer("% Penalty No Show", default="100")
apply_on_noshow = fields.Selection(
[("first", "First Day"), ("all", "All Days"), ("days", "Specify days")],
"No Show apply on",
string="No Show apply on",
help="Days on which the cancelation rule applies when"
" the reason is no show. Can be first, all days or specify the days.",
selection=[
("first", "First Day"),
("all", "All Days"),
("days", "Specify days"),
],
default="all",
)
days_noshow = fields.Integer("NoShow first days", default="2")
days_noshow = fields.Integer(
string="NoShow first days",
help="Is number of days no show in the cancelation rule "
"if the value of the apply_on_show field is specify days.",
default="2",
)

View File

@@ -15,63 +15,96 @@ class PmsCheckinPartner(models.Model):
_rec_name = "identifier"
_check_pms_properties_auto = True
# Fields declaration
identifier = fields.Char(
"Identifier", readonly=True, index=True, default=lambda self: _("New")
string="Identifier",
help="Checkin Partner Id",
readonly=True,
index=True,
default=lambda self: _("New"),
)
partner_id = fields.Many2one(
"res.partner",
string="Partner",
help="Partner associated with checkin partner",
comodel_name="res.partner",
domain="[('is_company', '=', False)]",
)
reservation_id = fields.Many2one(
"pms.reservation",
string="Reservation",
help="Reservation to which checkin partners belong",
comodel_name="pms.reservation",
check_pms_properties=True,
)
folio_id = fields.Many2one(
"pms.folio",
compute="_compute_folio_id",
string="Folio",
help="Folio to which reservation of checkin partner belongs",
store=True,
comodel_name="pms.folio",
compute="_compute_folio_id",
check_pms_properties=True,
)
pms_property_id = fields.Many2one(
"pms.property", store=True, readonly=True, related="folio_id.pms_property_id"
string="Property",
help="Property to which the folio associated belongs",
readonly=True,
store=True,
comodel_name="pms.property",
related="folio_id.pms_property_id",
)
name = fields.Char(
"Name",
compute="_compute_name",
store=True,
string="Name",
help="Checkin partner name",
readonly=False,
store=True,
compute="_compute_name",
)
email = fields.Char(
"E-mail",
compute="_compute_email",
store=True,
string="E-mail",
help="Checkin Partner Email",
readonly=False,
store=True,
compute="_compute_email",
)
mobile = fields.Char(
"Mobile",
string="Mobile",
help="Checkin Partner Mobile",
compute="_compute_mobile",
store=True,
readonly=False,
)
image_128 = fields.Image(
string="Image",
help="Checkin Partner Image, it corresponds with Partner Image associated",
related="partner_id.image_128",
)
segmentation_ids = fields.Many2many(
string="Segmentation",
help="Segmentation tags to classify checkin partners",
related="reservation_id.segmentation_ids",
readonly=True,
)
checkin = fields.Date(
related="reservation_id.checkin", store=True, depends=["reservation_id.checkin"]
string="Checkin",
help="Checkin date",
store=True,
related="reservation_id.checkin",
depends=["reservation_id.checkin"],
)
checkout = fields.Date(
related="reservation_id.checkout",
string="Checkout",
help="Checkout date",
store=True,
related="reservation_id.checkout",
depends=["reservation_id.checkout"],
)
arrival = fields.Datetime("Enter")
departure = fields.Datetime("Exit")
arrival = fields.Datetime("Enter", help="Checkin partner arrival date and time")
departure = fields.Datetime(
string="Exit", help="Checkin partner departure date and time"
)
state = fields.Selection(
string="State",
help="Status of the checkin partner regarding the reservation",
readonly=True,
store=True,
selection=[
("draft", "Unkown Guest"),
("precheckin", "Pending arrival"),
@@ -79,10 +112,7 @@ class PmsCheckinPartner(models.Model):
("done", "Out"),
("cancelled", "Cancelled"),
],
string="State",
compute="_compute_state",
store=True,
readonly=True,
)
# Compute
@@ -147,22 +177,6 @@ class PmsCheckinPartner(models.Model):
if not record.mobile:
record.mobile = record.partner_id.mobile
@api.model
def _checkin_mandatory_fields(self, depends=False):
# api.depends need "reservation_id.state" in the lambda function
if depends:
return ["reservation_id.state", "name"]
return ["name"]
@api.model
def _checkin_partner_fields(self):
# api.depends need "reservation_id.state" in the lambda function
checkin_fields = self._checkin_mandatory_fields()
checkin_fields.extend(["mobile", "email"])
return checkin_fields
# Constraints and onchanges
@api.constrains("departure", "arrival")
def _check_departure(self):
for record in self:
@@ -209,7 +223,6 @@ class PmsCheckinPartner(models.Model):
):
raise ValidationError(_("'%s' is not a valid phone", record.mobile))
# CRUD
@api.model
def create(self, vals):
# The checkin records are created automatically from adult depends
@@ -284,6 +297,41 @@ class PmsCheckinPartner(models.Model):
reservations._compute_checkin_partner_ids()
return res
@api.model
def _checkin_mandatory_fields(self, depends=False):
# api.depends need "reservation_id.state" in the lambda function
if depends:
return ["reservation_id.state", "name"]
return ["name"]
@api.model
def _checkin_partner_fields(self):
# api.depends need "reservation_id.state" in the lambda function
checkin_fields = self._checkin_mandatory_fields()
checkin_fields.extend(["mobile", "email"])
return checkin_fields
@api.model
def import_room_list_json(self, roomlist_json):
roomlist_json = json.loads(roomlist_json)
for checkin_dict in roomlist_json:
identifier = checkin_dict["identifier"]
reservation_id = checkin_dict["reservation_id"]
checkin = self.env["pms.checkin.partner"].search(
[("identifier", "=", identifier)]
)
reservation = self.env["pms.reservation"].browse(reservation_id)
if not checkin:
raise ValidationError(
_("%s not found in checkins (%s)"), identifier, reservation.name
)
checkin_vals = {}
for key, value in checkin_dict.items():
if key in ("reservation_id", "folio_id", "identifier"):
continue
checkin_vals[key] = value
checkin.write(checkin_vals)
def action_on_board(self):
for record in self:
if record.reservation_id.checkin > fields.Date.today():
@@ -310,24 +358,3 @@ class PmsCheckinPartner(models.Model):
}
record.update(vals)
return True
@api.model
def import_room_list_json(self, roomlist_json):
roomlist_json = json.loads(roomlist_json)
for checkin_dict in roomlist_json:
identifier = checkin_dict["identifier"]
reservation_id = checkin_dict["reservation_id"]
checkin = self.env["pms.checkin.partner"].search(
[("identifier", "=", identifier)]
)
reservation = self.env["pms.reservation"].browse(reservation_id)
if not checkin:
raise ValidationError(
_("%s not found in checkins (%s)"), identifier, reservation.name
)
checkin_vals = {}
for key, value in checkin_dict.items():
if key in ("reservation_id", "folio_id", "identifier"):
continue
checkin_vals[key] = value
checkin.write(checkin_vals)

File diff suppressed because it is too large Load Diff

View File

@@ -30,58 +30,40 @@ class ProductPricelist(models.Model):
check_pms_properties=True,
)
company_id = fields.Many2one(
string="Company",
help="Company to which the pricelist belongs",
check_pms_properties=True,
)
cancelation_rule_id = fields.Many2one(
"pms.cancelation.rule",
string="Cancelation Policy",
help="Cancelation Policy included in the room",
comodel_name="pms.cancelation.rule",
check_pms_properties=True,
)
pricelist_type = fields.Selection(
[("daily", "Daily Plan")], string="Pricelist Type", default="daily"
string="Pricelist Type",
help="Pricelist types, it can be Daily Plan",
default="daily",
selection=[("daily", "Daily Plan")],
)
pms_sale_channel_ids = fields.Many2many(
"pms.sale.channel",
string="Available Channels",
help="Sale channel for which the pricelist is included",
comodel_name="pms.sale.channel",
check_pms_properties=True,
)
availability_plan_id = fields.Many2one(
comodel_name="pms.availability.plan",
string="Availability Plan",
help="Availability Plan for which the pricelist is included",
comodel_name="pms.availability.plan",
ondelete="restrict",
check_pms_properties=True,
)
item_ids = fields.One2many(check_pms_properties=True)
# Constraints and onchanges
# @api.constrains("pricelist_type", "pms_property_ids")
# def _check_pricelist_type_property_ids(self):
# for record in self:
# if record.pricelist_type == "daily" and len(record.pms_property_ids) != 1:
# raise ValidationError(
# _(
# "A daily pricelist is used as a daily Rate Plan "
# "for room types and therefore must be related with "
# "one and only one property."
# )
# )
# if record.pricelist_type == "daily" and len(record.pms_property_ids) == 1:
# pms_property_id = (
# self.env["pms.property"].search(
# [("default_pricelist_id", "=", record.id)]
# )
# or None
# )
# if pms_property_id and pms_property_id != record.pms_property_ids:
# raise ValidationError(
# _("Relationship mismatch.")
# + " "
# + _(
# "This pricelist is used as default in a "
# "different property."
# )
# )
item_ids = fields.One2many(
string="Items",
help="Items for which the pricelist is made up",
check_pms_properties=True,
)
def _compute_price_rule_get_items(
self, products_qty_partner, date, uom_id, prod_tmpl_ids, prod_ids, categ_ids
@@ -91,11 +73,6 @@ class ProductPricelist(models.Model):
and self._context["property"]
and self._context.get("consumption_date")
):
# board_service_id = self._context.get("board_service")
# on_board_service_bool = True if board_service_id else False
# self.env["product.pricelist.item"].flush(
# ["price", "currency_id", "company_id"]
# )
self.env.cr.execute(
"""
SELECT item.id
@@ -159,7 +136,36 @@ class ProductPricelist(models.Model):
)
return items
# Action methods
# Constraints and onchanges
# @api.constrains("pricelist_type", "pms_property_ids")
# def _check_pricelist_type_property_ids(self):
# for record in self:
# if record.pricelist_type == "daily" and len(record.pms_property_ids) != 1:
# raise ValidationError(
# _(
# "A daily pricelist is used as a daily Rate Plan "
# "for room types and therefore must be related with "
# "one and only one property."
# )
# )
# if record.pricelist_type == "daily" and len(record.pms_property_ids) == 1:
# pms_property_id = (
# self.env["pms.property"].search(
# [("default_pricelist_id", "=", record.id)]
# )
# or None
# )
# if pms_property_id and pms_property_id != record.pms_property_ids:
# raise ValidationError(
# _("Relationship mismatch.")
# + " "
# + _(
# "This pricelist is used as default in a "
# "different property."
# )
# )
def open_massive_changes_wizard(self):
if self.ensure_one():

View File

@@ -26,17 +26,32 @@ class ProductPricelistItem(models.Model):
string="End Date Overnight",
help="End date to apply daily pricelist items",
)
on_board_service = fields.Boolean("Those included in Board Services")
on_board_service = fields.Boolean(
string="On Board Service",
help="Those included in Board Services",
)
board_service_room_type_ids = fields.Many2many(
"pms.board.service.room.type",
"board_service_pricelist_item_rel",
"pricelist_item_id",
"board_service_id",
string="Board Services on Room Types",
ondelete="cascade", # check_company=True,
string="Board Services",
help="""Specify a Board services on Room Types.""",
comodel_name="pms.board.service.room.type",
relation="board_service_pricelist_item_rel",
column1="pricelist_item_id",
column2="board_service_id",
ondelete="cascade",
check_pms_properties=True,
)
pricelist_id = fields.Many2one(
string="Pricelist",
help="Pricelist in which this item is included",
check_pms_properties=True,
)
product_id = fields.Many2one(
string="Product",
help="Product associated with the item",
check_pms_properties=True,
)
product_tmpl_id = fields.Many2one(
string="Product Template",
help="Product template associated with the item",
check_pms_properties=True,
)
pricelist_id = fields.Many2one(check_pms_properties=True)
product_id = fields.Many2one(check_pms_properties=True)
product_tmpl_id = fields.Many2one(check_pms_properties=True)

View File

@@ -5,10 +5,10 @@ class ProductProduct(models.Model):
_inherit = "product.product"
board_price = fields.Float(
"Board Service Price",
string="Board Service Price",
help="Get price on board service",
digits="Product Price",
compute="_compute_board_price",
help="Get price price on board service",
)
@api.depends_context("consumption_date")

View File

@@ -10,6 +10,78 @@ class FolioAdvancePaymentInv(models.TransientModel):
_name = "folio.advance.payment.inv"
_description = "Folio Advance Payment Invoice"
partner_invoice_id = fields.Many2one(
string="Billing contact",
help="Invoice address for current partner",
default=lambda self: self._default_partner_invoice_id,
comodel_name="res.partner",
)
advance_payment_method = fields.Selection(
string="Create Invoice",
help="A standard invoice is issued with all the order \
lines ready for invoicing, \
according to their invoicing policy \
(based on ordered or delivered quantity).",
required=True,
default="delivered",
selection=[
("delivered", "Regular invoice"),
("percentage", "Down payment (percentage)"),
("fixed", "Down payment (fixed amount)"),
],
)
bill_services = fields.Boolean(
string="Bill Services", help="Bill Services", default=True
)
bill_rooms = fields.Boolean(string="Bill Rooms", help="Bill Rooms", default=True)
deduct_down_payments = fields.Boolean(
string="Deduct down payments", help="Deduct down payments", default=True
)
has_down_payments = fields.Boolean(
string="Has down payments",
help="Has down payments",
readonly=True,
default=lambda self: self._default_has_down_payment,
)
product_id = fields.Many2one(
string="Down Payment Product",
default=lambda self: self._default_product_id,
comodel_name="product.product",
domain=[("type", "=", "service")],
)
count = fields.Integer(
string="Order Count",
default=lambda self: self._count,
)
amount = fields.Float(
string="Down Payment Amount",
help="The percentage of amount to be invoiced in advance, taxes excluded.",
digits="Account",
)
currency_id = fields.Many2one(
string="Currency",
help="Currency used in invoices",
comodel_name="res.currency",
default=lambda self: self._default_currency_id,
)
fixed_amount = fields.Monetary(
string="Down Payment Amount (Fixed)",
help="The fixed amount to be invoiced in advance, taxes excluded.",
)
deposit_account_id = fields.Many2one(
string="Income Account",
help="Account used for deposits",
default=lambda self: self._default_deposit_account_id,
comodel_name="account.account",
domain=[("deprecated", "=", False)],
)
deposit_taxes_id = fields.Many2many(
string="Customer Taxes",
help="Taxes used for deposits",
default=lambda self: self._default_deposit_taxes_id,
comodel_name="account.tax",
)
@api.model
def _count(self):
return len(self._context.get("active_ids", []))
@@ -57,64 +129,17 @@ class FolioAdvancePaymentInv(models.TransientModel):
folio = self.env["pms.folio"].browse(self._context.get("active_id", []))
return folio.partner_invoice_ids[0]
partner_invoice_id = fields.Many2one(
comodel_name="res.partner",
string="Billing contact",
default=_default_partner_invoice_id,
)
def _get_advance_details(self, order):
context = {"lang": order.partner_id.lang}
if self.advance_payment_method == "percentage":
amount = order.amount_untaxed * self.amount / 100
name = _("Down payment of %s%%") % (self.amount)
else:
amount = self.fixed_amount
name = _("Down Payment")
del context
advance_payment_method = fields.Selection(
[
("delivered", "Regular invoice"),
("percentage", "Down payment (percentage)"),
("fixed", "Down payment (fixed amount)"),
],
string="Create Invoice",
default="delivered",
required=True,
help="A standard invoice is issued with all the order \
lines ready for invoicing, \
according to their invoicing policy \
(based on ordered or delivered quantity).",
)
bill_services = fields.Boolean("Bill Services", default=True)
bill_rooms = fields.Boolean("Bill Rooms", default=True)
deduct_down_payments = fields.Boolean("Deduct down payments", default=True)
has_down_payments = fields.Boolean(
"Has down payments", default=_default_has_down_payment, readonly=True
)
product_id = fields.Many2one(
"product.product",
string="Down Payment Product",
domain=[("type", "=", "service")],
default=_default_product_id,
)
count = fields.Integer(default=_count, string="Order Count")
amount = fields.Float(
"Down Payment Amount",
digits="Account",
help="The percentage of amount to be invoiced in advance, taxes excluded.",
)
currency_id = fields.Many2one(
"res.currency", string="Currency", default=_default_currency_id
)
fixed_amount = fields.Monetary(
"Down Payment Amount (Fixed)",
help="The fixed amount to be invoiced in advance, taxes excluded.",
)
deposit_account_id = fields.Many2one(
"account.account",
string="Income Account",
domain=[("deprecated", "=", False)],
help="Account used for deposits",
default=_default_deposit_account_id,
)
deposit_taxes_id = fields.Many2many(
"account.tax",
string="Customer Taxes",
help="Taxes used for deposits",
default=_default_deposit_taxes_id,
)
return amount, name
@api.onchange("advance_payment_method")
def onchange_advance_payment_method(self):
@@ -161,18 +186,6 @@ class FolioAdvancePaymentInv(models.TransientModel):
return invoice_vals
def _get_advance_details(self, order):
context = {"lang": order.partner_id.lang}
if self.advance_payment_method == "percentage":
amount = order.amount_untaxed * self.amount / 100
name = _("Down payment of %s%%") % (self.amount)
else:
amount = self.fixed_amount
name = _("Down Payment")
del context
return amount, name
def _create_invoice(self, order, line, amount):
if (self.advance_payment_method == "percentage" and self.amount <= 0.00) or (
self.advance_payment_method == "fixed" and self.fixed_amount <= 0.00

View File

@@ -18,17 +18,17 @@ class AdvancedFiltersWizard(models.TransientModel):
_description = "Wizard for advanced filters"
pms_model_id = fields.Many2one(
"ir.model",
string="Recipients Model",
ondelete="cascade",
required=True,
domain=[("model", "in", PMS_BUSINESS_MODELS)],
default=lambda self: self.env.ref("pms.model_pms_reservation").id,
comodel_name="ir.model",
domain=[("model", "in", PMS_BUSINESS_MODELS)],
ondelete="cascade",
)
pms_model_name = fields.Char(
string="Recipients Model Name",
related="pms_model_id.model",
readonly=True,
related="pms_model_id.model",
related_sudo=True,
)
pms_domain = fields.Char(string="Domain")

View File

@@ -11,70 +11,89 @@ class FolioWizard(models.TransientModel):
)
_check_pms_properties_auto = True
# Fields declaration
start_date = fields.Date(
string="From:",
help="Start date for creation of reservations and folios",
required=True,
)
end_date = fields.Date(
string="To:",
help="End date for creation of reservations and folios",
required=True,
)
pricelist_id = fields.Many2one(
comodel_name="product.pricelist",
string="Pricelist",
compute="_compute_pricelist_id",
store=True,
help="Pricelist applied in folio",
readonly=False,
store=True,
comodel_name="product.pricelist",
compute="_compute_pricelist_id",
check_pms_properties=True,
)
pms_property_id = fields.Many2one(
comodel_name="pms.property",
string="Property",
help="Property to which the folio belongs",
default=lambda self: self._default_pms_property_id(),
comodel_name="pms.property",
)
segmentation_ids = fields.Many2many(
"res.partner.category", string="Segmentation", ondelete="restrict"
string="Segmentation",
help="Partner Tags",
ondelete="restrict",
comodel_name="res.partner.category",
)
partner_id = fields.Many2one(
"res.partner",
string="Partner",
help="Partner who made the reservation",
comodel_name="res.partner",
check_pms_properties=True,
)
folio_id = fields.Many2one(
"pms.folio",
string="Folio",
help="Folio in which are included new reservations",
comodel_name="pms.folio",
check_pms_properties=True,
)
availability_results = fields.One2many(
strign="Availability Results",
help="Availability Results",
readonly=False,
store=True,
comodel_name="pms.folio.availability.wizard",
inverse_name="folio_wizard_id",
compute="_compute_availability_results",
store=True,
readonly=False,
check_pms_properties=True,
)
agency_id = fields.Many2one(
string="Agency",
help="Agency that made the reservation",
comodel_name="res.partner",
ondelete="restrict",
domain=[("is_agency", "=", True)],
ondelete="restrict",
)
channel_type_id = fields.Many2one(
string="Direct Sale Channel",
help="Sales Channel through which the reservation was managed",
readonly=False,
store=True,
comodel_name="pms.sale.channel",
domain=[("channel_type", "=", "direct")],
compute="_compute_channel_type_id",
ondelete="restrict",
compute="_compute_channel_type_id",
)
total_price_folio = fields.Float(
string="Total Price", compute="_compute_total_price_folio"
string="Total Price",
help="Total price of folio with taxes",
compute="_compute_total_price_folio",
)
discount = fields.Float(
string="Discount",
help="Discount that be applied in total price",
default=0,
)
can_create_folio = fields.Boolean(compute="_compute_can_create_folio")
can_create_folio = fields.Boolean(
string="Can create folio", compute="_compute_can_create_folio"
)
def _default_pms_property_id(self):
if self._context.get("default_folio_id"):
@@ -164,7 +183,6 @@ class FolioWizard(models.TransientModel):
key=lambda s: s.num_rooms_available, reverse=True
)
# actions
def create_folio(self):
for record in self:
if not record.folio_id:

View File

@@ -18,51 +18,63 @@ class AvailabilityWizard(models.TransientModel):
_name = "pms.folio.availability.wizard"
_check_pms_properties_auto = True
# Fields declarations
folio_wizard_id = fields.Many2one(
string="Folio Wizard ID",
comodel_name="pms.folio.wizard",
)
checkin = fields.Date(
string="From:",
help="Date Reservation starts ",
required=True,
)
checkout = fields.Date(
string="To:",
help="Date Reservation ends",
required=True,
)
room_type_id = fields.Many2one(
string="Room Type",
help="Room Type reserved",
comodel_name="pms.room.type",
check_pms_properties=True,
)
num_rooms_available = fields.Integer(
string="Available rooms",
compute="_compute_num_rooms_available",
help="Number of rooms that are available",
store="true",
compute="_compute_num_rooms_available",
)
num_rooms_selected = fields.Many2one(
string="Selected rooms",
readonly=False,
store=True,
comodel_name="pms.num.rooms.selection",
inverse_name="folio_wizard_id",
string="Selected rooms",
compute="_compute_num_rooms_selected",
store=True,
readonly=False,
domain="[('value', '<=', num_rooms_available), "
"('room_type_id', '=', room_type_id)]",
compute="_compute_num_rooms_selected",
)
value_num_rooms_selected = fields.Integer(
compute="_compute_value_num_rooms_selected",
store=True,
string="Number of Rooms Selected",
readonly=False,
store=True,
compute="_compute_value_num_rooms_selected",
)
price_per_room = fields.Float(
string="Price per room",
help="Price per room in folio",
compute="_compute_price_per_room",
)
price_total = fields.Float(string="Total price", compute="_compute_price_total")
price_total = fields.Float(
string="Total price",
help="The total price in the folio",
compute="_compute_price_total",
)
pms_property_id = fields.Many2one(
related="folio_wizard_id.pms_property_id",
string="Property",
help="Propertiy with access to the element;",
related="folio_wizard_id.pms_property_id",
)
board_service_room_id = fields.Many2one(
string="Board Service",

View File

@@ -6,30 +6,26 @@ class WizardFolioChanges(models.TransientModel):
_name = "wizard.folio.changes"
_description = "Folio Changes"
def _default_folio_id(self):
folio_id = self._context.get("active_id")
folio = self.env["pms.folio"].browse(folio_id)
return folio
def _default_reservation_ids(self):
folio_id = self._context.get("active_id")
folio = self.env["pms.folio"].browse(folio_id)
return folio.reservation_ids
folio_id = fields.Many2one(
"pms.folio",
string="Folio",
default=_default_folio_id,
default=lambda self: self._default_folio_id(),
comodel_name="pms.folio",
)
reservation_ids = fields.Many2many(
"pms.reservation",
string="Reservations",
default=_default_reservation_ids,
default=lambda self: self._default_reservation_ids(),
comodel_name="pms.reservation",
relation="folio_changes_reservation_rel",
column1="folio_changes_id",
column2="reservation_ids",
domain="[('id', 'in', allowed_reservation_ids)]",
)
allowed_reservation_ids = fields.Many2many(
"pms.reservation",
string="Allowed Reservations",
comodel_name="pms.reservation",
relation="folio_changes_allowed_reservation_rel",
column1="folio_changes_id",
column2="allowed_reservation_ids",
compute="_compute_allowed_reservations",
)
new_price = fields.Float(
@@ -71,6 +67,16 @@ class WizardFolioChanges(models.TransientModel):
default=True,
)
def _default_folio_id(self):
folio_id = self._context.get("active_id")
folio = self.env["pms.folio"].browse(folio_id)
return folio
def _default_reservation_ids(self):
folio_id = self._context.get("active_id")
folio = self.env["pms.folio"].browse(folio_id)
return folio.reservation_ids
@api.depends("folio_id")
def _compute_allowed_reservations(self):
self.ensure_one()

View File

@@ -10,39 +10,37 @@ class AvailabilityWizard(models.TransientModel):
_description = "Wizard for massive changes on Availability Plans & Pricelists."
_check_pms_properties_auto = True
def _default_avail_readonly(self):
return True if self._context.get("availability_plan_id") else False
def _default_pricelist_readonly(self):
return True if self._context.get("pricelist_id") else False
# Fields declaration
pms_property_ids = fields.Many2many(
comodel_name="pms.property",
string="Property",
comodel_name="pms.property",
default=lambda self: self.env["pms.property"].browse(
self.env.user.get_active_property_ids()[0]
),
)
massive_changes_on = fields.Selection(
[("pricelist", "Pricelist"), ("availability_plan", "Availability Plan")],
string="On",
default="availability_plan",
selection=[
("pricelist", "Pricelist"),
("availability_plan", "Availability Plan"),
],
required=True,
default="availability_plan",
)
availability_plan_id = fields.Many2one(
comodel_name="pms.availability.plan",
string="Availability Plan to apply massive changes",
comodel_name="pms.availability.plan",
check_pms_properties=True,
# can be setted by context from availability plan detail
)
pricelist_id = fields.Many2one(
comodel_name="product.pricelist",
string="Pricelist to apply massive changes",
comodel_name="product.pricelist",
check_pms_properties=True,
)
allowed_pricelist_ids = fields.One2many(
comodel_name="product.pricelist", compute="_compute_allowed_pricelist_ids"
string="Allowed pricelists",
comodel_name="product.pricelist",
compute="_compute_allowed_pricelist_ids",
)
start_date = fields.Date(
string="From",
@@ -53,8 +51,8 @@ class AvailabilityWizard(models.TransientModel):
required=True,
)
room_type_id = fields.Many2one(
comodel_name="pms.room.type",
string="Room Type",
comodel_name="pms.room.type",
check_pms_properties=True,
)
price = fields.Float(string="Price")
@@ -176,31 +174,45 @@ class AvailabilityWizard(models.TransientModel):
)
rules_to_overwrite = fields.One2many(
string="Rule to Overwrite",
readonly=True,
store=False,
comodel_name="pms.availability.plan.rule",
compute="_compute_rules_to_overwrite",
store=False,
readonly=True,
)
pricelist_items_to_overwrite = fields.One2many(
string="Pricelist Items to Override",
readonly=True,
store=False,
comodel_name="product.pricelist.item",
compute="_compute_pricelist_items_to_overwrite",
store=False,
readonly=True,
)
num_rules_to_overwrite = fields.Integer(
string="Rules to overwrite on massive changes",
compute="_compute_num_rules_to_overwrite",
store=False,
readonly=True,
store=False,
compute="_compute_num_rules_to_overwrite",
)
num_pricelist_items_to_overwrite = fields.Integer(
string="Pricelist items to overwrite on massive changes",
compute="_compute_num_pricelist_items_to_overwrite",
store=False,
readonly=True,
store=False,
)
avail_readonly = fields.Boolean(default=_default_avail_readonly)
pricelist_readonly = fields.Boolean(default=_default_pricelist_readonly)
avail_readonly = fields.Boolean(
string="Avialability Readonly",
default=lambda self: self._default_avail_readonly(),
)
pricelist_readonly = fields.Boolean(
string="Pricelist Readonly",
default=lambda self: self._default_pricelist_readonly(),
)
def _default_avail_readonly(self):
return True if self._context.get("availability_plan_id") else False
def _default_pricelist_readonly(self):
return True if self._context.get("pricelist_id") else False
@api.depends("massive_changes_on")
def _compute_allowed_pricelist_ids(self):
@@ -417,7 +429,6 @@ class AvailabilityWizard(models.TransientModel):
)
return domain_overwrite
# actions
def apply_massive_changes(self):
for record in self:

View File

@@ -11,35 +11,35 @@ class WizardPaymentFolio(models.TransientModel):
_description = "Payments"
folio_id = fields.Many2one(
"pms.folio",
string="Folio",
required=True,
comodel_name="pms.folio",
)
reservation_ids = fields.Many2many(
"pms.reservation",
string="Reservations",
comodel_name="pms.reservation",
)
service_ids = fields.Many2many(
"pms.service",
string="Services",
comodel_name="pms.service",
)
payment_method_id = fields.Many2one(
"account.journal",
string="Payment Method",
required=True,
comodel_name="account.journal",
domain="[('id', 'in', allowed_method_ids)]",
)
allowed_method_ids = fields.Many2many(
"account.journal",
"allowed_payment_journal_rel",
"payment_id",
"journal_id",
compute="_compute_allowed_method_ids",
store="True",
comodel_name="account.journal",
relation="allowed_payment_journal_rel",
column1="payment_id",
column2="journal_id",
compute="_compute_allowed_method_ids",
)
amount = fields.Float("Amount", digits=("Product Price"))
date = fields.Date("Date", default=fields.Date.context_today, required=True)
partner_id = fields.Many2one("res.partner")
amount = fields.Float(string="Amount", digits=("Product Price"))
date = fields.Date(String="Date", required=True, default=fields.Date.context_today)
partner_id = fields.Many2one(string="Partner", comodel_name="res.partner")
@api.depends("folio_id")
def _compute_allowed_method_ids(self):

View File

@@ -6,29 +6,30 @@ from odoo.exceptions import UserError
class ReservationSplitJoinSwapWizard(models.TransientModel):
_name = "pms.reservation.split.join.swap.wizard"
string = ("Operation",)
help = ("Operation to be applied on the reservation",)
operation = fields.Selection(
[
("swap", "Swap rooms"),
("split", "Split reservation"),
("join", "Join reservation"),
],
string="Operation",
help="Operation to be applied on the reservation",
default=lambda self: self._context.get("default_operation")
if self._context.get("default_operation")
else "swap",
)
reservation_id = fields.Many2one(
string="Reservation",
comodel_name="pms.reservation",
default=lambda self: self.env["pms.reservation"]
.browse(self._context.get("active_id"))
.id
if self._context.get("active_id")
else False,
comodel_name="pms.reservation",
)
checkin = fields.Date(
string="Check In",
help="Checkin in reservation",
default=lambda self: self.env["pms.reservation"]
.browse(self._context.get("active_id"))
.checkin
@@ -37,6 +38,7 @@ class ReservationSplitJoinSwapWizard(models.TransientModel):
)
checkout = fields.Date(
string="Check Out",
help="checkout in reservation",
default=lambda self: self.env["pms.reservation"]
.browse(self._context.get("active_id"))
.checkout
@@ -45,15 +47,13 @@ class ReservationSplitJoinSwapWizard(models.TransientModel):
)
reservations = fields.Many2many(
string="Reservations",
comodel_name="pms.reservation",
compute="_compute_reservations",
readonly=False,
store=True,
comodel_name="pms.reservation",
compute="_compute_reservations",
)
room_source = fields.Many2one(
string="Room Source",
comodel_name="pms.room",
domain="[('id', 'in', allowed_rooms_sources)]",
default=lambda self: self.env["pms.reservation"]
.browse(self._context.get("active_id"))
.preferred_room_id
@@ -62,6 +62,8 @@ class ReservationSplitJoinSwapWizard(models.TransientModel):
.browse(self._context.get("active_id"))
.splitted
else False,
comodel_name="pms.room",
domain="[('id', 'in', allowed_rooms_sources)]",
)
room_target = fields.Many2one(
string="Room Target",
@@ -70,25 +72,26 @@ class ReservationSplitJoinSwapWizard(models.TransientModel):
)
allowed_rooms_sources = fields.Many2many(
string="Allowed rooms source",
store=True,
readonly=False,
comodel_name="pms.room",
relation="pms_wizard_split_join_swap_reservation_rooms_source",
column1="wizard_id",
column2="room_id",
compute="_compute_allowed_rooms_source",
store=True,
readonly=False,
)
allowed_rooms_target = fields.Many2many(
string="Allowed rooms target",
comodel_name="pms.room",
store=True,
readonly=False,
relation="pms_wizard_split_join_swap_reservation_rooms_target",
column1="wizard_id",
column2="room_id",
compute="_compute_allowed_rooms_target",
store=True,
readonly=False,
)
reservation_lines_to_change = fields.One2many(
string="Reservations Lines To Change",
comodel_name="pms.wizard.reservation.lines.split",
inverse_name="reservation_wizard_id",
compute="_compute_reservation_lines",
@@ -306,6 +309,7 @@ class ReservationLinesToSplit(models.TransientModel):
_name = "pms.wizard.reservation.lines.split"
reservation_wizard_id = fields.Many2one(
string="Reservation Wizard",
comodel_name="pms.reservation.split.join.swap.wizard",
)
date = fields.Date(
@@ -319,9 +323,9 @@ class ReservationLinesToSplit(models.TransientModel):
allowed_room_ids = fields.Many2many(
string="Allowed Rooms",
help="It contains all available rooms for this line",
store=True,
comodel_name="pms.room",
compute="_compute_allowed_room_ids",
store=True,
# readonly=False
)