mirror of
https://github.com/OCA/pms.git
synced 2025-01-29 00:17:45 +02:00
[ADD] Turist Operator Rol
This commit is contained in:
@@ -134,6 +134,9 @@ class HotelFolio(models.Model):
|
||||
('web', 'Web')], 'Sales Channel', default='door')
|
||||
user_id = fields.Many2one('res.users', string='Salesperson', index=True,
|
||||
track_visibility='onchange', default=lambda self: self.env.user)
|
||||
tour_operator_id = fields.Many2one('res.partner',
|
||||
'Tour Operator',
|
||||
domain=[('is_tour_operator', '=', True)])
|
||||
date_order = fields.Datetime(
|
||||
string='Order Date',
|
||||
required=True, readonly=True, index=True,
|
||||
|
||||
@@ -210,6 +210,7 @@ class HotelReservation(models.Model):
|
||||
required=True, track_visibility='onchange')
|
||||
|
||||
partner_id = fields.Many2one(related='folio_id.partner_id')
|
||||
tour_operator_id = fields.Many2one(related='folio_id.tour_operator_id')
|
||||
partner_invoice_id = fields.Many2one(related='folio_id.partner_invoice_id')
|
||||
partner_invoice_vat = fields.Char(related="partner_invoice_id.vat")
|
||||
partner_invoice_name = fields.Char(related="partner_invoice_id.name")
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
from odoo import api, fields, models
|
||||
from odoo.osv.expression import get_unaccent_wrapper
|
||||
from odoo.exceptions import ValidationError
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -29,49 +30,23 @@ class ResPartner(models.Model):
|
||||
folios_count = fields.Integer('Folios', compute='_compute_folios_count')
|
||||
unconfirmed = fields.Boolean('Unconfirmed', default=True)
|
||||
main_partner_id = fields.Many2one('res.partner', string='Destination Partner fusion')
|
||||
is_tour_operator = fields.Boolean('Is Tour Operator')
|
||||
|
||||
@api.model
|
||||
def name_search(self, name, args=None, operator='ilike', limit=100):
|
||||
result = super(ResPartner, self).name_search(name, args=None,
|
||||
operator='ilike',
|
||||
limit=100)
|
||||
if args is None:
|
||||
if not args:
|
||||
args = []
|
||||
if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'):
|
||||
self.check_access_rights('read')
|
||||
where_query = self._where_calc(args)
|
||||
self._apply_ir_rules(where_query, 'read')
|
||||
from_clause, where_clause, where_clause_params = where_query.get_sql()
|
||||
where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE '
|
||||
|
||||
# search on the name of the contacts and of its company
|
||||
search_name = name
|
||||
if operator in ('ilike', 'like'):
|
||||
search_name = '%%%s%%' % name
|
||||
if operator in ('=ilike', '=like'):
|
||||
operator = operator[1:]
|
||||
|
||||
unaccent = get_unaccent_wrapper(self.env.cr)
|
||||
|
||||
query = """SELECT id
|
||||
FROM res_partner
|
||||
{where} ({phone} {operator} {percent}
|
||||
OR {mobile} {operator} {percent})
|
||||
ORDER BY {display_name} {operator} {percent} desc,
|
||||
{display_name}
|
||||
""".format(where=where_str,
|
||||
operator=operator,
|
||||
phone=unaccent('phone'),
|
||||
display_name=unaccent('display_name'),
|
||||
mobile=unaccent('mobile'),
|
||||
percent=unaccent('%s'),)
|
||||
|
||||
where_clause_params += [search_name]*3
|
||||
if limit:
|
||||
query += ' limit %s'
|
||||
where_clause_params.append(limit)
|
||||
self.env.cr.execute(query, where_clause_params)
|
||||
partner_ids = [row[0] for row in self.env.cr.fetchall()]
|
||||
if partner_ids:
|
||||
result += self.browse(partner_ids).name_get()
|
||||
return result
|
||||
domain = ['|', '|', ('phone', operator, name),
|
||||
('mobile', operator, name), ('email', operator, name),
|
||||
]
|
||||
partners = self.search(domain + args, limit=limit,)
|
||||
res = partners.name_get()
|
||||
if limit:
|
||||
limit_rest = limit - len(partners)
|
||||
else:
|
||||
limit_rest = limit
|
||||
if limit_rest or not limit:
|
||||
args += [('id', 'not in', partners.ids)]
|
||||
res += super(ResPartner, self).name_search(
|
||||
name, args=args, operator=operator, limit=limit_rest)
|
||||
return res
|
||||
|
||||
@@ -84,6 +84,8 @@
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<field name="reservation_type" attrs="{'readonly':[('state','not in',('draft'))]}"/>
|
||||
<field name="channel_type" attrs="{'required':[('reservation_type','=','normal')]}"/>
|
||||
<field name="tour_operator_id"
|
||||
options="{'no_create': True,'no_open': True}" />
|
||||
</group>
|
||||
<group>
|
||||
<field name="partner_internal_comment"/>
|
||||
@@ -287,6 +289,7 @@
|
||||
<search string="Tables Detail">
|
||||
<field name="partner_id" />
|
||||
<field name="partner_invoice_id" />
|
||||
<field name="tour_operator_id" />
|
||||
<filter name="to_invoice" string="To invoice"
|
||||
domain="[('invoice_status', '=', 'to invoice')]" />
|
||||
<filter name="payment_pending" string="Payment Pending"
|
||||
@@ -294,8 +297,10 @@
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Customer" icon="terp-stock_symbol-selection"
|
||||
context="{'group_by':'partner_id'}" />
|
||||
<filter string="Invoice Contact"
|
||||
context="{'group_by':'partner_invoice_id'}" />
|
||||
<filter string="Invoice Contact"
|
||||
context="{'group_by':'partner_invoice_id'}" />
|
||||
<filter string="Tour Operator" domain="[]"
|
||||
context="{'group_by':'tour_operator_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
||||
@@ -192,26 +192,28 @@
|
||||
attrs="{'invisible': [('reservation_type','in',('out'))]}"/>
|
||||
<field nolabel="1" placeholder="Cancel Reason" name="cancelled_reason" attrs="{'invisible':[('state','not in',('cancelled'))]}"/>
|
||||
<field nolabel="1" colspan="2" placeholder="Description in Guest Documents" name="name"/>
|
||||
<field name="nights"/>
|
||||
<field placeholder="Arriva Hour" name="arrival_hour"/>
|
||||
<field placeholder="Departure our" name="departure_hour"/>
|
||||
</group>
|
||||
<group colspan="2" col="3" string="Reservation Details" name="reservation_details">
|
||||
<field name="pricelist_id"
|
||||
attrs="{'invisible': [('reservation_type','in',('out'))]}"/>
|
||||
<field name="tour_operator_id"
|
||||
options="{'no_create': True,'no_open': True}" />
|
||||
<field name="cancelled_reason" attrs="{'invisible': [('state', 'not in', ('cancelled'))]}"/>
|
||||
<field name="nights"/>
|
||||
<!-- TODO: How to filter to avoid show False (generic) pricelist board when exist a specific pricelist board¿? -->
|
||||
<field name="board_service_room_id" domain="[
|
||||
('hotel_room_type_id', '=', room_type_id),
|
||||
('pricelist_id', 'in', [pricelist_id, False])]"
|
||||
options="{'no_create': True,'no_open': True}"
|
||||
attrs="{'invisible': ['|',('reservation_type','in',('out')),('parent_reservation','!=',False)]}" />
|
||||
<field name="adults" attrs="{'invisible': [('reservation_type','in',('out'))]}"/>
|
||||
<field name="children" attrs="{'invisible': [('reservation_type','in',('out'))]}"/>
|
||||
<field name="qty_invoiced" invisible="1"/>
|
||||
<field name="qty_to_invoice" invisible="1"/>
|
||||
<field name="room_type_id" on_change="1" options="{'no_create': True,'no_open': True}"
|
||||
attrs="{'readonly':[('state','not in',('draft'))]}"/>
|
||||
<!-- TODO: How to filter to avoid show False (generic) pricelist board when exist a specific pricelist board¿? -->
|
||||
<field name="board_service_room_id" domain="[
|
||||
('hotel_room_type_id', '=', room_type_id),
|
||||
('pricelist_id', 'in', [pricelist_id, False])]"
|
||||
options="{'no_create': True,'no_open': True}"
|
||||
attrs="{'invisible': ['|',('reservation_type','in',('out')),('parent_reservation','!=',False)]}" />
|
||||
<field name="folio_internal_comment" colspan="2" nolabel="1" placeholder="Reservation Notes"/>
|
||||
</group>
|
||||
<group colspan="2" col="3" class="oe_subtotal_footer" style="margin-right: 20px; !important" name="reservation_total" string="Amounts">
|
||||
@@ -545,6 +547,7 @@
|
||||
<search string="Reservation Detail">
|
||||
<field name="partner_id" />
|
||||
<field name="folio_id" />
|
||||
<field name="tour_operator_id" />
|
||||
<filter string="My Reservations"
|
||||
domain="[('create_uid', '=', uid)]"
|
||||
/>
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
</button>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//field[@name='user_id']" position="after">
|
||||
<field name="is_tour_operator" attrs="{'invisible': [('company_type','!=','company')]}"/>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
@@ -54,47 +54,23 @@ class ResPartner(models.Model):
|
||||
|
||||
@api.model
|
||||
def name_search(self, name, args=None, operator='ilike', limit=100):
|
||||
result = super(ResPartner, self).name_search(name, args=None,
|
||||
operator='ilike',
|
||||
limit=100)
|
||||
if args is None:
|
||||
if not args:
|
||||
args = []
|
||||
if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'):
|
||||
self.check_access_rights('read')
|
||||
where_query = self._where_calc(args)
|
||||
self._apply_ir_rules(where_query, 'read')
|
||||
from_clause, where_clause, where_clause_params = where_query.get_sql()
|
||||
where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE '
|
||||
|
||||
# search on the name of the contacts and of its company
|
||||
search_name = name
|
||||
if operator in ('ilike', 'like'):
|
||||
search_name = '%%%s%%' % name
|
||||
if operator in ('=ilike', '=like'):
|
||||
operator = operator[1:]
|
||||
|
||||
unaccent = get_unaccent_wrapper(self.env.cr)
|
||||
|
||||
query = """SELECT id
|
||||
FROM res_partner
|
||||
{where} ({document_number} {operator} {percent})
|
||||
ORDER BY {display_name} {operator} {percent} desc,
|
||||
{display_name}
|
||||
""".format(where=where_str,
|
||||
operator=operator,
|
||||
document_number=unaccent('document_number'),
|
||||
display_name=unaccent('display_name'),
|
||||
percent=unaccent('%s'),)
|
||||
|
||||
where_clause_params += [search_name]*2
|
||||
if limit:
|
||||
query += ' limit %s'
|
||||
where_clause_params.append(limit)
|
||||
self.env.cr.execute(query, where_clause_params)
|
||||
partner_ids = [row[0] for row in self.env.cr.fetchall()]
|
||||
if partner_ids:
|
||||
result += self.browse(partner_ids).name_get()
|
||||
return result
|
||||
domain = ['|',
|
||||
('document_number', operator, name),
|
||||
('vat', operator, name),
|
||||
]
|
||||
partners = self.search(domain + args, limit=limit,)
|
||||
res = partners.name_get()
|
||||
if limit:
|
||||
limit_rest = limit - len(partners)
|
||||
else:
|
||||
limit_rest = limit
|
||||
if limit_rest or not limit:
|
||||
args += [('id', 'not in', partners.ids)]
|
||||
res += super(ResPartner, self).name_search(
|
||||
name, args=args, operator=operator, limit=limit_rest)
|
||||
return res
|
||||
|
||||
@api.model
|
||||
def _get_duplicated_ids(self, partner):
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
</xpath>
|
||||
|
||||
<xpath expr='//field[@name="vat"]' position='after'>
|
||||
<field name="unconfirmed" />
|
||||
<field name="unconfirmed" groups="base.group_no_one"/>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
|
||||
Reference in New Issue
Block a user