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.
		
		
		
		
		
			
		
			
				
					
					
						
							333 lines
						
					
					
						
							16 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							333 lines
						
					
					
						
							16 KiB
						
					
					
				
								# -*- coding: utf-8 -*-
							 | 
						|
								###############################################################################
							 | 
						|
								#
							 | 
						|
								#    Cybrosys Technologies Pvt. Ltd.
							 | 
						|
								#
							 | 
						|
								#    Copyright (C) 2024-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
							 | 
						|
								#    Author: Anfas Faisal K (odoo@cybrosys.info)
							 | 
						|
								#
							 | 
						|
								#    You can modify it under the terms of the GNU LESSER
							 | 
						|
								#    GENERAL PUBLIC LICENSE (LGPL 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 LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
							 | 
						|
								#
							 | 
						|
								#    You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
							 | 
						|
								#    (LGPL v3) along with this program.
							 | 
						|
								#    If not, see <http://www.gnu.org/licenses/>.
							 | 
						|
								#
							 | 
						|
								###############################################################################
							 | 
						|
								from collections import OrderedDict
							 | 
						|
								from odoo import api, exceptions, fields, models, _
							 | 
						|
								from odoo.exceptions import ValidationError
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								class ReportPDF(models.Model):
							 | 
						|
								    """Class to handle PDF Report model"""
							 | 
						|
								    _name = 'report.pdf'
							 | 
						|
								    _description = 'PDF Reports'
							 | 
						|
								    _order = 'id DESC'
							 | 
						|
								
							 | 
						|
								    name = fields.Char(string='Name', help="Name of the report")
							 | 
						|
								    model_id = fields.Many2one('ir.model', string='Model',
							 | 
						|
								                               required=True,
							 | 
						|
								                               ondelete="cascade", help="Name of the model")
							 | 
						|
								    fields_ids = fields.One2many('report.pdf.field',
							 | 
						|
								                                 'report_id',
							 | 
						|
								                                 string='Fields',
							 | 
						|
								                                 required=True, ondelete="cascade",
							 | 
						|
								                                 help="Name of the fields")
							 | 
						|
								    date_field_id = fields.Many2one('ir.model.fields',
							 | 
						|
								                                    string='Date Filter',
							 | 
						|
								                                    ondelete="cascade",
							 | 
						|
								                                    help="Name of the fields",
							 | 
						|
								                                    )
							 | 
						|
								    start_date = fields.Date(string='Start Date', help="Set the start date")
							 | 
						|
								    end_date = fields.Date(string='End Date', help="Set the end date")
							 | 
						|
								    field_order = fields.Char(default='[]', string="First Order",
							 | 
						|
								                              help="First order")
							 | 
						|
								    action_button = fields.Boolean(default=False, string="Action button",
							 | 
						|
								                                   help="Action button")
							 | 
						|
								    binding_model_id = fields.Many2one('ir.model',
							 | 
						|
								                                       ondelete="cascade",
							 | 
						|
								                                       string="Binding model",
							 | 
						|
								                                       help="Choose binding model")
							 | 
						|
								    binding_type = fields.Selection([('action', 'Action'),
							 | 
						|
								                                     ('report', 'Report')],
							 | 
						|
								                                    required=True, default='action',
							 | 
						|
								                                    string="Binding Type",
							 | 
						|
								                                    help="Choose binding type")
							 | 
						|
								    ir_act_server_ref_id = fields.Many2one('ir.actions.act_window',
							 | 
						|
								                                           readonly=True, copy=False,
							 | 
						|
								                                           string="Server Id",
							 | 
						|
								                                           help="We can get the server id")
							 | 
						|
								
							 | 
						|
								    @api.constrains('start_date', 'end_date')
							 | 
						|
								    def _check_start_date_end_date(self):
							 | 
						|
								        """This will give validation at the time of end date and start
							 | 
						|
								        date have any problem or mismatch"""
							 | 
						|
								        if self.start_date and self.end_date:
							 | 
						|
								            if self.start_date > self.end_date or fields.Date.today() > \
							 | 
						|
								                    self.end_date:
							 | 
						|
								                raise ValidationError(
							 | 
						|
								                    'The Start Date And End Date Is Misplaced')
							 | 
						|
								
							 | 
						|
								    @api.constrains('fields_ids')
							 | 
						|
								    def _check_fields_ids(self):
							 | 
						|
								        """ Checks whether the user has entered least one fields for the
							 | 
						|
								        report"""
							 | 
						|
								        if not self.fields_ids:
							 | 
						|
								            raise exceptions.ValidationError('Please select a field.')
							 | 
						|
								
							 | 
						|
								    def action_print_report(self):
							 | 
						|
								        """ When the user requests to print the report, this function will be
							 | 
						|
								        called. Parameters and return values of the function is noted below.
							 | 
						|
								        @param self: The current report.pdf record. @return: A dictionary
							 | 
						|
								        with report data like field headers and field datas.
							 | 
						|
								        """
							 | 
						|
								        for rec in self:
							 | 
						|
								            domain = []
							 | 
						|
								            if rec.date_field_id and rec.start_date:
							 | 
						|
								                domain.append((rec.date_field_id.name, '>=', rec.start_date))
							 | 
						|
								            if rec.date_field_id and rec.end_date:
							 | 
						|
								                domain.append((rec.date_field_id.name, '<=', rec.end_date))
							 | 
						|
								            if rec.date_field_id and(rec.start_date and rec.end_date):
							 | 
						|
								                domain = [(rec.date_field_id.name, '>=', rec.start_date),
							 | 
						|
								                          (rec.date_field_id.name, '<=', rec.end_date)]
							 | 
						|
								            model_data = self.env[rec.model_id.model].search(domain)
							 | 
						|
								            table_data = []
							 | 
						|
								            child_table_data = []
							 | 
						|
								            rec_currency_symbol = ''
							 | 
						|
								            for record in model_data:
							 | 
						|
								                rec_currency_symbol = record.currency_id.symbol
							 | 
						|
								                data_list = []
							 | 
						|
								                list_b = []
							 | 
						|
								                order = rec.field_order.strip('][').split(', ')
							 | 
						|
								                for field_id in order:
							 | 
						|
								                    field_obj = self.env['ir.model.fields'].browse(
							 | 
						|
								                        int(field_id))
							 | 
						|
								                    field_name = field_obj.name
							 | 
						|
								                    if field_obj.ttype == 'datetime':
							 | 
						|
								                        field_data = record[field_name].strftime("%d/%m/%Y")
							 | 
						|
								                    elif field_obj.ttype == 'boolean':
							 | 
						|
								                        if not record[field_name]:
							 | 
						|
								                            field_data = "No"
							 | 
						|
								                        else:
							 | 
						|
								                            field_data = "Yes"
							 | 
						|
								                    elif field_obj.ttype == 'many2one' or field_obj.ttype == 'many2one_reference':
							 | 
						|
								                        if record[field_name]:
							 | 
						|
								                            field_data = record[field_name].name_get()[0][1]
							 | 
						|
								                        else:
							 | 
						|
								                            field_data = "Null"
							 | 
						|
								                    elif field_obj.ttype == 'many2many':
							 | 
						|
								                        if record[field_name]:
							 | 
						|
								                            field_data = ""
							 | 
						|
								                            for count, value in enumerate(record[field_name]):
							 | 
						|
								                                if not count == len(record[field_name]) - 1:
							 | 
						|
								                                    field_data += value.name_get()[0][1] + ", "
							 | 
						|
								                                else:
							 | 
						|
								                                    field_data += value.name_get()[0][1]
							 | 
						|
								                        else:
							 | 
						|
								                            field_data = "Null"
							 | 
						|
								                    elif field_obj.ttype == 'one2many':
							 | 
						|
								                        if record[field_name]:
							 | 
						|
								                            child_fields = rec.fields_ids.one2many_model_field_ids
							 | 
						|
								                            if child_fields:
							 | 
						|
								                                field_data = "one2many"
							 | 
						|
								                                list_b = []
							 | 
						|
								                                for o2m_c_field in record[field_name]:
							 | 
						|
								                                    list_a = []
							 | 
						|
								                                    for c_field in child_fields:
							 | 
						|
								                                        c_field_name = c_field.name
							 | 
						|
								                                        if c_field.ttype == 'datetime':
							 | 
						|
								                                            child_field_data = o2m_c_field[
							 | 
						|
								                                                c_field_name].strftime(
							 | 
						|
								                                                "%d/%m/%Y")
							 | 
						|
								                                        elif c_field.ttype == 'boolean':
							 | 
						|
								                                            if o2m_c_field[c_field_name]:
							 | 
						|
								                                                child_field_data = "Yes"
							 | 
						|
								                                            else:
							 | 
						|
								                                                child_field_data = "No"
							 | 
						|
								                                        elif c_field.ttype in (
							 | 
						|
								                                                'many2one',
							 | 
						|
								                                                'many2one_reference'):
							 | 
						|
								                                            if o2m_c_field[c_field_name]:
							 | 
						|
								                                                child_field_data = o2m_c_field[
							 | 
						|
								                                                    c_field_name].name_get()[0][
							 | 
						|
								                                                    1]
							 | 
						|
								                                            else:
							 | 
						|
								                                                child_field_data = "Null"
							 | 
						|
								                                        elif c_field.ttype in (
							 | 
						|
								                                                'many2one',
							 | 
						|
								                                                'many2one_reference'):
							 | 
						|
								                                            if o2m_c_field[c_field_name]:
							 | 
						|
								                                                child_field_data = o2m_c_field[
							 | 
						|
								                                                    c_field_name].name_get()[0][
							 | 
						|
								                                                    1]
							 | 
						|
								                                            else:
							 | 
						|
								                                                child_field_data = "Null"
							 | 
						|
								                                        elif c_field.ttype in (
							 | 
						|
								                                                'many2many', 'one2many'):
							 | 
						|
								                                            if o2m_c_field[c_field_name]:
							 | 
						|
								                                                child_field_data = ""
							 | 
						|
								                                                for c_count, c_value in enumerate(
							 | 
						|
								                                                        o2m_c_field[
							 | 
						|
								                                                            c_field_name]):
							 | 
						|
								                                                    if not c_count == len(
							 | 
						|
								                                                            o2m_c_field[
							 | 
						|
								                                                                c_field_name]) - 1:
							 | 
						|
								                                                        child_field_data += \
							 | 
						|
								                                                            c_value.name_get()[
							 | 
						|
								                                                                0][
							 | 
						|
								                                                                1] + ", "
							 | 
						|
								                                                    else:
							 | 
						|
								                                                        child_field_data += \
							 | 
						|
								                                                            c_value.name_get()[
							 | 
						|
								                                                                0][1]
							 | 
						|
								                                            else:
							 | 
						|
								                                                child_field_data = "Null"
							 | 
						|
								                                        else:
							 | 
						|
								                                            child_field_data = o2m_c_field[
							 | 
						|
								                                                c_field_name]
							 | 
						|
								                                        list_a.append(child_field_data)
							 | 
						|
								                                        field_data = list_a
							 | 
						|
								                                    list_b.append(list_a)
							 | 
						|
								                            else:
							 | 
						|
								                                field_data = ""
							 | 
						|
								                                for count, value in enumerate(
							 | 
						|
								                                        record[field_name]):
							 | 
						|
								                                    if not count == len(record[field_name]) - 1:
							 | 
						|
								                                        field_data += value.name_get()[0][
							 | 
						|
								                                                          1] + ", "
							 | 
						|
								                                    else:
							 | 
						|
								                                        field_data += value.name_get()[0][1]
							 | 
						|
								                        else:
							 | 
						|
								                            field_data = "Null"
							 | 
						|
								                    elif field_obj.ttype == 'monetary':
							 | 
						|
								                        if record.currency_id.position == 'before':
							 | 
						|
								                            field_data = record.currency_id.symbol+str(record[field_name])
							 | 
						|
								                        else:
							 | 
						|
								                            field_data = str(record[field_name])+record.currency_id.symbol
							 | 
						|
								                    else:
							 | 
						|
								                        field_data = record[field_name]
							 | 
						|
								                    data_list.append(field_data)
							 | 
						|
								                table_data.append(data_list)
							 | 
						|
								                child_table_data.append(list_b)
							 | 
						|
								            child_label = rec.fields_ids.one2many_model_field_ids
							 | 
						|
								            child_field_label = ""
							 | 
						|
								            if child_label:
							 | 
						|
								                child_field_label = child_label.mapped('field_description')
							 | 
						|
								            field_heading = {}
							 | 
						|
								            for field in rec.fields_ids.report_field_id:
							 | 
						|
								                field_heading.update({field.field_description: (
							 | 
						|
								                    field.ttype, field.field_description,rec_currency_symbol)})
							 | 
						|
								            ordered_field_heading = OrderedDict(
							 | 
						|
								               list(field_heading.items()))
							 | 
						|
								            data = {
							 | 
						|
								                'report_name': rec.name,
							 | 
						|
								                'model_name': rec.model_id.model,
							 | 
						|
								                'fields_name': rec.fields_ids.report_field_id.mapped('name'),
							 | 
						|
								                'field_label': ordered_field_heading,
							 | 
						|
								                'date_field_id': rec.date_field_id.name,
							 | 
						|
								                'date_name': rec.date_field_id.field_description,
							 | 
						|
								                'start_date': rec.start_date,
							 | 
						|
								                'end_date': rec.end_date,
							 | 
						|
								                'field_order': rec.field_order,
							 | 
						|
								                'table_data': table_data,
							 | 
						|
								                'child_field_data': child_table_data,
							 | 
						|
								                'child_field_label': child_field_label,
							 | 
						|
								                'today_date': fields.Datetime.now()
							 | 
						|
								            }
							 | 
						|
								            return self.env.ref(
							 | 
						|
								                'pdf_report_designer.action_report_print_pdf_designer').report_action(
							 | 
						|
								                self, data=data)
							 | 
						|
								
							 | 
						|
								    def action_unlink_action(self):
							 | 
						|
								        """
							 | 
						|
								        Unlink an action button and reload the view.
							 | 
						|
								        """
							 | 
						|
								        self.ensure_one()
							 | 
						|
								        if self.ir_act_server_ref_id:
							 | 
						|
								            # Remove the action window
							 | 
						|
								            self.ir_act_server_ref_id.unlink()
							 | 
						|
								            self.write({
							 | 
						|
								                'ir_act_server_ref_id': False,
							 | 
						|
								                'action_button': False
							 | 
						|
								            })
							 | 
						|
								        else:
							 | 
						|
								            self.action_button = False
							 | 
						|
								
							 | 
						|
								        return {
							 | 
						|
								            'type': 'ir.actions.client',
							 | 
						|
								            'tag': 'reload',
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def action_create_model(self):
							 | 
						|
								        """ Create a contextual action for each server action."""
							 | 
						|
								        self.action_button = True
							 | 
						|
								        windowaction = self.env['ir.actions.act_window']
							 | 
						|
								        data = self.env['ir.model.data']
							 | 
						|
								        for rec in self.browse(self._ids):
							 | 
						|
								            binding_model_id = rec.model_id.id
							 | 
						|
								            model_data_id = data._load_xmlid('pdf_report_designer')
							 | 
						|
								            res_id = data.browse(model_data_id).res_id
							 | 
						|
								            button_name = _('Print Report (%s)') % rec.name
							 | 
						|
								            act_id = windowaction.create({
							 | 
						|
								                'name': button_name,
							 | 
						|
								                'is_action_created_from_pdf_report':True,
							 | 
						|
								                'type': 'ir.actions.act_window',
							 | 
						|
								                'res_model': 'pdf.report',
							 | 
						|
								                'binding_model_id': binding_model_id,
							 | 
						|
								                'context': "{'pdf' : %d}" % rec.id,
							 | 
						|
								                'view_mode': 'form,tree',
							 | 
						|
								                'view_id': res_id,
							 | 
						|
								                'target': 'new',
							 | 
						|
								            })
							 | 
						|
								            rec.write({
							 | 
						|
								                'ir_act_server_ref_id': act_id.id,
							 | 
						|
								            })
							 | 
						|
								        return {
							 | 
						|
								            'type': 'ir.actions.client',
							 | 
						|
								            'tag': 'reload',
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    @api.onchange('fields_ids')
							 | 
						|
								    def _onchange_fields_ids(self):
							 | 
						|
								        """
							 | 
						|
								        This method is used to create a list of selected fields ids
							 | 
						|
								        @param self: object pointer
							 | 
						|
								        """
							 | 
						|
								        self.fields_ids = []
							 | 
						|
								        if self.fields_ids:
							 | 
						|
								            self.field_order = str(self.fields_ids.report_field_id._origin.ids)
							 | 
						|
								
							 | 
						|
								    @api.onchange('model_id')
							 | 
						|
								    def _onchange_model_id(self):
							 | 
						|
								        """
							 | 
						|
								        This method is used to return domain on date_field_id on change of
							 | 
						|
								        model_id @param self: object pointer @return: returns a domain on
							 | 
						|
								        date_field_id field based on selected model id."""
							 | 
						|
								        if self.model_id:
							 | 
						|
								            self.fields_ids = False
							 | 
						|
								            self.date_field_id = False
							 | 
						|
								        return {
							 | 
						|
								            'domain': {
							 | 
						|
								                'date_field_id': [('model_id', '=', self.model_id),
							 | 
						|
								                                  ('ttype', 'in', ('date', 'datetime'))],
							 | 
						|
								            }
							 | 
						|
								        }
							 | 
						|
								
							 | 
						|
								    def unlink(self):
							 | 
						|
								        """ Regular unlink method, but make sure to clear the caches. """
							 | 
						|
								        for attachment in self:
							 | 
						|
								            action_rec = _('Print Report (%s)') % attachment.name
							 | 
						|
								            actions = self.env['ir.actions.act_window'].search(
							 | 
						|
								                [('name', '=', action_rec)])
							 | 
						|
								            actions.unlink()
							 | 
						|
								        super(ReportPDF, self).unlink()
							 | 
						|
								        return {
							 | 
						|
								            'type': 'ir.actions.client',
							 | 
						|
								            'tag': 'reload',
							 | 
						|
								        }
							 | 
						|
								
							 |