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.
		
		
		
		
		
			
		
			
				
					
					
						
							213 lines
						
					
					
						
							10 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							213 lines
						
					
					
						
							10 KiB
						
					
					
				| # -*- coding: utf-8 -*- | |
| ############################################################################# | |
| # | |
| #    Cybrosys Technologies Pvt. Ltd. | |
| # | |
| #    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>) | |
| #    Author: Cybrosys Techno Solutions(<https://www.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 odoo import api, fields, models | |
| from odoo.exceptions import ValidationError | |
| 
 | |
| 
 | |
| class MovieRegistration(models.Model): | |
|     """ | |
|         Model for managing movie registrations including details like partner, | |
|         movie, date, time slot, screen, tickets, etc. | |
|     """ | |
|     _name = 'movie.registration' | |
|     _description = 'Movie Registration' | |
| 
 | |
|     name = fields.Char(required=True, copy=False, | |
|                        default='New', readonly=True, | |
|                        help='Name of the Movie Ticket') | |
|     partner_id = fields.Many2one('res.partner', string='Select Partner', | |
|                                  help='Mention the partner') | |
|     movie_id = fields.Many2one('movie.movie', string='Select Movie', | |
|                                domain="[('id', 'in', available_movie_ids)]", | |
|                                required=True, help='Mention the movie id') | |
|     movie_type = fields.Many2many('show.type', related='movie_id.show_type_ids', | |
|                                   help='Show type of the movie') | |
|     movie_lang = fields.Many2one('res.lang', string='Movie Langauge', | |
|                                  related='movie_id.movie_language_id', | |
|                                  help='Language of the movie') | |
|     date = fields.Date(string='Date', default=fields.Date.today(), | |
|                        required=True, help='Mention the date for booking.') | |
|     time_slot_id = fields.Many2one('time.slots', | |
|                                    string='Select time slot', | |
|                                    domain="[('id', 'in', available_time_slot_ids)]", | |
|                                    required=True, help='Mention the time slots of the movie') | |
|     screen_id = fields.Many2one('movie.screen', string='Select Screen', | |
|                                 domain="[('id', 'in', available_screens_ids)]", | |
|                                 required=True, help='Mention the screen of the movie') | |
|     available_movie_ids = fields.Many2many('movie.movie', | |
|                                            string='Available movies', | |
|                                            help='Mention the available movies') | |
|     available_time_slot_ids = fields.Many2many('time.slots', | |
|                                                string='Available time slots', | |
|                                                compute='_compute_available_time_slot_ids', | |
|                                                help='Mention the available time slots') | |
|     available_screens_ids = fields.Many2many('movie.screen', | |
|                                              string='Available screens', | |
|                                              help='Mention the available screen') | |
|     movie_price = fields.Monetary(string='Movie Price', | |
|                                   related='movie_id.price', | |
|                                   help='Price of the movie ticket') | |
|     currency_id = fields.Many2one('res.currency', string='Currency', | |
|                                   help="Currency", | |
|                                   required=True, | |
|                                   default=lambda | |
|                                       self: self.env.user.company_id.currency_id) | |
|     no_of_tickets = fields.Integer(string='Number of tickets', default=1, | |
|                                    help='Mention the number of tickets') | |
|     movie_poster = fields.Binary(related='movie_id.movie_poster', | |
|                                  string='Movie poster', | |
|                                  help='Poster of the movie.') | |
|     movie_cast_ids = fields.Many2many(related='movie_id.movie_cast_ids', | |
|                                       string='Movie Cast', readonly=True, | |
|                                       help='Movie casts') | |
|     seat_ids = fields.One2many('movie.seats', 'movie_registration_id', | |
|                                string="Seats", help='Mention the seat ids') | |
|     qr_code = fields.Binary(string='Qr Code', help='Qr code containing ticket details') | |
|     state = fields.Selection([('draft', 'Draft'), | |
|                               ('done', 'Done'), | |
|                               ('invoiced', 'Invoiced')], string='Status', | |
|                              default='draft', help='Status of the movie registration') | |
| 
 | |
|     def action_submit(self): | |
|         """ Function for writing the state into done.""" | |
|         self.write({'state': 'done'}) | |
| 
 | |
|     def action_invoice(self): | |
|         """ Function for creating invoice.""" | |
|         product_id = self.env.ref('show_booking_management.product_1') | |
|         try: | |
|             move = self.env['account.move'].create([ | |
|                 { | |
|                     'move_type': 'out_invoice', | |
|                     'partner_id': self.partner_id.id, | |
|                     'movie_ticket_id': self.id, | |
|                     'date': self.date, | |
|                     'invoice_date': fields.Date.today(), | |
|                     'invoice_line_ids': [ | |
|                         (0, 0, | |
|                          { | |
|                              'product_id': product_id.id, | |
|                              'name': product_id.name, | |
|                              'quantity': self.no_of_tickets, | |
|                              'price_unit': self.movie_id.price, | |
|                          })], | |
|                 }, ]) | |
|             self.write({'state': 'invoiced'}) | |
|             move.action_post() | |
|             return { | |
|                 'name': 'Invoice', | |
|                 'res_id': move.id, | |
|                 'res_model': 'account.move', | |
|                 'view_id': False, | |
|                 'view_mode': 'form', | |
|                 'type': 'ir.actions.act_window', | |
|             } | |
|         except: | |
|             raise ValidationError('Invoice Creation Failed!') | |
| 
 | |
|     @api.depends('movie_id') | |
|     def _compute_available_time_slot_ids(self): | |
|         """ Function for computing time slots and screens.""" | |
|         for record in self: | |
|             record.available_time_slot_ids = record.movie_id.available_time_slots_ids.ids | |
|             record.available_screens_ids = record.movie_id.available_screens_ids.ids | |
| 
 | |
|     @api.onchange('date') | |
|     def fetch_movies(self): | |
|         """ Function for validating date and fetching movies based on the date.""" | |
|         for record in self: | |
|             if record.date < fields.Date.today(): | |
|                 raise ValidationError('The date must be greater than or equal to today\'s date.') | |
|             record.movie_id = None | |
|             record.available_movie_ids = None | |
|             movies_list = self.env['movie.movie'].search([ | |
|                 ('show_start_date', '<=', record.date), | |
|                 ('show_end_date', '>=', record.date), | |
|             ]).ids | |
|             record.available_movie_ids = movies_list | |
| 
 | |
|     def check_seat_availability(self): | |
|         """ Function for checking seat availability""" | |
|         reserved_seats = sum(self.search([ | |
|             ('date', '=', self.date), | |
|             ('time_slot_id', '=', self.time_slot_id.id), | |
|             ('screen_id', '=', self.screen_id.id), | |
|             ('state', '=', 'invoiced') | |
|         ]).mapped('no_of_tickets')) + self.no_of_tickets | |
|         if reserved_seats > self.screen_id.total_seat_count: | |
|             raise ValidationError('Selected screen is already full') | |
| 
 | |
|     @api.model | |
|     def create(self, vals): | |
|         """Supering create function to check screen availability""" | |
|         if vals.get('name', 'New') == 'New': | |
|             vals['name'] = self.env['ir.sequence'].next_by_code( | |
|                 'movie.registration') | |
|         res = super(MovieRegistration, self).create(vals) | |
|         res.check_seat_availability() | |
|         return res | |
| 
 | |
|     @api.constrains('no_of_tickets') | |
|     def check_seat(self): | |
|         """ Function for checking seat availability based on the number of tickets""" | |
|         self.check_seat_availability() | |
| 
 | |
|     @api.onchange('movie_id') | |
|     def set_values(self): | |
|         """ Function for resetting time slot and screen while changing movie.""" | |
|         for record in self: | |
|             record.update({'time_slot_id': None, 'screen_id': None}) | |
| 
 | |
|     def action_generate_ticket_pdf(self): | |
|         """ Function for downloading ticket pdf.""" | |
|         return self.env.ref( | |
|             'show_booking_management.action_report_movie_ticket').report_action(self) | |
| 
 | |
|     @api.model | |
|     def check_seat_available(self, date, time_slot_id, screen_id, ticket_count): | |
|         """ Function for updating the status of the seats availability based | |
|          on the movie time slot and screen selected""" | |
|         screen = self.env['movie.screen'].browse(int(screen_id)) | |
|         reserved_seats = sum(self.search([ | |
|             ('date', '=', date), | |
|             ('time_slot_id', '=', int(time_slot_id)), | |
|             ('screen_id', '=', int(screen_id)), | |
|             ('state', '=', 'invoiced') | |
|         ]).mapped('no_of_tickets')) | |
|         if reserved_seats + int(ticket_count) > screen.total_seat_count: | |
|             return { | |
|                 'Status': 'Failed', | |
|                 'Error': f"The selected screen has only " | |
|                          f"{screen.total_seat_count - reserved_seats} seats left!" | |
|             } | |
|         return {'Status': 'Success'} | |
| 
 | |
|     def action_open_invoices(self): | |
|         """ Function for viewing created invoices""" | |
|         return { | |
|             'name': 'Invoice', | |
|             'domain': [('movie_ticket_id', '=', self.id)], | |
|             'res_model': 'account.move', | |
|             'view_id': False, | |
|             'view_mode': 'tree,form', | |
|             'type': 'ir.actions.act_window', | |
|         }
 | |
| 
 |