You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
228 lines
11 KiB
228 lines
11 KiB
# -*- coding: utf-8 -*-
|
|
#############################################################################
|
|
#
|
|
# Cybrosys Technologies Pvt. Ltd.
|
|
#
|
|
# Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>).
|
|
# Author: Gayathri V (odoo@cybrosys.com)
|
|
#
|
|
# You can modify it under the terms of the GNU AFFERO
|
|
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
|
|
#
|
|
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
|
|
# (AGPL v3) along with this program.
|
|
# If not, see <http://www.gnu.org/licenses/>.
|
|
#
|
|
#############################################################################
|
|
from datetime import date
|
|
from odoo import api, fields, models, _
|
|
from odoo.exceptions import ValidationError
|
|
|
|
|
|
class CleaningBooking(models.Model):
|
|
"""Create a new model for booking purposes.
|
|
The system will incorporate three buttons to indicate the
|
|
booking and cleaning status: "Confirm", "Clean" and "Cancel"."""
|
|
_name = "cleaning.booking"
|
|
_description = "Cleaning Booking"
|
|
_inherit = ['mail.thread', 'mail.activity.mixin']
|
|
_rec_name = 'customer_name_id'
|
|
|
|
def _default_cleaning_team_ids(self):
|
|
"""Returns default values for cleaning_team_ids records"""
|
|
return self.env['cleaning.team'].search([]).ids
|
|
|
|
customer_name_id = fields.Many2one('res.partner',
|
|
string='Name of Customer',
|
|
required=True,
|
|
help="Choose customer name")
|
|
address = fields.Char(string='Address',
|
|
required=True,
|
|
help="Enter address of customer")
|
|
building_type_id = fields.Many2one('building.type',
|
|
string='Building Type',
|
|
required=True,
|
|
help="Choose building type")
|
|
booking_date = fields.Date(default=fields.date.today(),
|
|
help="Choose the booking date",
|
|
string='Booking Date')
|
|
cleaning_team_ids = fields.Many2many('cleaning.team',
|
|
string='Cleaning Team',
|
|
help="Store cleaning team based on "
|
|
"cleaning_time",
|
|
default=_default_cleaning_team_ids)
|
|
cleaning_team_id = fields.Many2one('cleaning.team',
|
|
string='Cleaning Team',
|
|
help="Choose cleaning team",
|
|
required=True,
|
|
domain="[('id', 'in', "
|
|
"cleaning_team_ids)]")
|
|
cleaning_inspection_id = fields.Many2one('cleaning.inspection',
|
|
string="Cleaning Inspection",
|
|
help="Choose Cleaning Inspection")
|
|
cleaning_team_duty_id = fields.Many2one('cleaning.team.duty',
|
|
string="Cleaning Team Duty",
|
|
help="Choose Cleaning Team Duty")
|
|
cleaning_date = fields.Date(string='Cleaning Date',
|
|
required=True,
|
|
help="Choose Date for cleaning")
|
|
cleaning_time = fields.Selection([('morning', 'Morning'),
|
|
('evening', 'Evening'),
|
|
('night', 'Night')],
|
|
string='Cleaning Time',
|
|
help="Choose Time for cleaning",
|
|
required=True)
|
|
description = fields.Char(string='Description',
|
|
help="Enter Description For Booking")
|
|
duration = fields.Selection([('forever', 'Forever'),
|
|
('fixed', 'Fixed')],
|
|
default='forever', string='Duration',
|
|
help="Choose Duration For Cleaning")
|
|
end_after = fields.Integer(string='End After',
|
|
help="Choose End of cleaning management")
|
|
end_duration = fields.Selection([('months', 'Months'),
|
|
('years', 'Years')],
|
|
string="End Duration",
|
|
help="Choose End duration of booking")
|
|
cleaning_shift_id = fields.Many2one("cleaning.shift",
|
|
help="Cleaning Shift",
|
|
string="Choose Cleaning Shift")
|
|
self_closable = fields.Boolean(string='Is Self Closable',
|
|
help="When checked reservations will"
|
|
"be automatically closed.")
|
|
automatic_closing = fields.Integer(string='Automatic Closing',
|
|
help="Automatic Closing Chooser")
|
|
location_state_id = fields.Many2one('res.country.state',
|
|
string="State",
|
|
required=True,
|
|
help="Choose State For Cleaning")
|
|
place = fields.Char(string="Place", help="Enter Place of Customer")
|
|
state = fields.Selection([('draft', 'Draft'),
|
|
('booked', 'Booked'),
|
|
('cleaned', 'Cleaned'),
|
|
('cancelled', 'Cancelled')],
|
|
default='draft', string='Status',
|
|
help="Stages For Cleaning Processes",
|
|
tracking=True)
|
|
confirm_stage = fields.Boolean(string="Is Confirm", default=True,
|
|
help="When checked,the status" ""
|
|
"will be 'Confirm'.")
|
|
clean_stage = fields.Boolean(string="Clean", default=True,
|
|
help="When checked,the status will be 'Clean'")
|
|
cancel_stage = fields.Boolean(string="Cancel", default=True,
|
|
help="When checked,the status"
|
|
"will be 'Cancel'.")
|
|
unit_price = fields.Float(string="Unit Price", default=0.0, required=True,
|
|
help="Uit Price for an hour")
|
|
total_hour_of_working = fields.Char(string="Total working hours",
|
|
help="Total working hours done by Team")
|
|
invoice_count = fields.Integer(compute="_compute_invoice_count",
|
|
string='Invoice Count')
|
|
|
|
@api.onchange('cleaning_time')
|
|
def _onchange_cleaning_time(self):
|
|
"""The team leader will appear at the scheduled cleaning time."""
|
|
domain = []
|
|
if self.cleaning_time:
|
|
res = self.env['cleaning.team.duty'].search(
|
|
[('cleaning_date', '=', self.cleaning_date),
|
|
('cleaning_time', '=', self.cleaning_time),
|
|
('state', 'not in', ['cancelled', 'cleaned'])])
|
|
if res:
|
|
domain = [('duty_type', '=', self.cleaning_time),
|
|
('id', 'not in', [duty.team_id.id for duty in res])]
|
|
else:
|
|
domain.append(('duty_type', '=', self.cleaning_time))
|
|
self.write({'cleaning_team_ids': [(6, 0, self.env
|
|
['cleaning.team'].search(domain).ids)]})
|
|
|
|
@api.onchange('cleaning_team_id')
|
|
def _onchange_cleaning_team_id(self):
|
|
"""The team leader's time will appear when changing the leader."""
|
|
self.cleaning_time = self.cleaning_team_id.duty_type
|
|
|
|
def action_booking(self):
|
|
"""The button action for "Confirm" typically involves
|
|
finalizing and saving the booking details entered
|
|
by the user."""
|
|
duty_ids_to_add = []
|
|
for rec in self:
|
|
cleaning_team_duty = rec.cleaning_team_duty_id.create({
|
|
"team_id": rec.cleaning_team_id.id,
|
|
"team_leader_id": rec.cleaning_team_id.team_leader_id.employee_name_id.id,
|
|
"members_ids": rec.cleaning_team_id.members_ids.ids,
|
|
"location_state_id": rec.location_state_id.id,
|
|
"place": rec.place,
|
|
"customer_id": rec.customer_name_id.id,
|
|
"cleaning_date": rec.cleaning_date,
|
|
"cleaning_time": rec.cleaning_time,
|
|
"cleaning_id": rec.id
|
|
})
|
|
rec.write(
|
|
{'state': 'booked', 'confirm_stage': False,
|
|
'clean_stage': False,
|
|
'cancel_stage': False,
|
|
'cleaning_team_duty_id': cleaning_team_duty.id})
|
|
duty_ids_to_add.append((4, cleaning_team_duty.id))
|
|
|
|
def action_cancel(self):
|
|
"""The button action for "Cancel" typically involves canceling
|
|
and removing a booking that was previously confirmed or reserved."""
|
|
for rec in self:
|
|
rec.cleaning_team_duty_id.write({'state': 'cancelled'})
|
|
rec.write(
|
|
{'state': 'cancelled', 'confirm_stage': False,
|
|
'cancel_stage': True,
|
|
'clean_stage': True})
|
|
|
|
def action_create_invoice(self):
|
|
"""Function for create an invoice for cleaning processes"""
|
|
for rec in self:
|
|
if rec.unit_price > 0.0:
|
|
invoice = rec.env['account.move'].create({
|
|
'move_type': 'out_invoice',
|
|
'partner_id': rec.customer_name_id.id,
|
|
'invoice_date': date.today(),
|
|
'payment_reference': rec.cleaning_date,
|
|
'cleaning_id': rec.id,
|
|
'invoice_line_ids': [(0, 0, {
|
|
'name': f"{rec.cleaning_team_id.name} ({rec.cleaning_inspection_id.inspection_date_and_time})",
|
|
'price_unit': float(rec.unit_price) * float(
|
|
rec.total_hour_of_working),
|
|
})],
|
|
})
|
|
return {
|
|
'name': 'account.move.form',
|
|
'res_model': 'account.move',
|
|
'type': 'ir.actions.act_window',
|
|
'view_mode': 'form',
|
|
'view_type': 'form',
|
|
'view_id': rec.env.ref("account.view_move_form").id,
|
|
'res_id': invoice.id,
|
|
'target': 'current'
|
|
}
|
|
else:
|
|
raise ValidationError(_("Specify the Unit Price for a hour"))
|
|
|
|
def action_view_invoice(self):
|
|
"""Function for open Invoice Smart Button"""
|
|
self.ensure_one()
|
|
return {
|
|
'type': 'ir.actions.act_window',
|
|
'name': 'Invoice',
|
|
'view_mode': 'list,form',
|
|
'res_model': 'account.move',
|
|
'domain': [('cleaning_id', '=', self.id)],
|
|
'context': "{'create': False}"
|
|
}
|
|
|
|
def _compute_invoice_count(self):
|
|
"""Function for count number of Invoices"""
|
|
for record in self:
|
|
record.invoice_count = self.env['account.move'].search_count(
|
|
[('cleaning_id', '=', self.id)])
|
|
|