1
0
forked from Mapan/odoo17e
odoo17e-kedaikipas58/addons/appointment_account_payment/tests/test_calendar_booking.py
2024-12-10 09:04:09 +07:00

253 lines
12 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import Command
from odoo.addons.appointment_account_payment.tests.common import AppointmentAccountPaymentCommon
from odoo.tests import users, tagged
from odoo.tools import mute_logger
from unittest.mock import patch
from dateutil.relativedelta import relativedelta
from freezegun import freeze_time
@tagged("post_install", "-at_install")
class AppointmentAccountPaymentTest(AppointmentAccountPaymentCommon):
@mute_logger('odoo.sql_db')
@users('apt_manager')
def test_booking_to_event_on_invoice_paid_resource(self):
""" Replace booking with Event when invoice is paid - resource appointment """
appointment_type = self.appointment_resources_payment
asked_capacity = 5
start = self.start_slot
stop = self.stop_slot
# Assert Initial Capacity
resources_remaining_capacity = appointment_type._get_resources_remaining_capacity(appointment_type.resource_ids, start, stop)
self.assertEqual(resources_remaining_capacity['total_remaining_capacity'], 5)
# Create Calendar Event Booking and Calendar Booking Lines
booking_values = {
'appointment_type_id': appointment_type.id,
'asked_capacity': asked_capacity,
'duration': 1.0,
'partner_id': self.apt_manager.partner_id.id,
'product_id': appointment_type.product_id.id,
'start': start,
'stop': stop,
}
calendar_booking = self.env['calendar.booking'].create(booking_values)
calendar_booking_lines_values = {}
for resource in appointment_type.resource_ids:
resource_remaining_capacity = resources_remaining_capacity.get(resource)
new_capacity_reserved = min(resource_remaining_capacity, asked_capacity, resource.capacity)
asked_capacity -= new_capacity_reserved
calendar_booking_lines_values[resource.id] = {
'appointment_resource_id': resource.id,
'calendar_booking_id': calendar_booking.id,
'capacity_reserved': new_capacity_reserved,
'capacity_used': new_capacity_reserved if resource.shareable and appointment_type.resource_manage_capacity else resource.capacity,
}
self.env['calendar.booking.line'].create(calendar_booking_lines_values.values())
# Assert Booking Lines are not taking capacity
resources_remaining_capacity = appointment_type._get_resources_remaining_capacity(appointment_type.resource_ids, start, stop)
self.assertEqual(resources_remaining_capacity['total_remaining_capacity'], 5)
# Create an invoice
invoice = calendar_booking.sudo()._make_invoice_from_booking()
self.assertEqual(calendar_booking.account_move_id, invoice)
self.assertFalse(invoice.calendar_booking_ids.calendar_event_id)
# Paying invoice creates event and reserve space
invoice._invoice_paid_hook()
event = invoice.calendar_booking_ids.calendar_event_id
self.assertEqual(len(event), 1)
self.assertTrue(invoice.calendar_booking_ids.calendar_event_id)
resources_remaining_capacity = appointment_type._get_resources_remaining_capacity(appointment_type.resource_ids, start, stop)
self.assertEqual(resources_remaining_capacity['total_remaining_capacity'], 0)
# Assert Booking Data
self.assertTrue(event.active)
self.assertEqual(event, calendar_booking.calendar_event_id)
self.assertEqual(event.appointment_type_id, calendar_booking.appointment_type_id)
self.assertEqual(event.resource_total_capacity_reserved, calendar_booking.asked_capacity)
self.assertEqual(event.resource_total_capacity_used, calendar_booking.asked_capacity)
self.assertEqual(event.duration, calendar_booking.duration)
self.assertEqual(event.partner_ids, calendar_booking.partner_id)
self.assertEqual(event.start, calendar_booking.start)
self.assertEqual(event.stop, calendar_booking.stop)
self.assertTrue(all(attendee.state == 'accepted' for attendee in event.attendee_ids))
# Assert Booking Lines Data
booking_line_1 = event.booking_line_ids.filtered(lambda line: line.appointment_resource_id == self.resource_1)
booking_line_2 = event.booking_line_ids.filtered(lambda line: line.appointment_resource_id == self.resource_2)
self.assertEqual(len(booking_line_1 + booking_line_2), 2)
for booking_line in (booking_line_1 | booking_line_2):
calendar_booking_line = calendar_booking.booking_line_ids.filtered(
lambda line: line.appointment_resource_id == booking_line.appointment_resource_id)
self.assertTrue(calendar_booking_line)
self.assertTrue(booking_line.active)
self.assertEqual(booking_line.capacity_reserved, calendar_booking_line.capacity_reserved)
self.assertEqual(booking_line.capacity_used, calendar_booking_line.capacity_used)
self.assertEqual(booking_line.event_start, calendar_booking.start)
self.assertEqual(booking_line.event_stop, calendar_booking.stop)
@mute_logger('odoo.sql_db')
@freeze_time('2022-2-13 20:00:00')
@users('apt_manager')
def test_booking_to_event_on_invoice_paid_users(self):
""" Replace booking with Event when invoice is paid - staff user appointment """
appointment_type = self.appointment_users_payment
start = self.start_slot
stop = self.stop_slot
# Assert Initial Data
slots = appointment_type._get_appointment_slots('UTC')
slots_list = self._filter_appointment_slots(slots)
self.assertEqual(len(slots_list), 1)
# Create Calendar Event Booking
booking_values = {
'appointment_type_id': appointment_type.id,
'duration': 1.0,
'partner_id': self.apt_manager.partner_id.id,
'product_id': appointment_type.product_id.id,
'staff_user_id': self.staff_user_bxls.id,
'start': start,
'stop': stop,
}
calendar_booking = self.env['calendar.booking'].create(booking_values)
# Create an invoice
invoice = calendar_booking.sudo()._make_invoice_from_booking()
self.assertEqual(calendar_booking.account_move_id, invoice)
self.assertFalse(invoice.calendar_booking_ids.calendar_event_id)
# Calendar Booking do not reserve space
slots = appointment_type._get_appointment_slots('UTC')
slots_list = self._filter_appointment_slots(slots)
self.assertEqual(len(slots_list), 1)
# Paying invoice creates event and reserve space
invoice._invoice_paid_hook()
event = invoice.calendar_booking_ids.calendar_event_id
self.assertEqual(len(event), 1)
slots = appointment_type._get_appointment_slots('UTC')
slots_list = self._filter_appointment_slots(slots)
self.assertEqual(len(slots_list), 0)
# Assert Booking Data
self.assertTrue(event.active)
self.assertEqual(event, calendar_booking.calendar_event_id)
self.assertEqual(event.appointment_type_id, calendar_booking.appointment_type_id)
self.assertEqual(event.duration, calendar_booking.duration)
self.assertEqual(event.user_id, calendar_booking.staff_user_id)
self.assertEqual(event.partner_ids, calendar_booking.partner_id | calendar_booking.staff_user_id.partner_id)
self.assertEqual(event.start, calendar_booking.start)
self.assertEqual(event.stop, calendar_booking.stop)
self.assertTrue(all(attendee.state == 'accepted' for attendee in event.attendee_ids))
def test_booking_unlink(self):
""" Unlinking a booking should (only) unlink appointment answers not linked to any calendar event. """
appointment_type = self.appointment_users_payment
appointment_question = self.env['appointment.question'].create({
'appointment_type_id': appointment_type.id,
'name': 'How are you ?',
'question_type': 'char',
})
appointment_answer_input_values = {
'appointment_type_id': appointment_type.id,
'question_id': appointment_question.id,
'value_text_box': 'I am Good',
}
# Create Calendar Event Booking
booking_values = {
'appointment_type_id': appointment_type.id,
'appointment_answer_input_ids': [Command.create(appointment_answer_input_values)],
'duration': 1.0,
'partner_id': self.apt_manager.partner_id.id,
'product_id': appointment_type.product_id.id,
'staff_user_id': self.staff_user_bxls.id,
'start': self.start_slot,
'stop': self.stop_slot,
}
calendar_booking = self.env['calendar.booking'].create(booking_values)
self.assertFalse(calendar_booking.calendar_event_id)
answer_inputs = calendar_booking.appointment_answer_input_ids
self.assertEqual(len(answer_inputs), 1)
calendar_booking.unlink()
self.assertFalse(answer_inputs.exists())
calendar_booking = self.env['calendar.booking'].create(booking_values)
answer_inputs = calendar_booking.appointment_answer_input_ids
calendar_booking._make_event_from_paid_booking()
self.assertTrue(answer_inputs.calendar_event_id)
calendar_booking.unlink()
self.assertTrue(answer_inputs.exists())
@users('apt_manager')
def test_contiguous_bookings_availability(self):
""" Checks that two bookings with the same user (or resource) are both considered as available on contiguous slots. """
booking_values = {
'appointment_type_id': self.appointment_users_payment.id,
'duration': 1.0,
'partner_id': self.apt_manager.partner_id.id,
'product_id': self.appointment_users_payment.product_id.id,
'staff_user_id': self.staff_user_bxls.id,
}
calendar_bookings = self.env['calendar.booking'].create([{
'start': self.start_slot,
'stop': self.stop_slot,
**booking_values
}, {
'start': self.stop_slot,
'stop': self.stop_slot + relativedelta(hours=1),
**booking_values
}])
self.assertFalse(calendar_bookings._filter_unavailable_bookings())
calendar_bookings._make_event_from_paid_booking()
self.assertEqual(len(calendar_bookings.calendar_event_id), 2)
def test_gc_calendar_booking(self):
""" Remove bookings still existing after 6 months.
Remove bookings with ending passed for 2 months at least. """
max_creation_dt = self.reference_now - relativedelta(months=6)
max_stop_dt = self.reference_now - relativedelta(months=2)
with patch.object(self.env.cr, 'now', lambda: max_creation_dt - relativedelta(months=1)):
booking_1, booking_2 = self.env['calendar.booking'].create([{
'start': max_stop_dt + relativedelta(hours=1),
'stop': max_stop_dt + relativedelta(hours=2),
'appointment_type_id': self.appointment_users_payment.id,
'product_id': self.appointment_users_payment.product_id.id,
}, {
'start': max_stop_dt - relativedelta(hours=2),
'stop': max_stop_dt - relativedelta(hours=1),
'appointment_type_id': self.appointment_users_payment.id,
'product_id': self.appointment_users_payment.product_id.id,
}])
with patch.object(self.env.cr, 'now', lambda: self.reference_now):
booking_3, booking_4 = self.env['calendar.booking'].create([{
'start': max_stop_dt + relativedelta(hours=1),
'stop': max_stop_dt + relativedelta(hours=2),
'appointment_type_id': self.appointment_users_payment.id,
'product_id': self.appointment_users_payment.product_id.id,
}, {
'start': max_stop_dt - relativedelta(hours=2),
'stop': max_stop_dt - relativedelta(hours=1),
'appointment_type_id': self.appointment_users_payment.id,
'product_id': self.appointment_users_payment.product_id.id,
}])
with freeze_time(self.reference_now):
self.env['calendar.booking']._gc_calendar_booking()
self.assertFalse(booking_1.exists())
self.assertFalse(booking_2.exists())
self.assertTrue(booking_3.exists())
self.assertFalse(booking_4.exists())