Example #1
0
class RequestGroup(models.Model):
    _name = "hc.res.request.group"
    _description = "Request Group"

    identifier_id = fields.Many2one(comodel_name="hc.request.group.identifier",
                                    string="Identifier",
                                    help="Business identifier.")
    subject_type = fields.Selection(
        string="Subject Type",
        selection=[("Patient", "Patient"), ("Group", "Group")],
        help="Type of subject of the request group.")
    subject_name = fields.Char(string="Subject",
                               compute="_compute_subject_name",
                               store="True",
                               help="Subject of the request group.")
    subject_patient_id = fields.Many2one(
        comodel_name="hc.res.patient",
        string="Subject Patient",
        help="Patient subject of the request group.")
    subject_group_id = fields.Many2one(
        comodel_name="hc.res.group",
        string="Subject Group",
        help="Group subject of the request group.")
    context_type = fields.Selection(
        string="Context Type",
        selection=[("Encounter", "Encounter"),
                   ("Episode Of Care", "Episode Of Care")],
        help="Type of Encounter or Episode for the request group.")
    context_name = fields.Char(
        string="Context",
        compute="_compute_context_name",
        store="True",
        help="Encounter or Episode for the request group.")
    context_encounter_id = fields.Many2one(
        comodel_name="hc.res.encounter",
        string="Context Encounter",
        help="Encounter for the request group.")
    context_episode_of_care_id = fields.Many2one(
        comodel_name="hc.res.episode.of.care",
        string="Context Episode Of Care",
        help="Episode Of Care for the request group.")
    occurrence_date_time = fields.Datetime(
        string="Occurrence Date Time",
        help="When the request group was authored.")
    author_type = fields.Selection(
        string="Author Type",
        selection=[("Device", "Device"), ("Practitioner", "Practitioner")],
        help="Type of device or practitioner that authored the request group.")
    author_name = fields.Char(
        string="Author",
        compute="_compute_author_name",
        store="True",
        help="Device or practitioner that authored the request group.")
    author_device_id = fields.Many2one(
        comodel_name="hc.res.device",
        string="Author Device",
        help="Device that authored the request group.")
    author_practitioner_id = fields.Many2one(
        comodel_name="hc.res.practitioner",
        string="Author Practitioner",
        help="Practitioner that authored the request group.")
    reason_type = fields.Selection(
        string="Reason Type",
        selection=[("code", "Code"), ("string", "String"),
                   ("Resource Type", "Resource Type")],
        help="Type of reason for the request group.")
    reason_name = fields.Char(string="Reason",
                              compute="_compute_reason_name",
                              store="True",
                              help="Reason for the request group.")
    reason_code_id = fields.Many2one(
        comodel_name="hc.vs.request.group.reason",
        string="Reason Code",
        help="Code of reason for the request group.")
    reason_string = fields.Char(string="Reason String",
                                help="String of reason for the request group.")
    reason_resource_id = fields.Many2one(
        comodel_name="hc.vs.resource.type",
        string="Reason Resource",
        help="Resource type of reason for the request group.")
    note_ids = fields.One2many(comodel_name="hc.request.group.note",
                               inverse_name="request_group_id",
                               string="Notes",
                               help="Additional notes about the response.")
    action_ids = fields.One2many(comodel_name="hc.request.group.action",
                                 inverse_name="request_group_id",
                                 string="Actions",
                                 help="Proposed actions, if any.")
Example #2
0
File: event.py Project: orgis/odoo
class event_event(models.Model):
    """Event"""
    _name = 'event.event'
    _description = 'Event'
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _order = 'date_begin'

    name = fields.Char(string='Event Name',
                       translate=True,
                       required=True,
                       readonly=False,
                       states={'done': [('readonly', True)]})
    active = fields.Boolean(default=True, track_visibility="onchange")
    user_id = fields.Many2one('res.users',
                              string='Responsible',
                              default=lambda self: self.env.user,
                              readonly=False,
                              states={'done': [('readonly', True)]})
    company_id = fields.Many2one('res.company',
                                 string='Company',
                                 change_default=True,
                                 default=lambda self: self.env['res.company'].
                                 _company_default_get('event.event'),
                                 required=False,
                                 readonly=False,
                                 states={'done': [('readonly', True)]})
    organizer_id = fields.Many2one(
        'res.partner',
        string='Organizer',
        default=lambda self: self.env.user.company_id.partner_id)
    event_type_id = fields.Many2one('event.type',
                                    string='Category',
                                    readonly=False,
                                    states={'done': [('readonly', True)]},
                                    oldname='type')
    color = fields.Integer('Kanban Color Index')
    event_mail_ids = fields.One2many(
        'event.mail',
        'event_id',
        string='Mail Schedule',
        default=lambda self: self._default_event_mail_ids(),
        copy=True)

    @api.model
    def _default_event_mail_ids(self):
        return [(0, 0, {
            'interval_unit': 'now',
            'interval_type': 'after_sub',
            'template_id': self.env.ref('event.event_subscription')
        })]

    # Seats and computation
    seats_max = fields.Integer(
        string='Maximum Attendees Number',
        oldname='register_max',
        readonly=True,
        states={
            'draft': [('readonly', False)],
            'confirm': [('readonly', False)]
        },
        help=
        "For each event you can define a maximum registration of seats(number of attendees), above this numbers the registrations are not accepted."
    )
    seats_availability = fields.Selection([('limited', 'Limited'),
                                           ('unlimited', 'Unlimited')],
                                          'Maximum Attendees',
                                          required=True,
                                          default='unlimited')
    seats_min = fields.Integer(
        string='Minimum Attendees',
        oldname='register_min',
        help=
        "For each event you can define a minimum reserved seats (number of attendees), if it does not reach the mentioned registrations the event can not be confirmed (keep 0 to ignore this rule)"
    )
    seats_reserved = fields.Integer(oldname='register_current',
                                    string='Reserved Seats',
                                    store=True,
                                    readonly=True,
                                    compute='_compute_seats')
    seats_available = fields.Integer(oldname='register_avail',
                                     string='Maximum Attendees',
                                     store=True,
                                     readonly=True,
                                     compute='_compute_seats')
    seats_unconfirmed = fields.Integer(oldname='register_prospect',
                                       string='Unconfirmed Seat Reservations',
                                       store=True,
                                       readonly=True,
                                       compute='_compute_seats')
    seats_used = fields.Integer(oldname='register_attended',
                                string='Number of Participants',
                                store=True,
                                readonly=True,
                                compute='_compute_seats')
    seats_expected = fields.Integer(string='Number of Expected Attendees',
                                    readonly=True,
                                    compute='_compute_seats')

    @api.multi
    @api.depends('seats_max', 'registration_ids.state')
    def _compute_seats(self):
        """ Determine reserved, available, reserved but unconfirmed and used seats. """
        # initialize fields to 0
        for event in self:
            event.seats_unconfirmed = event.seats_reserved = event.seats_used = event.seats_available = 0
        # aggregate registrations by event and by state
        if self.ids:
            state_field = {
                'draft': 'seats_unconfirmed',
                'open': 'seats_reserved',
                'done': 'seats_used',
            }
            query = """ SELECT event_id, state, count(event_id)
                        FROM event_registration
                        WHERE event_id IN %s AND state IN ('draft', 'open', 'done')
                        GROUP BY event_id, state
                    """
            self._cr.execute(query, (tuple(self.ids), ))
            for event_id, state, num in self._cr.fetchall():
                event = self.browse(event_id)
                event[state_field[state]] += num
        # compute seats_available
        for event in self:
            if event.seats_max > 0:
                event.seats_available = event.seats_max - (
                    event.seats_reserved + event.seats_used)
            event.seats_expected = event.seats_unconfirmed + event.seats_reserved + event.seats_used

    # Registration fields
    registration_ids = fields.One2many('event.registration',
                                       'event_id',
                                       string='Attendees',
                                       readonly=False,
                                       states={'done': [('readonly', True)]})
    # Date fields
    date_tz = fields.Selection('_tz_get',
                               string='Timezone',
                               required=True,
                               default=lambda self: self.env.user.tz)
    date_begin = fields.Datetime(string='Start Date',
                                 required=True,
                                 track_visibility='onchange',
                                 states={'done': [('readonly', True)]})
    date_end = fields.Datetime(string='End Date',
                               required=True,
                               track_visibility='onchange',
                               states={'done': [('readonly', True)]})
    date_begin_located = fields.Datetime(string='Start Date Located',
                                         compute='_compute_date_begin_tz')
    date_end_located = fields.Datetime(string='End Date Located',
                                       compute='_compute_date_end_tz')

    @api.model
    def _tz_get(self):
        return [(x, x) for x in pytz.all_timezones]

    @api.one
    @api.depends('date_tz', 'date_begin')
    def _compute_date_begin_tz(self):
        if self.date_begin:
            self_in_tz = self.with_context(tz=(self.date_tz or 'UTC'))
            date_begin = fields.Datetime.from_string(self.date_begin)
            self.date_begin_located = fields.Datetime.to_string(
                fields.Datetime.context_timestamp(self_in_tz, date_begin))
        else:
            self.date_begin_located = False

    @api.one
    @api.depends('date_tz', 'date_end')
    def _compute_date_end_tz(self):
        if self.date_end:
            self_in_tz = self.with_context(tz=(self.date_tz or 'UTC'))
            date_end = fields.Datetime.from_string(self.date_end)
            self.date_end_located = fields.Datetime.to_string(
                fields.Datetime.context_timestamp(self_in_tz, date_end))
        else:
            self.date_end_located = False

    state = fields.Selection(
        [('draft', 'Unconfirmed'), ('cancel', 'Cancelled'),
         ('confirm', 'Confirmed'), ('done', 'Done')],
        string='Status',
        default='draft',
        readonly=True,
        required=True,
        copy=False,
        help=
        "If event is created, the status is 'Draft'. If event is confirmed for the particular dates the status is set to 'Confirmed'. If the event is over, the status is set to 'Done'. If event is cancelled the status is set to 'Cancelled'."
    )
    auto_confirm = fields.Boolean(string='Confirmation not required',
                                  compute='_compute_auto_confirm')

    @api.one
    def _compute_auto_confirm(self):
        self.auto_confirm = self.env['ir.values'].get_default(
            'event.config.settings', 'auto_confirmation')

    reply_to = fields.Char(
        'Reply-To Email',
        readonly=False,
        states={'done': [('readonly', True)]},
        help=
        "The email address of the organizer is likely to be put here, with the effect to be in the 'Reply-To' of the mails sent automatically at event or registrations confirmation. You can also put the email address of your mail gateway if you use one."
    )
    address_id = fields.Many2one(
        'res.partner',
        string='Location',
        default=lambda self: self.env.user.company_id.partner_id,
        readonly=False,
        states={'done': [('readonly', True)]})
    country_id = fields.Many2one('res.country',
                                 'Country',
                                 related='address_id.country_id',
                                 store=True)
    description = fields.Html(string='Description',
                              oldname='note',
                              translate=True,
                              readonly=False,
                              states={'done': [('readonly', True)]})
    # badge fields
    badge_front = fields.Html(string='Badge Front')
    badge_back = fields.Html(string='Badge Back')
    badge_innerleft = fields.Html(string='Badge Inner Left')
    badge_innerright = fields.Html(string='Badge Inner Right')
    event_logo = fields.Html(string='Event Logo')

    @api.multi
    @api.depends('name', 'date_begin', 'date_end')
    def name_get(self):
        result = []
        for event in self:
            date_begin = fields.Datetime.from_string(event.date_begin)
            date_end = fields.Datetime.from_string(event.date_end)
            dates = [
                fields.Date.to_string(
                    fields.Datetime.context_timestamp(event, dt))
                for dt in [date_begin, date_end] if dt
            ]
            dates = sorted(set(dates))
            result.append(
                (event.id, '%s (%s)' % (event.name, ' - '.join(dates))))
        return result

    @api.one
    @api.constrains('seats_max', 'seats_available')
    def _check_seats_limit(self):
        if self.seats_availability == 'limited' and self.seats_max and self.seats_available < 0:
            raise ValidationError(_('No more available seats.'))

    @api.one
    @api.constrains('date_begin', 'date_end')
    def _check_closing_date(self):
        if self.date_end < self.date_begin:
            raise ValidationError(
                _('Closing Date cannot be set before Beginning Date.'))

    @api.model
    def create(self, vals):
        res = super(event_event, self).create(vals)
        if res.organizer_id:
            res.message_subscribe([res.organizer_id.id])
        if res.auto_confirm:
            res.button_confirm()
        return res

    @api.multi
    def write(self, vals):
        res = super(event_event, self).write(vals)
        if vals.get('organizer_id'):
            self.message_subscribe([vals['organizer_id']])
        return res

    @api.one
    def button_draft(self):
        self.state = 'draft'

    @api.one
    def button_cancel(self):
        for event_reg in self.registration_ids:
            if event_reg.state == 'done':
                raise UserError(
                    _("You have already set a registration for this event as 'Attended'. Please reset it to draft if you want to cancel this event."
                      ))
        self.registration_ids.write({'state': 'cancel'})
        self.state = 'cancel'

    @api.one
    def button_done(self):
        self.state = 'done'

    @api.one
    def button_confirm(self):
        self.state = 'confirm'

    @api.onchange('event_type_id')
    def _onchange_type(self):
        if self.event_type_id:
            self.seats_min = self.event_type_id.default_registration_min
            self.seats_max = self.event_type_id.default_registration_max
            self.reply_to = self.event_type_id.default_reply_to

    @api.multi
    def action_event_registration_report(self):
        res = self.env['ir.actions.act_window'].for_xml_id(
            'event', 'action_report_event_registration')
        res['context'] = {
            "search_default_event_id": self.id,
            "group_by": ['create_date:day'],
        }
        return res

    @api.one
    def mail_attendees(self,
                       template_id,
                       force_send=False,
                       filter_func=lambda self: True):
        for attendee in self.registration_ids.filtered(filter_func):
            self.env['mail.template'].browse(template_id).send_mail(
                attendee.id, force_send=force_send)
class website_url_tracker(models.Model):
    _name = 'website.url.tracker'

    timestamp = fields.Datetime(string='Time Stamp')
    user_id = fields.Many2one(comodel_name='res.users', string='Visitor')
    partner_id = fields.Many2one(comodel_name='res.partner', string='Partner')
Example #4
0
class HrEmployeeFiscal(models.Model):
    _name = 'hr.employee.fiscal'
    _order = 'date_from desc'

    @api.one
    def _compute_create_user(self):
        self.user_create = "%s:%s" % (self.create_uid.login.split(
            '@')[0], datetime.strptime(
                self.create_date,
                '%Y-%m-%d %H:%M:%S').strftime('%d-%m-%Y-%H:%M:%S'))

    @api.one
    def _compute_last_user(self):
        self.user_last = "%s:%s" % (self.write_uid.login.split(
            '@')[0], datetime.strptime(
                self.write_date,
                '%Y-%m-%d %H:%M:%S').strftime('%d-%m-%Y %H:%M:%S'))

    user_create = fields.Char(compute='_compute_create_user',
                              string='Creado',
                              readonly=True,
                              size=68,
                              store=False)
    user_last = fields.Char(compute='_compute_last_user',
                            string='Modificado',
                            readonly=True,
                            size=68,
                            store=False)
    employee_id = fields.Many2one('hr.employee', 'Empleado', required=False)
    # TODO: poner company_id, obtener company
    company_id = fields.Many2one(related='employee_id.company_id',
                                 string='Compañia',
                                 required=False)

    date_from = fields.Date('Inicio',
                            default=datetime.today().strftime('%Y-%m-01'),
                            required=True,
                            readonly=False)
    date_to = fields.Date('Termino',
                          default=datetime.today().strftime('%Y-%m-30'),
                          required=True,
                          readonly=False)

    country_id = fields.Many2one('res.country',
                                 related='employee_id.country_id',
                                 string="Nacionalidad (País)",
                                 readonly=True,
                                 store=True)

    #home_state_id = fields.Char(related='employee_id.home_state_id.name', string='Provincia', readonly=True, store=False)
    date_irpf = fields.Datetime('Fecha Calculo', required=False, readonly=True)
    modif_id = fields.Many2one('hr.employee.fiscal.modif',
                               'Modificador IRPF',
                               required=True)
    key_id = fields.Many2one('hr.employee.fiscal.key',
                             'Clave percepcion',
                             required=True)
    marital = fields.Selection(related='employee_id.marital',
                               string="Estado civil",
                               readonly=True,
                               store=False)
    situation = fields.Selection([
        ('1', 'Monoparental'),
        ('2', 'Con conyuge a cargo'),
        ('3', 'Otras situacion'),
    ],
                                 string='Situacion familiar',
                                 default='',
                                 required=True,
                                 readonly=False)
    conyuge_nif = fields.Char(
        string="DNI/NIF Conyuge",
        size=12,
        required=False,
    )
    minus = fields.Selection([
        ('0', 'Sin Minusvalia'),
        ('3', 'Igual/Superior a 33% e inferior 65%'),
        ('A', 'Entre 33% y 65%, con asistencia'),
        ('6', 'Igual/Superior a 65%'),
        ('B', 'Igual/Superior a 65%, con asistencia'),
    ],
                             string='Minusvalia',
                             default='0',
                             required=False)

    geo_move = fields.Selection([
        ('S', 'Si'),
        ('N', 'No'),
    ],
                                string='Movilidad geografica',
                                default='N',
                                required=False)
    geo_date = fields.Date(
        string="Fecha Movilidad",
        required=False,
    )

    loan = fields.Selection([
        ('S', 'Si'),
        ('N', 'No'),
    ],
                            string='Prestamo vivienda',
                            default='N',
                            required=False)
Example #5
0
class contract_service_deactivate(models.TransientModel):

    _name = 'contract.service.deactivate'

    @api.model
    def default_get(self, fields):
        res = super(contract_service_deactivate, self).default_get(fields)
        if self._context.get('active_model', '') == 'contract.service':
            active_id = self._context.get('active_id')
            contract_service = self.env['contract.service'].browse(active_id)
            res.update({
                'account_id': contract_service.account_id.id,
                'service_id': contract_service.id
            })
        return res

    deactivation_date = fields.Datetime('Deactivation Date',
                                        default=fields.datetime.now())
    account_id = fields.Many2one('account.analytic.account', 'Account')
    service_id = fields.Many2one('contract.service', 'Service')

    @api.multi
    def deactivate(self):
        context = self._context or {}
        context = dict(context)
        contract_service_obj = self.env['contract.service']
        context.update({'deactivation_date': self.deactivation_date})
        contract_service_obj.action_desactivate([self.service_id.id],
                                                context=context)
        # If we activate again, we will need a new activation line, as
        # we will have refunded any extra, and will need to bill in
        # advance again.
        self.service_id.write({'activation_line_generated': False})
        self._create_refund_lines()
        return True

    @api.multi
    def _create_refund_lines(self):
        contract_service_obj = self.env['contract.service']
        deactivate_date = datetime.datetime.strptime(
            self.deactivation_date,
            DEFAULT_SERVER_DATETIME_FORMAT,
        ).date()
        contract_service_obj.create_refund_line([self.service_id.id],
                                                mode='prorata',
                                                date=deactivate_date)

    @api.constrains('deactivation_date')
    def _check_future_date(self):
        today = datetime.datetime.utcnow().date()
        for wiz in self:
            act_date = datetime.datetime.strptime(
                wiz.deactivation_date,
                DEFAULT_SERVER_DATETIME_FORMAT,
            ).date()
            if act_date > today:
                raise Warning(
                    _('You cannot deactivate a '
                      'service in the future.'))
                return False
        return True
Example #6
0
class rbs_documento_mercantil_vehiculo(models.Model):
    _name = "rbs.documento.mercantil.vehiculo"
    _description = "Documento Mercantil Vehiculo"
    #name= field.Char('Nombre')
    anio_id = fields.Many2one('rbs.archivo.anio', string='Año', required=True)
    libro_id = fields.Many2one('rbs.archivo.libro',
                               string='Libro',
                               required=True)
    tomo_id = fields.Many2one("rbs.archivo.tomo", string='Tomo', required=True)

    persona_id = fields.Many2one('rbs.persona', string='Compareciente(n)')
    persona_nombres = fields.Char(string='Nombres del Compareciente')
    persona_apellidos = fields.Char(string='Apellidos del Compareciente')
    persona_cedula = fields.Char(string='Cedula del Compareciente')
    persona_representante = fields.Char(
        string='Representante del Compareciente')
    persona_razonSocial = fields.Char(string='Razon Social del Compareciente')

    tipo_compareciente_id = fields.Many2one('rbs.tipo.compareciente.v',
                                            string='Tipo de Compareciente')
    tipo_contrato_id = fields.Many2one('rbs.tipo.contrato',
                                       string='Tipo de Contrato',
                                       required=True)

    fecha_inscripcion = fields.Datetime(string='Fecha de Inscripcion',
                                        required=True)
    numero_inscripcion = fields.Char(string='Numero de Inscripcion',
                                     required=True)
    fecha_cancelacion = fields.Datetime(string='Fecha de Cancelacion')
    tipo_bien_id = fields.Many2one('rbs.tipo.bien',
                                   string='Tipo de Bien',
                                   required=True)
    chasis = fields.Char(string='Chasis')
    motor = fields.Char(string='Motor')
    marca = fields.Char(string='Marca')
    modelo = fields.Char(string='Modelo')
    anio_fabricacion = fields.Char(string='Año de Fabricacion')
    placa = fields.Char(string='Placa')
    ultima_modificacion = fields.Char(string='Ultima Modificacion')
    nombre_institucion = fields.Char(string='Nombre de la Institucion',
                                     required=True)
    canton_notaria = fields.Char(string='Canton de Notaria', required=True)
    fecha_escritura_contrato = fields.Datetime(string='Fecha de Escritura',
                                               required=True)

    estado = fields.Selection([
        ('VIGENTE', 'VIGENTE'),
        ('NOVIGENTE', 'NO VIGENTE'),
    ],
                              string='Estado',
                              required=True)
    #filedata = fields.Binary('Archivo',filters='*.pdf')
    #filename = fields.Char('Nombre de archivo', default="Archivo.pdf")
    filedata_id = fields.Many2one('rbs.archivo.pdf')
    filedata = fields.Binary(related='filedata_id.filedata', filters='*.pdf')
    esPesado = fields.Boolean(related='filedata_id.esPesado',
                              string='¿Es Pesado?')
    rutaFTP = fields.Char(related='filedata_id.rutaFTP',
                          string='Escriba la ruta del Archivo')

    identificacion_unica = fields.Char(
        string='Identificador Unico Sistema Remoto',
        compute='_compute_upper',
        store=True)
    ubicacion_dato_id = fields.Many2one('rbs.ubicacion.dato',
                                        string='Ubicacion del Dato',
                                        required=True)

    def _getUltimoAnio(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.vehiculo").search(
            cr, uid, [], limit=1, order='id desc')
        anio = self.pool.get("rbs.documento.mercantil.vehiculo").browse(
            cr, uid, acta_id, context=None).anio_id.id
        return anio

    def _getUltimoLibro(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.vehiculo").search(
            cr, uid, [], limit=1, order='id desc')
        libro = self.pool.get("rbs.documento.mercantil.vehiculo").browse(
            cr, uid, acta_id, context=None).libro_id.id
        return libro

    def _getUltimoTomo(self, cr, uid, context=None):
        acta_id = self.pool.get("rbs.documento.mercantil.vehiculo").search(
            cr, uid, [], limit=1, order='id desc')
        tomo = self.pool.get("rbs.documento.mercantil.vehiculo").browse(
            cr, uid, acta_id, context=None).tomo_id.id
        return tomo

    def _create_pdf(self, cr, uid, context=None):
        return self.pool.get("rbs.archivo.pdf").create(cr,
                                                       uid, {},
                                                       context=None)

    _defaults = {
        'anio_id': _getUltimoAnio,
        'libro_id': _getUltimoLibro,
        'tomo_id': _getUltimoTomo,
        'filedata_id': _create_pdf,
    }

    _rec_name = 'numero_inscripcion'

    @api.depends('ubicacion_dato_id', 'persona_cedula', 'numero_inscripcion')
    def _compute_upper(self):
        for rec in self:
            try:
                rec.identificacion_unica = '03' + rec.ubicacion_dato_id.name + rec.persona_cedula + rec.numero_inscripcion
            except:
                try:
                    rec.identificacion_unica = '03' + rec.ubicacion_dato_id.name + rec.numero_inscripcion + rec.numero_inscripcion
                except:
                    pass

    def on_change_anio_id(self, cr, uid, ids, anio_id, context=None):
        result = {}
        if (self._getUltimoAnio(cr, uid, context=None) != anio_id):
            result['libro_id'] = 0
        return {
            'value': result,
        }

    def on_change_libro_id(self, cr, uid, ids, libro_id, context=None):
        result = {}
        if (self._getUltimoLibro(cr, uid, context=None) != libro_id):
            result['tomo_id'] = 0
        return {
            'value': result,
        }

    def codigoascii(self, text):
        return unicode(text).encode('utf-8')

    def onchange_persona_id(self, cr, uid, ids, persona_id, context=None):
        persona_id = self.pool.get('rbs.persona').search(
            cr, uid, [
                ('id', '=', persona_id),
            ])
        persona = self.pool.get('rbs.persona').browse(cr,
                                                      uid,
                                                      persona_id,
                                                      context=None)
        result = {}

        try:

            if persona:
                #raise osv.except_osv('Esto es un Mesaje!',establecimiento)
                try:
                    if persona.persona_nombres:
                        result['persona_nombres'] = self.codigoascii(
                            persona.persona_nombres)
                except:
                    pass

                try:
                    if persona.persona_apellidos:
                        result['persona_apellidos'] = self.codigoascii(
                            persona.persona_apellidos)
                except:
                    pass
                try:
                    if persona.name:
                        result['persona_cedula'] = str(persona.name)
                except:
                    pass
                try:
                    if persona.persona_representante:
                        result['persona_representante'] = self.codigoascii(
                            persona.persona_representante)
                except:
                    pass
                try:
                    if persona.persona_razonSocial:
                        result['persona_razonSocial'] = self.codigoascii(
                            persona.persona_razonSocial)
                except:
                    pass
        except:
            pass

        return {
            'value': result,
        }

    def onchange_inscripcion(self,
                             cr,
                             uid,
                             ids,
                             inscripcion_num,
                             libro_id,
                             context=None):
        vehiculo_id = self.pool.get('rbs.documento.mercantil.vehiculo').search(
            cr, uid, [('numero_inscripcion', '=', inscripcion_num),
                      ('libro_id', '=', libro_id)])
        vehiculo = self.pool.get('rbs.documento.mercantil.vehiculo').browse(
            cr, uid, vehiculo_id, context=None)
        result = {}

        try:

            if vehiculo:
                vehiculo = vehiculo[0]
                #raise osv.except_osv('Esto es un Mesaje!',establecimiento)
                try:
                    if vehiculo.fecha_inscripcion:
                        result['fecha_inscripcion'] = str(
                            vehiculo.fecha_inscripcion)

                except:
                    pass
                try:
                    if vehiculo.anio_id:
                        result['anio_id'] = vehiculo.anio_id.id

                except:
                    pass
                try:
                    if vehiculo.libro_id:
                        result['libro_id'] = vehiculo.libro_id.id

                except:
                    pass
                try:
                    if vehiculo.tomo_id:
                        result['tomo_id'] = vehiculo.tomo_id.id

                except:
                    pass
                try:
                    if vehiculo.tipo_contrato_id:
                        result[
                            'tipo_contrato_id'] = vehiculo.tipo_contrato_id.id

                except:
                    pass

                try:
                    if vehiculo.fecha_cancelacion:
                        result['fecha_cancelacion'] = str(
                            vehiculo.fecha_cancelacion)

                except:
                    pass
                try:
                    if vehiculo.tipo_bien_id:
                        result['tipo_bien_id'] = vehiculo.tipo_bien_id

                except:
                    pass

                try:
                    if vehiculo.chasis:
                        result['chasis'] = self.codigoascii(vehiculo.chasis)

                except:
                    pass

                try:
                    if vehiculo.motor:
                        result['motor'] = self.codigoascii(vehiculo.motor)

                except:
                    pass

                try:
                    if vehiculo.marca:
                        result['marca'] = self.codigoascii(vehiculo.marca)

                except:
                    pass

                try:
                    if vehiculo.modelo:
                        result['modelo'] = self.codigoascii(vehiculo.modelo)

                except:
                    pass

                try:
                    if vehiculo.anio_fabricacion:
                        result['anio_fabricacion'] = str(
                            vehiculo.anio_fabricacion)

                except:
                    pass

                try:
                    if vehiculo.placa:
                        result['placa'] = self.codigoascii(vehiculo.placa)

                except:
                    pass

                try:
                    if vehiculo.ultima_modificacion:
                        result['ultima_modificacion'] = str(
                            vehiculo.ultima_modificacion)

                except:
                    pass
                try:
                    if vehiculo.nombre_institucion:
                        result['nombre_institucion'] = self.codigoascii(
                            vehiculo.nombre_institucion)

                except:
                    pass
                try:
                    if vehiculo.canton_notaria:
                        result['canton_notaria'] = self.codigoascii(
                            vehiculo.canton_notaria)

                except:
                    pass
                try:
                    if vehiculo.fecha_escritura_contrato:
                        result['fecha_escritura_contrato'] = str(
                            vehiculo.fecha_escritura_contrato)

                except:
                    pass

                try:
                    if vehiculo.estado:
                        result['estado'] = vehiculo.estado

                except:
                    pass

                try:
                    if vehiculo.filedata_id:
                        result['filedata_id'] = vehiculo.filedata_id.id

                except:
                    pass

                try:
                    if vehiculo.ubicacion_dato_id:
                        result[
                            'ubicacion_dato_id'] = vehiculo.ubicacion_dato_id.id

                except:
                    pass

            if not vehiculo:
                result['filedata_id'] = self._create_pdf(cr, uid, context=None)
        except:
            pass

        return {
            'value': result,
        }
Example #7
0
class event_track(models.Model):
    _name = "event.track"
    _description = 'Event Track'
    _order = 'priority, date'
    _inherit = ['mail.thread', 'ir.needaction_mixin', 'website.seo.metadata', 'website.published.mixin']

    name = fields.Char('Title', required=True, translate=True)

    user_id = fields.Many2one('res.users', 'Responsible', track_visibility='onchange', default=lambda self: self.env.user)
    speaker_ids = fields.Many2many('res.partner', string='Speakers')
    tag_ids = fields.Many2many('event.track.tag', string='Tags')
    state = fields.Selection([
        ('draft', 'Proposal'), ('confirmed', 'Confirmed'), ('announced', 'Announced'), ('published', 'Published'), ('refused', 'Refused')],
        'Status', default='draft', required=True, copy=False, track_visibility='onchange')
    description = fields.Html('Track Description', translate=True)
    date = fields.Datetime('Track Date')
    duration = fields.Float('Duration', digits=(16, 2), default=1.5)
    location_id = fields.Many2one('event.track.location', 'Room')
    event_id = fields.Many2one('event.event', 'Event', required=True)
    color = fields.Integer('Color Index')
    priority = fields.Selection([
        ('0', 'Low'), ('1', 'Medium'),
        ('2', 'High'), ('3', 'Highest')],
        'Priority', required=True, default='1')
    image = fields.Binary('Image', compute='_compute_image', readonly=True, store=True)

    @api.one
    @api.depends('speaker_ids.image')
    def _compute_image(self):
        if self.speaker_ids:
            self.image = self.speaker_ids[0].image
        else:
            self.image = False

    @api.model
    def create(self, vals):
        res = super(event_track, self).create(vals)
        res.message_subscribe(res.speaker_ids.ids)
        return res

    @api.multi
    def write(self, vals):
        res = super(event_track, self).write(vals)
        if vals.get('speaker_ids'):
            self.message_subscribe([speaker['id'] for speaker in self.resolve_2many_commands('speaker_ids', vals['speaker_ids'], ['id'])])
        return res

    @api.multi
    @api.depends('name')
    def _website_url(self, field_name, arg):
        res = super(event_track, self)._website_url(field_name, arg)
        res.update({(track.id, '/event/%s/track/%s' % (slug(track.event_id), slug(track))) for track in self})
        return res

    def read_group(self, cr, uid, domain, fields, groupby, offset=0, limit=None, context=None, orderby=False, lazy=True):
        """ Override read_group to always display all states. """
        if groupby and groupby[0] == "state":
            # Default result structure
            # states = self._get_state_list(cr, uid, context=context)
            states = [('draft', 'Proposal'), ('confirmed', 'Confirmed'), ('announced', 'Announced'), ('published', 'Published')]
            read_group_all_states = [{
                '__context': {'group_by': groupby[1:]},
                '__domain': domain + [('state', '=', state_value)],
                'state': state_value,
                'state_count': 0,
            } for state_value, state_name in states]
            # Get standard results
            read_group_res = super(event_track, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)
            # Update standard results with default results
            result = []
            for state_value, state_name in states:
                res = filter(lambda x: x['state'] == state_value, read_group_res)
                if not res:
                    res = filter(lambda x: x['state'] == state_value, read_group_all_states)
                res[0]['state'] = [state_value, state_name]
                result.append(res[0])
            return result
        else:
            return super(event_track, self).read_group(cr, uid, domain, fields, groupby, offset=offset, limit=limit, context=context, orderby=orderby)

    def open_track_speakers_list(self, cr, uid, track_id, context=None):
        track_id = self.browse(cr, uid, track_id, context=context)
        return {
            'name': _('Speakers'),
            'domain': [('id', 'in', [partner.id for partner in track_id.speaker_ids])],
            'view_type': 'form',
            'view_mode': 'kanban,form',
            'res_model': 'res.partner',
            'view_id': False,
            'type': 'ir.actions.act_window',
        }
Example #8
0
class AccountAccount(models.Model):
    _name = "account.account"
    _description = "Account"
    _order = "code"

    #@api.multi
    #def _compute_has_unreconciled_entries(self):
    #    print "ici dedans"
    #    account_ids = self.ids
    #    for account in self:
    #        # Avoid useless work if has_unreconciled_entries is not relevant for this account
    #        if account.deprecated or not account.reconcile:
    #            account.has_unreconciled_entries = False
    #            account_ids = account_ids - account
    #    if account_ids:
    #        res = dict.fromkeys([x.id for x in account_ids], False)
    #        self.env.cr.execute(
    #            """ SELECT s.account_id FROM(
    #                    SELECT
    #                        a.id as account_id, a.last_time_entries_checked AS last_time_entries_checked,
    #                        MAX(l.write_date) AS max_date
    #                    FROM
    #                        account_move_line l
    #                        RIGHT JOIN account_account a ON (a.id = l.account_id)
    #                    WHERE
    #                        a.id in %s
    #                        AND EXISTS (
    #                            SELECT 1
    #                            FROM account_move_line l
    #                            WHERE l.account_id = a.id
    #                            AND l.amount_residual > 0
    #                        )
    #                        AND EXISTS (
    #                            SELECT 1
    #                            FROM account_move_line l
    #                            WHERE l.account_id = a.id
    #                            AND l.amount_residual < 0
    #                        )
    #                    GROUP BY a.id, a.last_time_entries_checked
    #                ) as s
    #                WHERE (last_time_entries_checked IS NULL OR max_date > last_time_entries_checked)
    #            """ % (account_ids,))
    #        res.update(self.env.cr.dictfetchall())
    #        for account in self.browse(res.keys()):
    #            if res[account.id]:
    #                account.has_unreconciled_entries = True

    @api.multi
    @api.constrains('internal_type', 'reconcile')
    def _check_reconcile(self):
        for account in self:
            if account.internal_type in ('receivable', 'payable') and account.reconcile == False:
                raise ValueError(_('You cannot have a receivable/payable account that is not reconciliable. (account code: %s)') % account.code)

    name = fields.Char(required=True, index=True)
    currency_id = fields.Many2one('res.currency', string='Account Currency',
        help="Forces all moves for this account to have this account currency.")
    code = fields.Char(size=64, required=True, index=True)
    deprecated = fields.Boolean(index=True, default=False)
    user_type_id = fields.Many2one('account.account.type', string='Type', required=True, oldname="user_type", 
        help="Account Type is used for information purpose, to generate country-specific legal reports, and set the rules to close a fiscal year and generate opening entries.")
    internal_type = fields.Selection(related='user_type_id.type', store=True, readonly=True)
    #has_unreconciled_entries = fields.Boolean(compute='_compute_has_unreconciled_entries',
    #    help="The account has at least one unreconciled debit and credit since last time the invoices & payments matching was performed.")
    last_time_entries_checked = fields.Datetime(string='Latest Invoices & Payments Matching Date', readonly=True, copy=False,
        help='Last time the invoices & payments matching was performed on this account. It is set either if there\'s not at least '\
        'an unreconciled debit and an unreconciled credit Or if you click the "Done" button.')
    reconcile = fields.Boolean(string='Allow Reconciliation', default=False,
        help="Check this box if this account allows invoices & payments matching of journal items.")
    tax_ids = fields.Many2many('account.tax', 'account_account_tax_default_rel',
        'account_id', 'tax_id', string='Default Taxes')
    note = fields.Text('Internal Notes')
    company_id = fields.Many2one('res.company', string='Company', required=True,
        default=lambda self: self.env['res.company']._company_default_get('account.account'))
    tag_ids = fields.Many2many('account.account.tag', 'account_account_account_tag', string='Tags', help="Optional tags you may want to assign for custom reporting")

    _sql_constraints = [
        ('code_company_uniq', 'unique (code,company_id)', 'The code of the account must be unique per company !')
    ]

    @api.model
    def name_search(self, name, args=None, operator='ilike', limit=100):
        args = args or []
        domain = []
        if name:
            domain = ['|', ('code', '=ilike', name + '%'), ('name', operator, name)]
            if operator in expression.NEGATIVE_TERM_OPERATORS:
                domain = ['&'] + domain
        accounts = self.search(domain + args, limit=limit)
        return accounts.name_get()

    @api.onchange('internal_type')
    def onchange_internal_type(self):
        if self.internal_type in ('receivable', 'payable'):
            self.reconcile = True

    @api.multi
    @api.depends('name', 'code')
    def name_get(self):
        result = []
        for account in self:
            name = account.code + ' ' + account.name
            result.append((account.id, name))
        return result

    @api.one
    def copy(self, default=None):
        default = dict(default or {})
        default.update(code=_("%s (copy)") % (self.code or ''))
        return super(AccountAccount, self).copy(default)

    @api.multi
    def write(self, vals):
        # Dont allow changing the company_id when account_move_line already exist
        if vals.get('company_id', False):
            move_lines = self.env['account.move.line'].search([('account_id', 'in', self.ids)], limit=1)
            for account in self:
                if (account.company_id.id <> vals['company_id']) and move_lines:
                    raise UserError(_('You cannot change the owner company of an account that already contains journal items.'))
        return super(AccountAccount, self).write(vals)

    @api.multi
    def unlink(self):
        if self.env['account.move.line'].search([('account_id', 'in', self.ids)], limit=1):
            raise UserError(_('You cannot do that on an account that contains journal items.'))
        #Checking whether the account is set as a property to any Partner or not
        values = ['account.account,%s' % (account_id,) for account_id in self.ids]
        partner_prop_acc = self.env['ir.property'].search([('value_reference', 'in', values)], limit=1)
        if partner_prop_acc:
            raise UserError(_('You cannot remove/deactivate an account which is set on a customer or vendor.'))
        return super(AccountAccount, self).unlink()

    @api.multi
    def mark_as_reconciled(self):
        return self.write({'last_time_entries_checked': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)})

    @api.multi
    def action_open_reconcile(self):
        # Open reconciliation view for this account
        action_context = {'show_mode_selector': False, 'account_ids': [self.id,]}
        return {
            'type': 'ir.actions.client',
            'tag': 'manual_reconciliation_view',
            'context': action_context,
        }
Example #9
0
class PurchaseRequisition(models.Model):
    _inherit = "purchase.requisition"
    _description = "Call for Bids"

    # new fields
    bid_tendering_mode = fields.Selection(
        [('open', 'Open'), ('restricted', 'Restricted')],
        'Call for Bids Mode',
        required=True,
        default='open',
        help="- Restricted : you select yourself the bidders and generate a "
        "RFQ for each of those. \n- Open : anybody can bid (you have to "
        "advertise the call for bids) and you directly encode the bids "
        "you received. You are still able to generate RFQ if you want to "
        "contact usual bidders.")
    bid_receipt_mode = fields.Selection(
        [('open', 'Open'), ('sealed', 'Sealed')],
        'Bid Receipt Mode',
        required=True,
        help="- Open : The bids can be opened when received and encoded. \n"
        "- Closed : The bids can be marked as received but they have to "
        "be opened \nall at the same time after an opening ceremony "
        "(probably specific to public sector).",
        default='open')
    req_incoterm_id = fields.Many2one(
        'stock.incoterms',
        'Requested Incoterms',
        help="Default value requested to the supplier. International "
        "Commercial Terms are a series of predefined commercial terms "
        "used in international transactions.")
    req_incoterm_address = fields.Char(
        'Requested Incoterms Place',
        help="Incoterm Place of Delivery. International Commercial Terms are a"
        " series of predefined commercial terms used in international "
        "transactions.")
    req_payment_term_id = fields.Many2one(
        'account.payment.term',
        'Requested Payment Term',
        help="Default value requested to the supplier.")
    req_terms_of_payment = fields.Char('Requested Terms of Payment')
    pricelist_id = fields.Many2one(
        'product.pricelist',
        'Pricelist',
        domain=[('type', '=', 'purchase')],
        help="If set that pricelist will be used to generate the RFQ."
        "Mostely used to ask a requisition in a given currency.")
    date_end = fields.Datetime(
        'Bid Submission Deadline',
        help="All bids received after that date won't be valid (probably "
        "specific to public sector).")
    delivery_remark = fields.Text('Delivery Remarks')
    budget = fields.Float()
    selection_reasons = fields.Text(copy=False)

    @api.multi
    def _has_product_lines(self):
        """
        Check there are products lines when confirming Call for Bids.
        Called from workflow transition draft->sent.
        """
        for callforbids in self:
            if not callforbids.line_ids:
                raise except_orm(
                    _('Error!'),
                    _('You have to define some products before confirming the '
                      'call for bids.'))
        return True

    @api.model
    def _prepare_purchase_order(self, requisition, supplier):
        values = super(PurchaseRequisition,
                       self)._prepare_purchase_order(requisition, supplier)
        values.update({
            'bid_validity': requisition.req_validity,
            'payment_term_id': requisition.req_payment_term_id.id,
            'incoterm_id': requisition.req_incoterm_id.id,
            'incoterm_address': requisition.req_incoterm_address,
            'delivery_remark': requisition.delivery_remark,
        })
        if requisition.pricelist_id:
            values['pricelist_id'] = requisition.pricelist_id.id
        return values

    @api.model
    def _prepare_purchase_order_line(self, requisition, requisition_line,
                                     purchase_id, supplier):
        vals = super(PurchaseRequisition, self)._prepare_purchase_order_line(
            requisition, requisition_line, purchase_id, supplier)
        vals.update(
            price_unit=0,
            requisition_line_id=requisition_line.id,
            remark=requisition_line.remark,
        )
        return vals

    @api.model
    def check_valid_quotation(self, quotation):
        return False

    def _prepare_po_from_tender(self, cr, uid, tender, context=None):
        """Give the generated PO the correct type and state
        and propagate the Delivery Remarks from tender"""
        result = super(PurchaseRequisition,
                       self)._prepare_po_from_tender(cr, uid, tender, context)
        result.update({
            'type': 'purchase',
            'state': 'draftpo',
            'keep_in_draft': True,
        })
        return result

    @api.multi
    def generate_po(self):
        self.ensure_one()

        for po_line in self.po_line_ids:
            # set bid selected boolean to true on RFQ containing confirmed
            # lines
            if (po_line.state == 'confirmed'
                    and not po_line.order_id.bid_partial):
                po_line.order_id.bid_partial = True

        result = super(PurchaseRequisition, self).generate_po()
        self.generated_order_ids.write({'keep_in_draft': False})
        return result

    @api.model
    def quotation_selected(self, quotation):
        """Predicate that checks if a quotation has at least one line chosen
        :param quotation: record of 'purchase.order'

        :returns: True if one line has been chosen

        """
        # This topic is subject to changes
        return quotation.bid_partial

    @api.model
    def cancel_unconfirmed_quotations(self, tender):
        """
        Called from generate_po. Cancel only draft and sent rfq
        """
        tender.refresh()
        for quotation in tender.purchase_ids:
            if quotation.state in ['draft', 'sent', 'draftbid', 'bid']:
                if self.quotation_selected(quotation):
                    quotation.signal_workflow('select_requisition')
                else:
                    quotation.signal_workflow('purchase_cancel')
                    quotation.message_post(
                        body=_('Canceled by the call for bids associated '
                               'to this request for quotation.'))

        return True

    @api.multi
    def tender_open(self):
        """
        Cancel RFQ that have not been sent. Ensure that there are RFQs."
        """
        pos_to_cancel = self.env['purchase.order']
        rfq_valid = False
        for callforbids in self:
            for purchase in callforbids.purchase_ids:
                if purchase.state == 'draft':
                    pos_to_cancel |= purchase
                elif purchase.state != 'cancel':
                    rfq_valid = True
        if pos_to_cancel:
            reason = self.env.ref('purchase_rfq_bid_workflow.'
                                  'purchase_cancel_reason_rfq_canceled')
            pos_to_cancel.write({'cancel_reason': reason.id})
            pos_to_cancel.action_cancel()
        if not rfq_valid:
            raise except_orm(_('Error'), _('You do not have valid sent RFQs.'))
        return super(PurchaseRequisition, self).tender_open()

    @api.multi
    def _get_po_to_cancel(self):
        """Get the list of PO/RFQ that can be cancelled on RFQ

        :returns: List of candidate PO/RFQ record

        """
        purchases = self.mapped('purchase_ids')
        return purchases.filtered(lambda rec: rec.state in ('draft', 'sent'))

    @api.one
    def _check_can_be_canceled(self):
        """Raise an exception if callforbids can not be cancelled

        :returns: True or raise exception

        """
        for purchase in self.purchase_ids:
            if purchase.state not in ('draft', 'sent'):
                raise except_orm(
                    _('Error'),
                    _('You cannot cancel a call for bids which '
                      'has already received bids.'))
        return True

    @api.model
    def _cancel_po_with_reason(self, po_list, reason_id):
        """Cancel purchase order of a tender, using given reasons
        :param po_list: list of po record to cancel
        :param reason_id: reason id of cancelation

        :returns: cancel po record list

        """
        po_list.write({'cancel_reason': reason_id})
        po_list.signal_workflow('purchase_cancel')
        return po_list

    @api.model
    def _get_default_reason(self):
        """Return default cancel reason"""
        reason = self.env.ref('purchase_requisition_bid_selection'
                              '.purchase_cancelreason_callforbids_canceled')
        return reason.id

    @api.multi
    def tender_cancel(self):
        """
        Cancel call for bids and try to cancel related RFQs/PO

        """
        reason_id = self._get_default_reason()
        for callforbid in self:
            callforbid._check_can_be_canceled()
        po_to_cancel = self._get_po_to_cancel()
        if po_to_cancel:
            self._cancel_po_with_reason(po_to_cancel, reason_id)
        self.state = 'cancel'

    @api.multi
    def update_selection_reasons(self):
        wizard = self.env['purchase.action_modal.'
                          'ask_selection_reasons'].browse(
                              self.env.context['active_id'])
        self.selection_reasons = wizard.selection_reasons
        self.signal_workflow('bid_selected')

    @api.multi
    def tender_selected(self):
        self.state = 'selected'

    @api.multi
    def act_tender_closed(self):
        self.signal_workflow('close_bid')

    @api.multi
    def tender_closed(self):
        self.state = 'closed'

    @api.multi
    def open_rfq(self):
        """
        This opens rfq view to view all generated rfq/bids associated to the
        call for bids
        """
        ActWindow = self.env['ir.actions.act_window']
        res = ActWindow.for_xml_id('purchase', 'purchase_rfq')
        res['domain'] = expression.AND([
            safe_eval(res.get('domain', [])),
            [('requisition_id', 'in', self.ids)]
        ])
        # FIXME: need to disable create - temporarily set as invisible in view
        return res

    @api.multi
    def open_po(self):
        """
        This opens po view to view all generated po associated to the call for
        bids
        """
        ActWindow = self.env['ir.actions.act_window']
        res = ActWindow.for_xml_id('purchase', 'purchase_form_action')
        res['domain'] = expression.AND([
            safe_eval(res.get('domain', [])),
            [('requisition_id', 'in', self.ids)]
        ])
        return res

    @api.multi
    def confirm_selection(self):
        """
        Check all quantities have been sourced
        """
        self.ensure_one()
        dp_obj = self.env['decimal.precision']
        precision = dp_obj.precision_get('Product Unit of Measure')
        for line in self.line_ids:
            qty = line.product_qty
            for pol in line.purchase_line_ids:
                if pol.state == 'confirmed':
                    qty -= pol.quantity_bid
            if qty == line.product_qty:
                break  # nothing selected
            compare = float_compare(qty, 0, precision_digits=precision)
            if compare != 0:
                break  # too much or too few selected
        else:
            return self.ask_selection_reasons()

        # open a dialog to confirm that we want more / less or no qty
        ctx = self.env.context.copy()

        ctx.update({
            'action': 'ask_selection_reasons',
            'active_model': self._name,
            'active_ids': self._ids,
        })
        view = self.env.ref('purchase_requisition_bid_selection'
                            '.action_modal_confirm_different_quantity')
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'purchase.action_modal',
            'view_id': view.id,
            'views': [(view.id, 'form')],
            'target': 'new',
            'context': ctx,
        }

    @api.multi
    def ask_confirmation_to_close_selection(self):
        ctx = self.env.context.copy()

        ctx.update({
            'action': 'act_tender_closed',
            'active_model': self._name,
            'active_ids': self._ids,
        })
        view = self.env.ref('purchase_requisition_bid_selection'
                            '.modal_confirm_close_selection')
        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'purchase.action_modal',
            'view_id': view.id,
            'views': [(view.id, 'form')],
            'target': 'new',
            'context': ctx,
        }

    def open_product_line(self, cr, uid, ids, context=None):
        """ Filter to show only lines from bids received.
        Group by requisition line instead of product for unicity.
        """
        res = super(PurchaseRequisition,
                    self).open_product_line(cr, uid, ids, context=context)
        ctx = res.setdefault('context', {})
        if 'search_default_groupby_product' in ctx:
            del ctx['search_default_groupby_product']
        if 'search_default_hide_cancelled' in ctx:
            del ctx['search_default_hide_cancelled']
        ctx['search_default_groupby_requisitionline'] = True
        ctx['search_default_showbids'] = True
        return res

    @api.multi
    def ask_selection_reasons(self):
        ctx = self._context.copy()
        ctx.update({
            'action': 'update_selection_reasons',
            'active_model': self._name,
            'active_ids': self._ids,
            'default_selection_reasons': self.selection_reasons,
        })
        view = self.env.ref('purchase_requisition_bid_selection.'
                            'ask_selection_reasons')

        return {
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'purchase.action_modal.ask_selection_reasons',
            'view_id': view.id,
            'views': [(view.id, 'form')],
            'target': 'new',
            'context': ctx,
        }
Example #10
0
class MrpProduction(models.Model):
    _inherit = 'mrp.production'
    _order = 'name desc'

    date_planned = fields.Datetime(readonly=False)  # Redefined
    routing_id = fields.Many2one(ondelete='restrict')  # Redefined
    date = fields.Datetime('Creation Date',
                           states={
                               'cancel': [('readonly', True)],
                               'done': [('readonly', True)]
                           },
                           default=fields.Datetime.now,
                           copy=False)
    state = fields.Selection(PRODUCTION_STATES)  # Redefined
    note = fields.Text('Notes')
    workcenter_lines = fields.One2many(readonly=False)  # Redefined
    origin = fields.Char(
        readonly=False,  # Redefined
        states={
            'cancel': [('readonly', True)],
            'done': [('readonly', True)]
        })
    color_production = fields.Integer('Color production',
                                      compute='_get_color_production',
                                      readonly=True)
    theo_cost = fields.Float('Theorical Cost',
                             digits=dp.get_precision('Product Price'),
                             copy=False)
    production_type = fields.Selection(PRODUCTION_TYPES,
                                       'Type of production',
                                       default='normal',
                                       copy=False)

    @api.multi
    def _get_color_production(self):
        for prod in self:
            color_production = -1  # blanco (cero da error al cargar la vista kanban)
            if prod.priority == '0':  # Prioridad no urgente
                color_production = 4  # verde claro
            elif prod.priority == '1':  # Prioridad normal
                color_production = 3  # amarillo
            elif prod.priority == '2':  # Prioridad urgente
                color_production = 2  # rojo claro
            elif prod.priority == '3':  # Prioridad muy urgente
                color_production = 1  # gris
            prod.color_production = color_production

    @api.multi
    def modify_consumption(self):
        ctx = dict(self._context,
                   active_model=self._name,
                   active_ids=self.ids,
                   active_id=self.ids[0])
        mod_cons_obj = self.env['mrp.modify.consumption'].with_context(ctx)
        return mod_cons_obj.create({}).wizard_view()

    @api.model
    def _costs_generate(self, production):
        """ Calculates total costs at the end of the production.
        @param production: Id of production order.
        @return: Calculated amount.
        """
        amount = 0.0
        analytic_line_obj = self.env['account.analytic.line']
        for wc_line in production.workcenter_lines:
            wc = wc_line.workcenter_id
            if wc.costs_journal_id and wc.costs_general_account_id:
                # Cost per hour
                value = wc_line.hour * wc.costs_hour
                account = wc.costs_hour_account_id.id
                if value and account:
                    amount += value
                    analytic_line_obj.sudo().create({
                        'name':
                        wc_line.name + ' (H)',
                        'amount':
                        value,
                        'account_id':
                        account,
                        'general_account_id':
                        wc.costs_general_account_id.id,
                        'journal_id':
                        wc.costs_journal_id.id,
                        'ref':
                        wc.code,
                        'product_id':
                        wc.product_id.id,
                        'unit_amount':
                        wc_line.hour,
                        'product_uom_id':
                        wc.product_id and wc.product_id.uom_id.id or False
                    })
        return amount

    @api.model
    def _make_production_produce_line(self, production):
        move_id = super(MrpProduction,
                        self)._make_production_produce_line(production)
        move = self.env['stock.move'].browse(move_id)
        move_name = _('PROD: %s') % production.name
        move.write({'name': move_name})
        return move_id

    @api.onchange('product_uos_qty')
    def product_uos_qty_change(self):
        if self.product_id.uos_id:
            qty_uom = float(self.product_uos_qty /
                            (self.product_id.uos_coeff or 1.0))
            self.product_qty = qty_uom
            self.product_uos = self.product_id.uos_id
        else:
            self.product_uos_qty = False
            self.product_uos = False

    @api.model
    def action_produce(self,
                       production_id,
                       production_qty,
                       production_mode,
                       wiz=False):
        stock_move_obj = self.env['stock.move']
        uom_obj = self.env['product.uom']
        production = self.browse(production_id)
        production_qty_uom = uom_obj._compute_qty(
            production.product_uom.id, production_qty,
            production.product_id.uom_id.id)
        precision = self.env['decimal.precision'].precision_get(
            'Product Unit of Measure')
        main_production_move = False
        default_mode = self._context.get('default_mode', False)
        if production_mode == 'produce':  # New Case: Produce Only
            produced_products = {}
            for produced_product in production.move_created_ids2:
                if produced_product.scrapped:
                    continue
                if not produced_products.get(produced_product.product_id.id,
                                             False):
                    produced_products[produced_product.product_id.id] = 0
                produced_products[produced_product.product_id.
                                  id] += produced_product.product_qty
            for produce_product in production.move_created_ids:
                subproduct_factor = self._get_subproduct_factor(
                    production.id, produce_product.id)
                lot_id = wiz and wiz.lot_id.id or False
                qty = min(subproduct_factor * production_qty_uom,
                          produce_product.product_qty
                          )  # Needed when producing more than maximum quantity
                new_moves = produce_product.action_consume(
                    qty,
                    location_id=produce_product.location_id.id,
                    restrict_lot_id=lot_id)
                stock_move_obj.browse(new_moves).write(
                    {'production_id': production_id})
                remaining_qty = subproduct_factor * production_qty_uom - qty
                if not float_is_zero(remaining_qty,
                                     precision_digits=precision):
                    # In case you need to make more than planned
                    # consumed more in wizard than previously planned
                    extra_move_id = produce_product.copy(
                        default={
                            'product_uom_qty': remaining_qty,
                            'production_id': production_id
                        })
                    extra_move_id.action_confirm()
                    extra_move_id.action_done()
                if produce_product.product_id == production.product_id:
                    main_production_move = produce_product.id
            if default_mode != 'consume' and not production.move_created_ids:
                production.signal_workflow('button_finished_validated')
        else:
            if not main_production_move:
                main_production_move = production.move_created_ids2 and production.move_created_ids2[
                    0].id
            # Añadimos al contexto 'main_production_move'
            # para poder escribirlo en el write y en el action_consume()
            self = self.with_context(main_production_move=main_production_move)
            res = super(MrpProduction, self).action_produce(production_id,
                                                            production_qty,
                                                            production_mode,
                                                            wiz=wiz)
            if default_mode != 'consume' and not production.move_created_ids:
                production.signal_workflow('button_finished_validated')
            if default_mode == 'consume':
                # Custom behaivor, set closed state
                production.signal_workflow('button_validated_closed')
        return True

    @api.multi
    def action_finished(self):
        for production in self:
            production.write({'state': 'finished'})
        return True

    @api.multi
    def action_validated(self):
        tmpl_obj = self.env['product.template']
        for production in self:
            theo_cost = tmpl_obj._calc_price(production.bom_id, test=True)
            production.write({'state': 'validated', 'theo_cost': theo_cost})
        return True

    @api.multi
    def action_close(self):
        tmpl_obj = self.env['product.template']
        precision = self.env['decimal.precision'].precision_get(
            'Product Price')
        for production in self:
            date = max([
                x.date for x in production.move_created_ids2
                if x.state == 'done' and not x.scrapped
            ] or [None])
            for move in production.move_lines2.filtered(
                    lambda r: r.state == 'done'):
                # Establecemos en los movimiento de consumos los precios de coste de producto que tenía en la fecha
                # que se realizó el producto finalizado, para que coincida con la misma posición
                # en la que se calcula el theo_cost. Esto es debido a que los consumos se pueden hacer más
                # tarde que la validación del producto terminado (action_validated)
                price_unit = tmpl_obj.get_history_price(
                    move.product_id.product_tmpl_id.id,
                    move.company_id.id,
                    date=date)
                # Aplicamos el redondeo que tendría el campo standard_price,
                # ya que get_history_price devuelve el valor sin precision
                price_unit = float_round(price_unit,
                                         precision_digits=precision)
                price_unit = price_unit or move.product_id.standard_price
                move.write({'price_unit': price_unit})
            production.write({'state': 'closed'})
        return True

    @api.multi
    def action_cancel(self):
        """ Cancels the production order and related stock moves.
        @return: True
        """
        res = super(MrpProduction, self).action_cancel()
        # Put related procurements in cancel state
        proc_obj = self.env['procurement.order']
        procs = proc_obj.search([('production_id', 'in', self.ids)])
        procs.write({'state': 'cancel'})
        return res

    @api.multi
    def action_in_production(self):
        """
        Overwrite to set startworking state of all workcenter lines instead
        only one.
        """
        for workcenter_line in self.mapped('workcenter_lines'):
            workcenter_line.signal_workflow('button_start_working')
        return super(MrpProduction, self).action_in_production()

    @api.multi
    def action_production_end(self):
        prod_line_obj = self.env['mrp.production.product.line']
        res = super(MrpProduction, self).action_production_end()
        for production in self:
            bom = production.bom_id
            finished_qty = sum([
                x.product_uom_qty for x in production.move_created_ids2
                if x.state == 'done' and not x.scrapped
            ])
            factor = self.env['product.uom']._compute_qty(
                production.product_uom.id, finished_qty, bom.product_uom.id)
            new_qty = factor / bom.product_qty
            routing_id = production.routing_id.id
            result, result2 = self.env['mrp.bom']._bom_explode(
                bom, production.product_id, new_qty, routing_id=routing_id)
            prod_lines = result
            production.product_lines.unlink()
            for line in prod_lines:
                line['production_id'] = production.id
                prod_line_obj.create(line)
        # Nos aseguramos de que la trazabilidad hacia arriba de la producción es correcta
        # Hay casos en los que se eliminan las lineas de consumos y se agragan nuevas,
        # momento en el que se pierde la traza
        self.update_production_traceability()
        return res

    @api.multi
    def update_production_traceability(self):
        for production in self:
            for move in production.move_created_ids2.filtered(
                    lambda r: r.state == 'done'):
                if move.production_id:  # Is final production move
                    raw_ids = move.production_id.move_lines
                    raw_ids |= move.production_id.move_lines2.filtered(
                        lambda r: r.state != 'cancel' and not r.scrapped)
                    move.write({'parent_ids': [(6, 0, raw_ids.ids)]})
        return True

    @api.multi
    def unlink(self):
        """ Unlink the production order and related stock moves.
        @return: True
        """
        if any(x.state not in ('draft', 'confirmed', 'ready', 'in_production',
                               'cancel') for x in self):
            raise exceptions.Warning(
                _('Error!'),
                _('You cannot delete a production which is not cancelled.'))
        prods_to_cancel = self.filtered(lambda r: r.state != 'cancel')
        if prods_to_cancel:
            prods_to_cancel.action_cancel()
        moves_to_unlink = self.mapped('move_created_ids2') + self.mapped(
            'move_lines2')
        moves_to_unlink.unlink()
        wc_lines_to_unlink = self.mapped('workcenter_lines')
        wc_lines_to_unlink.unlink()
        res = super(MrpProduction, self).unlink()
        return res

    @api.multi
    def update_production_priority(self):
        domain = [('priority', '!=', '3'),
                  ('state', 'in', ['confirmed', 'ready'])]
        production_ids = self or self.search(domain)
        for production in production_ids:
            product_id = production.product_id
            ctx = dict(self._context, location=production.location_dest_id.id)
            product_available = product_id.with_context(
                ctx)._product_available()[product_id.id]
            qty_to_compare = product_available[
                'qty_available'] - product_available['outgoing_qty']
            company_id = production.company_id
            domain = company_id and [('company_id', '=', company_id.id)] or []
            domain.append(('product_id', '=', product_id.id))
            op = self.env['stock.warehouse.orderpoint'].search(domain, limit=1)
            min_qty = security_qty = 0
            if op:
                min_qty = min(op.product_min_qty, op.product_max_qty)
                security_qty = op.product_security_qty
            if qty_to_compare <= 0:
                priority = '2'  # Urgente
            elif qty_to_compare <= security_qty:
                priority = '1'  # Normal
            elif qty_to_compare <= min_qty:
                priority = '0'  # No urgente
            else:
                priority = '0'  # No urgente
            if production.priority != priority:
                production.write({'priority': priority})
        return True
Example #11
0
class MailMandrillMessage(models.Model):
    _name = 'mail.mandrill.message'
    _order = 'timestamp desc'
    _rec_name = 'name'

    name = fields.Char(string='Subject', readonly=True)
    mandrill_id = fields.Char(string='Mandrill message ID', required=True,
                              readonly=True)
    timestamp = fields.Integer(string='Mandrill UTC timestamp', readonly=True)
    time = fields.Datetime(string='Mandrill time', readonly=True)
    date = fields.Date(string='Mandrill date', readonly=True)
    recipient = fields.Char(string='Recipient email', readonly=True)
    sender = fields.Char(string='Sender email', readonly=True)
    state = fields.Selection([
        ('deferred', 'Deferred'),
        ('sent', 'Sent'),
        ('opened', 'Opened'),
        ('rejected', 'Rejected'),
        ('spam', 'Spam'),
        ('unsub', 'Unsubscribed'),
        ('bounced', 'Bounced'),
        ('soft-bounced', 'Soft bounced'),
    ], string='State', index=True, readonly=True,
        help=" * The 'Sent' status indicates that message was succesfully "
             "delivered to recipient Mail Exchange (MX) server.\n"
             " * The 'Opened' status indicates that message was opened or "
             "clicked by recipient.\n"
             " * The 'Rejected' status indicates that recipient email "
             "address is blacklisted by Mandrill. It is recomended to "
             "delete this email address.\n"
             " * The 'Spam' status indicates that Mandrill consider this "
             "message as spam.\n"
             " * The 'Unsubscribed' status indicates that recipient has "
             "requested to be unsubscribed from this message.\n"
             " * The 'Bounced' status indicates that message was bounced "
             "by recipient Mail Exchange (MX) server.\n"
             " * The 'Soft bounced' status indicates that message was soft "
             "bounced by recipient Mail Exchange (MX) server.\n")
    bounce_type = fields.Char(string='Bounce type', readonly=True)
    bounce_description = fields.Char(string='Bounce description',
                                     readonly=True)
    tags = fields.Char(string='Tags', readonly=True)
    metadata = fields.Text(string='Metadata', readonly=True)
    event_ids = fields.One2many(
        string='Mandrill events',
        comodel_name='mail.mandrill.event', inverse_name='message_id')

    def _message_prepare(self, message_id, event_type, event):
        msg = event.get('msg')
        ts = msg.get('ts', 0)
        time = datetime.datetime.fromtimestamp(ts)
        tags = msg.get('tags', [])
        metadata = msg.get('metadata', {})
        metatext = json.dumps(metadata, indent=4) if metadata else False
        return {
            'mandrill_id': message_id,
            'timestamp': ts,
            'time': time.strftime('%Y-%m-%d %H:%M:%S') if ts else False,
            'date': time.strftime('%Y-%m-%d') if ts else False,
            'recipient': msg.get('email', False),
            'sender': msg.get('sender', False),
            'name': msg.get('subject', False),
            'tags': ', '.join(tags) if tags else False,
            'metadata': metatext,
        }

    def _event_prepare(self, message, event_type, event):
        m_event = self.env['mail.mandrill.event']
        method = getattr(m_event, 'process_' + event_type, None)
        if method and hasattr(method, '__call__'):
            return method(message, event)
        else:
            _logger.info('Unknown event type: %s' % event_type)
        return False

    @api.model
    def process(self, message_id, event_type, event):
        if not (message_id and event_type and event):
            return False
        msg = event.get('msg')
        message = self.search([('mandrill_id', '=', message_id)])
        if msg and not message:
            data = self._message_prepare(message_id, event_type, event)
            message = self.create(data) if data else False
        if message:
            m_event = self.env['mail.mandrill.event']
            data = self._event_prepare(message, event_type, event)
            return m_event.create(data) if data else False
        return False
Example #12
0
class WebsiteSupportTicketCompose(models.Model):

    _name = "website.support.ticket.compose"

    ticket_id = fields.Many2one('website.support.ticket', string='Ticket ID')
    partner_id = fields.Many2one('res.partner',
                                 string="Partner",
                                 readonly="True")
    email = fields.Char(string="Email", readonly="True")
    subject = fields.Char(string="Subject", readonly="True")
    body = fields.Text(string="Message Body")
    template_id = fields.Many2one(
        'mail.template',
        string="Mail Template",
        domain=
        "[('model_id','=','website.support.ticket'), ('built_in','=',False)]")
    approval = fields.Boolean(string="Approval")
    planned_time = fields.Datetime(string="Planned Time")

    @api.onchange('template_id')
    def _onchange_template_id(self):
        if self.template_id:
            values = self.env[
                'mail.compose.message'].generate_email_for_composer(
                    self.template_id.id,
                    [self.ticket_id.id])[self.ticket_id.id]
            self.body = values['body']

    @api.one
    def send_reply(self):

        #Change the approval state before we send the mail
        if self.approval:
            #Change the ticket state to awaiting approval
            awaiting_approval_state = self.env['ir.model.data'].get_object(
                'website_support', 'website_ticket_state_awaiting_approval')
            self.ticket_id.state = awaiting_approval_state.id

            #One support request per ticket...
            self.ticket_id.planned_time = self.planned_time
            self.ticket_id.approval_message = self.body
            self.ticket_id.sla_active = False

        #Send email
        values = {}

        setting_staff_reply_email_template_id = self.env['ir.default'].get(
            'website.support.settings', 'staff_reply_email_template_id')

        if setting_staff_reply_email_template_id:
            email_wrapper = self.env['mail.template'].browse(
                setting_staff_reply_email_template_id)

        values = email_wrapper.generate_email([self.id])[self.id]
        values['model'] = "website.support.ticket"
        values['res_id'] = self.ticket_id.id
        send_mail = self.env['mail.mail'].create(values)
        #send_mail.send()

        #Add to the message history to keep the data clean from the rest HTML
        self.env['website.support.ticket.message'].create({
            'ticket_id':
            self.ticket_id.id,
            'by':
            'staff',
            'content':
            self.body.replace("<p>", "").replace("</p>", "")
        })

        #Post in message history
        #self.ticket_id.message_post(body=self.body, subject=self.subject, message_type='comment', subtype='mt_comment')

        if self.approval:
            #Also change the approval
            awaiting_approval = self.env['ir.model.data'].get_object(
                'website_support', 'awaiting_approval')
            self.ticket_id.approval_id = awaiting_approval.id
        else:
            #Change the ticket state to staff replied
            staff_replied = self.env['ir.model.data'].get_object(
                'website_support', 'website_ticket_state_staff_replied')
            self.ticket_id.state = staff_replied.id
Example #13
0
class WebsiteSupportTicket(models.Model):

    _name = "website.support.ticket"
    _description = "Website Support Ticket"
    _order = "create_date desc"
    _rec_name = "subject"
    _inherit = ['mail.thread']
    _translate = True

    @api.model
    def _read_group_state(self, states, domain, order):
        """ Read group customization in order to display all the states in the
            kanban view, even if they are empty
        """

        staff_replied_state = self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_staff_replied')
        customer_replied_state = self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_customer_replied')
        customer_closed = self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_customer_closed')
        staff_closed = self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_staff_closed')

        exclude_states = [
            staff_replied_state.id, customer_replied_state.id,
            customer_closed.id, staff_closed.id
        ]

        # state_ids = states._search([('id','not in',exclude_states)], order=order, access_rights_uid=SUPERUSER_ID)
        state_ids = states._search([],
                                   order=order,
                                   access_rights_uid=SUPERUSER_ID)

        return states.browse(state_ids)

    def _default_state(self):
        return self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_open')

    def _default_state_new(self):
        state_obj = self.env['website.support.ticket.states']
        state = 'Open'
        open_state = state_obj.search([('name', '=', state)])
        #print("========================>",open_state.id)
        return open_state.id

    def _default_priority_id(self):
        default_priority = self.env['website.support.ticket.priority'].search([
            ('sequence', '=', '1')
        ])
        return default_priority[0]

    def _default_approval_id(self):
        return self.env['ir.model.data'].get_object('website_support',
                                                    'no_approval_required')

    attach_line = fields.One2many('sunfire.ticket.attach', 'attach_id')

    sun_channel = fields.Many2one('sunfire.ticket.channel', string='Channel')
    channel = fields.Char(string="Channel", default="Manual")
    create_user_id = fields.Many2one('res.users', "Create User")
    priority_id = fields.Many2one('website.support.ticket.priority',
                                  default=_default_priority_id,
                                  string="Priority")
    parent_company_id = fields.Many2one(string="Parent Company",
                                        related="partner_id.company_id")
    partner_id = fields.Many2one('res.partner', string="Partner")
    user_id = fields.Many2one('res.users', string="Assigned User")
    person_name = fields.Char(string='Person Name')
    email = fields.Char(string="Email")
    support_email = fields.Char(string="Support Email")
    category = fields.Many2one('website.support.ticket.categories',
                               string="Category",
                               track_visibility='onchange')
    sub_category_id = fields.Many2one('website.support.ticket.subcategory',
                                      string="Sub Category")
    subject = fields.Char(string="Subject")
    description = fields.Text(string="Description")
    state = fields.Many2one('website.support.ticket.states',
                            group_expand='_read_group_state',
                            default=_default_state,
                            string="State")
    conversation_history = fields.One2many('website.support.ticket.message',
                                           'ticket_id',
                                           string="Conversation History")
    attachment = fields.Binary(string="Attachments")
    attachment_filename = fields.Char(string="Attachment Filename")
    attachment_ids = fields.One2many('ir.attachment',
                                     'res_id',
                                     domain=[('res_model', '=',
                                              'website.support.ticket')],
                                     string="Media Attachments")
    unattended = fields.Boolean(
        string="Unattended",
        compute="_compute_unattend",
        store="True",
        help=
        "In 'Open' state or 'Customer Replied' state taken into consideration name changes"
    )
    portal_access_key = fields.Char(string="Portal Access Key")
    ticket_number = fields.Char(string="Ticket Number",
                                readonly=True,
                                store=True)
    ticket_color = fields.Char(related="priority_id.color",
                               string="Ticket Color")
    company_id = fields.Many2one(
        'res.company',
        string="Company",
        default=lambda self: self.env['res.company']._company_default_get(
            'website.support.ticket'))
    support_rating = fields.Integer(string="Support Rating")
    support_comment = fields.Text(string="Actions Taken")
    #comment_temp=fields.Text(string='Actions Taken')
    close_comment = fields.Text(string="Close Comment")
    close_time = fields.Datetime(string="Close Time")
    close_date = fields.Date(string="Close Date")
    closed_by_id = fields.Many2one('res.users', string="Closed By")
    time_to_close = fields.Integer(string="Time to close (seconds)")
    extra_field_ids = fields.One2many('website.support.ticket.field',
                                      'wst_id',
                                      string="Extra Details")
    planned_time = fields.Datetime(string="Planned Time")
    planned_time_format = fields.Char(string="Planned Time Format",
                                      compute="_compute_planned_time_format")
    approval_id = fields.Many2one('website.support.ticket.approval',
                                  default=_default_approval_id,
                                  string="Approval")
    approval_message = fields.Text(string="Approval Message")
    approve_url = fields.Char(compute="_compute_approve_url",
                              string="Approve URL")
    disapprove_url = fields.Char(compute="_compute_disapprove_url",
                                 string="Disapprove URL")
    tag_ids = fields.Many2many('website.support.ticket.tag', string="Tags")
    new_tag_ids = fields.Many2one('sunfire.ticket.tag', string="Tag")
    sla_id = fields.Many2one('website.support.sla', string="SLA")
    sla_timer = fields.Float(string="SLA Time Remaining")
    sla_timer_format = fields.Char(string="SLA Timer Format",
                                   compute="_compute_sla_timer_format")
    sla_active = fields.Boolean(string="SLA Active")
    sla_response_category_id = fields.Many2one('website.support.sla.response',
                                               string="SLA Response Category")
    sla_alert_ids = fields.Many2many(
        'website.support.sla.alert',
        string="SLA Alerts",
        help="Keep record of SLA alerts sent so we do not resend them")
    time_assign = fields.Datetime('Time To Assign')
    time_open = fields.Datetime('Time To Open')
    time_resolve = fields.Datetime('Time To Resolve')
    action_taken_line = fields.One2many('sunfire.actions', 'action_taken_id')
    status = fields.Selection([('open', 'Open'), ('assigned', 'Assigned'),
                               ('in_progress', 'Work in Progress'),
                               ('awaiting', 'Awaiting Customer'),
                               ('resolved', 'Resolved'), ('closed', 'Closed')],
                              string='Status',
                              readonly=True,
                              copy=False,
                              index=True,
                              track_visibility='onchange',
                              default='open')
    date_create_new = fields.Date("Create Date",
                                  compute='new_date_order',
                                  store=True)

    @api.depends('create_date')
    def new_date_order(self):
        lang_obj = self.env['res.lang']
        lang = lang_obj.search([("name", "=", "English")])
        for dt in self:
            if dt.create_date != False:
                temp = datetime.datetime.strptime(dt.create_date,
                                                  "%Y-%m-%d %H:%M:%S").date()
                dt.date_create_new = temp
            else:
                dt.date_create_new = ""

    def status_mail(self):
        email_template = self.env['ir.model.data'].get_object(
            'website_support', 'support_ticket_status_mail')
        email_values = email_template.generate_email([self.id])[self.id]
        email_values['model'] = "website.support.ticket"
        email_values['res_id'] = self.id
        #assigned_user = self.env['res.users'].browse( int(values['user_id']) )
        email_values['email_to'] = self.partner_id.email or self.email
        email_values['body_html'] = email_values['body_html'].replace(
            "_user_name_", self.partner_id.name)
        email_values['body'] = email_values['body'].replace(
            "_user_name_", self.partner_id.name)
        send_mail = self.env['mail.mail'].create(email_values)
        #print("here======+>")
        send_mail.send()

    @api.multi
    def action_assigned(self):
        #self.status_mail()
        return self.write({
            'status': 'assigned',
            'time_assign': datetime.datetime.now()
        })

    @api.multi
    def action_in_progress(self):
        #self.status_mail()
        return self.write({'status': 'in_progress'})

    @api.multi
    def action_awaiting(self):
        #self.status_mail()
        return self.write({'status': 'awaiting'})

    @api.multi
    def action_resolved(self):
        #self.status_mail()
        return self.write({
            'status': 'resolved',
            'time_resolve': datetime.datetime.now()
        })

    @api.multi
    def action_close(self):
        #self.status_mail()
        return self.write({'status': 'closed'})

    @api.onchange('user_id')
    def onchng_user(self):
        appr_obj = self.env['approval_types.info'].search([
            ('approval_type', '=', 'Technical Services')
        ])
        li = []
        domain = {}
        for i in appr_obj.role_line:
            li.append(i.users.id)
        domain['user_id'] = [('id', 'in', li)]
        return {'domain': domain}

    @api.one
    @api.depends('sla_timer')
    def _compute_sla_timer_format(self):
        # Display negative hours in a positive format
        self.sla_timer_format = '{0:02.0f}:{1:02.0f}'.format(
            *divmod(abs(self.sla_timer) * 60, 60))

    @api.model
    def update_sla_timer(self):

        # Subtract 1 minute from the timer of all active SLA tickets, this includes going into negative
        for active_sla_ticket in self.env['website.support.ticket'].search([
            ('sla_active', '=', True), ('sla_id', '!=', False),
            ('sla_response_category_id', '!=', False)
        ]):

            # If we only countdown during busines hours
            if active_sla_ticket.sla_response_category_id.countdown_condition == 'business_only':
                # Check if the current time aligns with a timeslot in the settings,
                # setting has to be set for business_only or UserError occurs
                setting_business_hours_id = self.env['ir.default'].get(
                    'website.support.settings', 'business_hours_id')
                current_hour = datetime.datetime.now().hour
                current_minute = datetime.datetime.now().minute / 60
                current_hour_float = current_hour + current_minute
                day_of_week = datetime.datetime.now().weekday()
                during_work_hours = self.env[
                    'resource.calendar.attendance'].search([
                        ('calendar_id', '=', setting_business_hours_id),
                        ('dayofweek', '=', day_of_week),
                        ('hour_from', '<', current_hour_float),
                        ('hour_to', '>', current_hour_float)
                    ])

                # If holiday module is installed take into consideration
                holiday_module = self.env['ir.module.module'].search([
                    ('name', '=', 'hr_public_holidays'),
                    ('state', '=', 'installed')
                ])
                if holiday_module:
                    holiday_today = self.env['hr.holidays.public.line'].search(
                        [('date', '=', datetime.datetime.now().date())])
                    if holiday_today:
                        during_work_hours = False

                if during_work_hours:
                    active_sla_ticket.sla_timer -= 1 / 60
            else:
                #Countdown even if the business hours setting is not set
                active_sla_ticket.sla_timer -= 1 / 60

            #Send an email out to everyone in the category about the SLA alert
            notification_template = self.env['ir.model.data'].sudo(
            ).get_object('website_support', 'support_ticket_sla_alert')

            for sla_alert in self.env['website.support.sla.alert'].search([
                ('vsa_id', '=', active_sla_ticket.sla_id.id),
                ('alert_time', '>=', active_sla_ticket.sla_timer)
            ]):

                #Only send out the alert once
                if sla_alert not in active_sla_ticket.sla_alert_ids:

                    for my_user in active_sla_ticket.category.cat_user_ids:
                        values = notification_template.generate_email(
                            active_sla_ticket.id)
                        values['body_html'] = values['body_html'].replace(
                            "_user_name_", my_user.partner_id.name)
                        values['email_to'] = my_user.partner_id.email

                        send_mail = self.env['mail.mail'].create(values)
                        #send_mail.send()

                        #Remove the message from the chatter since this would bloat the communication history by a lot
                        send_mail.mail_message_id.res_id = 0

                    #Add the alert to the list of already sent SLA
                    active_sla_ticket.sla_alert_ids = [(4, sla_alert.id)]

    def pause_sla(self):
        self.sla_active = False

    def resume_sla(self):
        self.sla_active = True

    @api.one
    @api.depends('planned_time')
    def _compute_planned_time_format(self):

        #If it is assigned to the partner, use the partners timezone and date formatting
        if self.planned_time and self.partner_id and self.partner_id.lang:
            partner_language = self.env['res.lang'].search([
                ('code', '=', self.partner_id.lang)
            ])[0]

            my_planned_time = datetime.datetime.strptime(
                self.planned_time, DEFAULT_SERVER_DATETIME_FORMAT)

            #If we have timezone information translate the planned date to local time otherwise UTC
            if self.partner_id.tz:
                my_planned_time = my_planned_time.replace(
                    tzinfo=tz.gettz('UTC'))
                local_time = my_planned_time.astimezone(
                    tz.gettz(self.partner_id.tz))
                self.planned_time_format = local_time.strftime(
                    partner_language.date_format + " " +
                    partner_language.time_format) + " " + self.partner_id.tz
            else:
                self.planned_time_format = my_planned_time.strftime(
                    partner_language.date_format + " " +
                    partner_language.time_format) + " UTC"

        else:
            self.planned_time_format = self.planned_time

    @api.one
    def _compute_approve_url(self):
        self.approve_url = "/support/approve/" + str(self.id)

    @api.one
    def _compute_disapprove_url(self):
        self.disapprove_url = "/support/disapprove/" + str(self.id)

    @api.onchange('sub_category_id')
    def _onchange_sub_category_id(self):
        if self.sub_category_id:

            add_extra_fields = []

            for extra_field in self.sub_category_id.additional_field_ids:
                add_extra_fields.append((0, 0, {'name': extra_field.name}))

            self.update({
                'extra_field_ids': add_extra_fields,
            })

    @api.onchange('partner_id')
    def _onchange_partner_id(self):
        self.person_name = self.partner_id.name
        self.email = self.partner_id.email

    def message_new(self, msg, custom_values=None):
        """ Create new support ticket upon receiving new email"""

        defaults = {
            'support_email': msg.get('to'),
            'subject': msg.get('subject')
        }

        #Extract the name from the from email if you can
        if "<" in msg.get('from') and ">" in msg.get('from'):
            start = msg.get('from').rindex("<") + 1
            end = msg.get('from').rindex(">", start)
            from_email = msg.get('from')[start:end]
            from_name = msg.get('from').split("<")[0].strip()
            defaults['person_name'] = from_name
        else:
            from_email = msg.get('from')

        defaults['email'] = from_email
        defaults['channel'] = "Email"

        #Try to find the partner using the from email
        search_partner = self.env['res.partner'].sudo().search([('email', '=',
                                                                 from_email)])
        if len(search_partner) > 0:
            defaults['partner_id'] = search_partner[0].id
            defaults['person_name'] = search_partner[0].name

        defaults['description'] = tools.html_sanitize(msg.get('body'))

        #Assign to default category
        setting_email_default_category_id = self.env['ir.default'].get(
            'website.support.settings', 'email_default_category_id')

        if setting_email_default_category_id:
            defaults['category'] = setting_email_default_category_id

        return super(WebsiteSupportTicket,
                     self).message_new(msg, custom_values=defaults)

    def message_update(self, msg_dict, update_vals=None):
        """ Override to update the support ticket according to the email. """

        body_short = tools.html_sanitize(msg_dict['body'])
        #body_short = tools.html_email_clean(msg_dict['body'], shorten=True, remove=True)

        #Add to message history to keep HTML clean
        self.conversation_history.create({
            'ticket_id': self.id,
            'by': 'customer',
            'content': body_short
        })

        #If the to email address is to the customer then it must be a staff member
        if msg_dict.get('to') == self.email:
            change_state = self.env['ir.model.data'].get_object(
                'website_support', 'website_ticket_state_staff_replied')
        else:
            change_state = self.env['ir.model.data'].get_object(
                'website_support', 'website_ticket_state_customer_replied')

        self.state = change_state.id

        return super(WebsiteSupportTicket,
                     self).message_update(msg_dict, update_vals=update_vals)

    @api.one
    @api.depends('state')
    def _compute_unattend(self):
        #BACK COMPATABLITY Use open and customer reply as default unattended states
        opened_state = self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_open')
        customer_replied_state = self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_customer_replied')

        if self.state == opened_state or self.state == customer_replied_state or self.state.unattended == True:
            self.unattended = True

    @api.multi
    def request_approval(self):

        approval_email = self.env['ir.model.data'].get_object(
            'website_support', 'support_ticket_approval')

        values = self.env['mail.compose.message'].generate_email_for_composer(
            approval_email.id, [self.id])[self.id]

        request_message = values['body']

        return {
            'name': "Request Approval",
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'website.support.ticket.compose',
            'context': {
                'default_ticket_id': self.id,
                'default_email': self.email,
                'default_subject': self.subject,
                'default_approval': True,
                'default_body': request_message
            },
            'target': 'new'
        }

    @api.multi
    def open_close_ticket_wizard(self):

        return {
            'name': "Close Support Ticket",
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'website.support.ticket.close',
            'context': {
                'default_ticket_id': self.id
            },
            'target': 'new'
        }

    @api.model
    def _needaction_domain_get(self):
        open_state = self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_open')
        custom_replied_state = self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_customer_replied')
        return [
            '|', ('state', '=', open_state.id),
            ('state', '=', custom_replied_state.id)
        ]

    #assigns ticket number
    def set_ticket_number(self, vals):
        print("vals", vals)
        tag_obj = self.env['sunfire.ticket.tag']
        sun_tag_ids = tag_obj.search([('id', '=', vals['new_tag_ids'])])
        vals['time_open'] = datetime.datetime.now()
        if sun_tag_ids.name == "Incident":
            print("Incident")
            vals['ticket_number'] = self.env['ir.sequence'].next_by_code(
                'website.support.ticket.incident')
        elif sun_tag_ids.name == "Request":
            print("Request")
            vals['ticket_number'] = self.env['ir.sequence'].next_by_code(
                'website.support.ticket.request')
        else:
            print("else")
            vals['ticket_number'] = self.env['ir.sequence'].next_by_code(
                'website.support.ticket')

    @api.model
    def create(self, vals):
        # Get next ticket number from the sequence
        # vals['ticket_number'] = self.env['ir.sequence'].next_by_code('website.support.ticket')
        #call the function which assigns the ticket number
        self.set_ticket_number(vals)
        new_id = super(WebsiteSupportTicket, self).create(vals)

        new_id.portal_access_key = randint(1000000000, 2000000000)

        ticket_open_email_template = self.env['ir.model.data'].get_object(
            'website_support', 'website_ticket_state_open').mail_template_id
        ticket_open_email_template.send_mail(new_id.id, True)

        #Check if this contact has a SLA assigned
        if new_id.partner_id.sla_id:
            #Check if this category has a SLA response time
            category_response = self.env[
                'website.support.sla.response'].search([
                    ('vsa_id', '=', new_id.partner_id.sla_id.id),
                    ('category_id', '=', new_id.category.id)
                ])
            if category_response:
                new_id.sla_id = new_id.partner_id.sla_id.id
                new_id.sla_active = True
                new_id.sla_timer = category_response.response_time
                new_id.sla_response_category_id = category_response.id

        #Send an email out to everyone in the category
        notification_template = self.env['ir.model.data'].sudo().get_object(
            'website_support', 'new_support_ticket_category')
        support_ticket_menu = self.env['ir.model.data'].sudo().get_object(
            'website_support', 'website_support_ticket_menu')
        support_ticket_action = self.env['ir.model.data'].sudo().get_object(
            'website_support', 'website_support_ticket_action')

        for my_user in new_id.category.cat_user_ids:
            values = notification_template.generate_email(new_id.id)
            values['body_html'] = values['body_html'].replace(
                "_ticket_url_", "web#id=" + str(new_id.id) +
                "&view_type=form&model=website.support.ticket&menu_id=" +
                str(support_ticket_menu.id) + "&action=" +
                str(support_ticket_action.id)).replace("_user_name_",
                                                       my_user.partner_id.name)
            values['email_to'] = my_user.partner_id.email

            send_mail = self.env['mail.mail'].create(values)
            #send_mail.send()

            #Remove the message from the chatter since this would bloat the communication history by a lot
            send_mail.mail_message_id.res_id = 0

        return new_id

    @api.multi
    def write(self, values, context=None):

        update_rec = super(WebsiteSupportTicket, self).write(values)

        if 'state' in values:
            if self.state.mail_template_id:
                self.state.mail_template_id.send_mail(self.id, True)

        #Email user if category has changed
        if 'category' in values:
            change_category_email = self.env['ir.model.data'].sudo(
            ).get_object('website_support',
                         'new_support_ticket_category_change')
            change_category_email.send_mail(self.id, True)

        if 'user_id' in values:
            setting_change_user_email_template_id = self.env['ir.default'].get(
                'website.support.settings', 'change_user_email_template_id')

            if setting_change_user_email_template_id:
                email_template = self.env['mail.template'].browse(
                    setting_change_user_email_template_id)
            else:
                #Default email template
                email_template = self.env['ir.model.data'].get_object(
                    'website_support', 'support_ticket_user_change')

            email_values = email_template.generate_email([self.id])[self.id]
            email_values['model'] = "website.support.ticket"
            email_values['res_id'] = self.id
            assigned_user = self.env['res.users'].browse(int(
                values['user_id']))
            email_values['email_to'] = assigned_user.partner_id.email
            email_values['body_html'] = email_values['body_html'].replace(
                "_user_name_", assigned_user.name)
            email_values['body'] = email_values['body'].replace(
                "_user_name_", assigned_user.name)
            send_mail = self.env['mail.mail'].create(email_values)
            #send_mail.send()
        return update_rec

    def send_survey(self):
        notification_template = self.env['ir.model.data'].sudo().get_object(
            'website_support', 'support_ticket_survey')
        values = notification_template.generate_email(self.id)
        surevey_url = "support/survey/" + str(self.portal_access_key)
        values['body_html'] = values['body_html'].replace(
            "_survey_url_", surevey_url)
        send_mail = self.env['mail.mail'].create(values)
        send_mail.send(True)
Example #14
0
class RequestGroupAction(models.Model):
    _name = "hc.request.group.action"
    _description = "Request Group Action"

    request_group_id = fields.Many2one(
        comodel_name="hc.res.request.group",
        string="Request Group",
        help="Request Group associated with this Request Group Action.")
    action_identifier_id = fields.Many2one(
        comodel_name="hc.request.group.action.action.identifier",
        string="Action Identifier",
        help="Unique identifier.")
    label = fields.Char(
        string="Label",
        help="User-visible label for the action (e.g. 1. or A.).")
    title = fields.Char(string="Title", help="User-visible title.")
    description = fields.Text(string="Description",
                              help="Short description of the action.")
    text_equivalent = fields.Text(
        string="Text Equivalent",
        help=
        "Static text equivalent of the action, used if the dynamic aspects cannot be interpreted by the receiving system."
    )
    code_ids = fields.Many2many(
        comodel_name="hc.vs.action.code",
        relation="request_group_action_code_rel",
        string="Codes",
        help="The meaning of the action or its sub-actions.")
    documentation_ids = fields.One2many(
        comodel_name="hc.request.group.action.documentation",
        inverse_name="action_id",
        string="Documentation",
        help=
        "Supporting documentation for the intended performer of the action.")
    timing_type = fields.Selection(
        string="Timing Type",
        selection=[("dateTime", "Datetime"), ("Period", "Period"),
                   ("Duration", "Duration"), ("Range", "Range"),
                   ("Timing", "Timing")],
        help="Type of when the action should take place.")
    timing_name = fields.Char(string="Timing",
                              compute="_compute_timing_name",
                              store="True",
                              help="When the action should take place.")
    timing_datetime = fields.Datetime(
        string="Timing Datetime", help="When the action should take place.")
    timing_start_date = fields.Datetime(
        string="Timing Start Date",
        help="Start of when the action should take place.")
    timing_end_date = fields.Datetime(
        string="Timing End Date",
        help="End of when the action should take place.")
    timing_duration = fields.Float(
        string="Timing Duration",
        help="Duration when the action should take place.")
    timing_duration_uom_id = fields.Many2one(
        comodel_name="product.uom",
        string="Timing Duration UOM",
        domain="[('category_id','=','Time (UCUM)')]",
        help="Timing Duration unit of measure.")
    timing_range_low = fields.Float(
        string="Timing Range Low",
        help="Low limit of when the action should take place.")
    timing_range_high = fields.Float(
        string="Timing Range High",
        help="High limit of when the action should take place.")
    timing_range_uom_id = fields.Many2one(comodel_name="product.uom",
                                          string="Timing Range UOM",
                                          help="Timing Range unit of measure.")
    timing_id = fields.Many2one(comodel_name="hc.request.group.action.timing",
                                string="Timing",
                                help="When the action should take place.")
    participant_ids = fields.One2many(
        comodel_name="hc.request.group.action.participant",
        inverse_name="action_id",
        string="Participants",
        help="Participant.")
    type = fields.Selection(
        string="Type",
        selection=[("create", "Create"), ("update", "Update"),
                   ("remove", "Remove"), ("fire-event", "Fire-Event")],
        help="The type of action to perform (create, update, remove).")
    grouping_behavior = fields.Selection(
        string="Grouping Behavior",
        selection=[("visual-group", "Visual-Group"),
                   ("logical-group", "Logical-Group"),
                   ("sentence-group", "Sentence-Group")],
        help="Defines the grouping behavior for the action and its children.")
    selection_behavior = fields.Selection(
        string="Selection Behavior",
        selection=[("any", "Any"), ("all", "All"),
                   ("all-or-none", "All-Or-None"),
                   ("exactly-one", "Exactly-One"),
                   ("at-most-one", "At-Most-One"),
                   ("one-or-more", "One-Or-More")],
        help="Defines the selection behavior for the action and its children.")
    required_behavior = fields.Selection(
        string="Required Behavior",
        selection=[("must", "Must"), ("could", "Could"),
                   ("must-unless-documented", "Must-Unless-Documented")],
        help="Defines the requiredness behavior for the action.")
    precheck_behavior = fields.Selection(
        string="Precheck Behavior",
        selection=[("yes", "Yes"), ("no", "No")],
        help="Defines whether the action should usually be preselected.")
    cardinality_behavior = fields.Selection(
        string="Cardinality Behavior",
        selection=[("single", "Single"), ("multiple", "Multiple")],
        help="Defines whether the action can be selected multiple times.")
    resource_string = fields.Char(string="Resource String",
                                  help="String of the target of the action.")
    resource_code_id = fields.Many2one(
        comodel_name="hc.vs.resource.type",
        string="Resource Code",
        help="Code of the target of the action.")
    condition_ids = fields.One2many(
        comodel_name="hc.request.group.action.condition",
        inverse_name="action_id",
        string="Conditions",
        help="Whether or not the action is applicable.")
    related_action_ids = fields.One2many(
        comodel_name="hc.request.group.action.related.action",
        inverse_name="action_id",
        string="Related Actions",
        help="Relationship to another action.")
Example #15
0
class project_task(models.Model):
    _inherit = "project.task"
    _order = "sequence"
    
    @api.model
    def create(self, vals):
        vals['reference'] = self.env['ir.sequence'].get('project.Task')
        return super(project_task, self).create(vals)
   
    user_id = fields.Many2one('res.users', 'Assigned to', select=True, track_visibility='onchange', default="")
    actor_ids = fields.Many2many(comodel_name='project.scrum.actors', string='Actor')
    sprint_id = fields.Many2one(comodel_name='project.scrum.sprint', string='Sprint', store=True)
    us_id = fields.Many2one(comodel_name='project.scrum.us', string='User Stories')
    date_start = fields.Datetime(string='Starting Date', required=False, default=fields.Datetime.now())
    date_end = fields.Datetime(string='Ending Date', required=False)
    use_scrum = fields.Boolean(related='project_id.use_scrum')
    description = fields.Html('Description')
    current_sprint = fields.Boolean(compute='_current_sprint', string='Current Sprint', search='_search_current_sprint')
    moscow = fields.Selection([
            (1, 'must'), 
            (2, 'should'), 
            (3, 'could'), 
            (4, 'wont'), 
            ('not_set', 'Not Set'), 
            ], string='Moscow')
    value = fields.Selection([
             (0, '0'), (0.5, '0.5'), (1, '1'), (2, '2'), (3, '3'), (5, '5'), (8, '8'), (13, '13'), \
             (20, '20'), (40, '40'), (100, '100'), (00, 'Not Set'),
             ], string='Value')
    risk = fields.Selection([
            (0, '0'), (1, '1'), (2, '2'), (3, '3'), (5, '5'), (8, '8'), (13, '13'), (20, '20'), \
            (40, '40'), (100, '100'), (00, 'Not Set'),
            ], string='Risk')
    kano = fields.Selection([
            ('excitement', 'Excitement'), ('indifferent', 'Indifferent'), ('mandatory', 'Mandatory'), \
            ('performance', 'Performance'),
            ('questionable', 'Questionable'), ('reverse', 'Reverse'), ('not_set', 'Not Set'),
            ], string='Kano')
    color = fields.Integer(related='project_id.color')
    reference = fields.Char('Number', select=True, readonly=True, copy=False, default=':')

    @api.depends('sprint_id')
    @api.one
    def _current_sprint(self):
        sprint = self.env['project.scrum.sprint'].get_current_sprint(self.project_id.id)
        #~ _logger.error('Task computed %r' % self)
        if sprint:
            self.current_sprint = sprint.id == self.sprint_id.id
        else:
            self.current_sprint = False
            
    def _search_current_sprint(self, operator, value):
        #~ raise Warning('operator %s value %s' % (operator, value))
        project_id = self.env.context.get('default_project_id', None)
        sprint = self.env['project.scrum.sprint'].get_current_sprint(project_id)
        #~ raise Warning('sprint %s csprint %s context %s' % (self.sprint_id, sprint, self.env.context))
        _logger.error('Task %r' % self)
        return [('sprint_id', '=', sprint and sprint.id or None)]
            
    @api.multi
    def write(self, vals):
        if vals.get('stage_id') == self.env.ref('project.project_stage_data_2').id:
            vals['date_end'] = fields.datetime.now()
        return super(project_task, self).write(vals)

    @api.model
    def _read_group_sprint_id(self, present_ids, domain, **kwargs):
        project = self.env['project.project'].browse(self._resolve_project_id_from_context())

        if project.use_scrum:
            sprints = self.env['project.scrum.sprint'].search([('project_id', '=', project.id)], order='sequence').name_get()
            return sprints, None
        else:
            return [], None

    @api.model
    def _read_group_us_id(self, present_ids, domain, **kwargs):
        project = self.env['project.project'].browse(self._resolve_project_id_from_context())

        if project.use_scrum:
            user_stories = self.env['project.scrum.us'].search([('project_id', '=', project.id)], order='sequence').name_get()
            return user_stories, None
        else:
            return [], None
Example #16
0
class ShiftShift(models.Model):
    _inherit = 'event.event'
    _name = 'shift.shift'
    _description = 'Shift Template'

    @api.model
    def _default_shift_mail_ids(self):
        return [(0, 0, {
            'interval_unit': 'now',
            'interval_type': 'after_sub',
            'template_id': self.env.ref('coop_shift.shift_subscription')
        })]

    name = fields.Char(string="Shift Name")
    event_mail_ids = fields.One2many(default=None)
    shift_mail_ids = fields.One2many(
        'shift.mail',
        'shift_id',
        string='Mail Schedule',
        default=lambda self: self._default_shift_mail_ids())
    shift_type_id = fields.Many2one('shift.type',
                                    string='Category',
                                    required=False,
                                    readonly=False,
                                    states={'done': [('readonly', True)]})
    week_number = fields.Selection(WEEK_NUMBERS,
                                   string='Week',
                                   compute="_compute_week_number",
                                   store=True)
    week_list = fields.Selection([('MO', 'Monday'), ('TU', 'Tuesday'),
                                  ('WE', 'Wednesday'), ('TH', 'Thursday'),
                                  ('FR', 'Friday'), ('SA', 'Saturday'),
                                  ('SU', 'Sunday')], 'Weekday')
    registration_ids = fields.One2many('shift.registration',
                                       'shift_id',
                                       string='Attendees',
                                       readonly=False,
                                       states={'done': [('readonly', True)]})
    shift_template_id = fields.Many2one('shift.template',
                                        string='Template',
                                        ondelete='restrict')
    seats_reserved = fields.Integer(compute='_compute_seats_shift')
    seats_available = fields.Integer(compute='_compute_seats_shift')
    seats_unconfirmed = fields.Integer(compute='_compute_seats_shift')
    seats_used = fields.Integer(compute='_compute_seats_shift')
    seats_expected = fields.Integer(compute='_compute_seats_shift')
    auto_confirm = fields.Boolean(string='Confirmation not required',
                                  compute='_compute_auto_confirm')
    event_ticket_ids = fields.One2many(
        default=lambda rec: rec._default_tickets())
    shift_ticket_ids = fields.One2many(
        'shift.ticket',
        'shift_id',
        string='Shift Ticket',
        default=lambda rec: rec._default_shift_tickets(),
        copy=True)
    date_tz = fields.Selection('_tz_get', string='Timezone', default=False)
    date_begin = fields.Datetime(compute="_compute_date_begin",
                                 store=True,
                                 required=False)
    date_begin_tz = fields.Datetime(string='Begin Date Time')
    date_end = fields.Datetime(compute="_compute_date_end",
                               store=True,
                               required=False)
    date_end_tz = fields.Datetime(string='End Date Time')
    date_without_time = fields.Date(string='Date',
                                    compute='_compute_begin_date_fields',
                                    store=True,
                                    multi="begin_date")
    begin_date_string = fields.Char(string='Begin Date',
                                    compute='_compute_begin_date_fields',
                                    store=True,
                                    multi="begin_date")
    end_date_for_mail = fields.Char(string='End Date for mail',
                                    compute='_compute_end_date_fields',
                                    store=True,
                                    multi="end_date")
    begin_date_without_time_string = fields.Char(
        string='Begin Date for mail without time',
        multi="begin_date",
        compute='_compute_begin_date_fields')
    begin_time = fields.Float(string='Start Time',
                              compute='_compute_begin_date_fields',
                              store=True,
                              multi="begin_date")
    begin_time_string = fields.Char(string='Start Time',
                                    compute='_compute_begin_date_fields',
                                    multi="begin_date")
    end_time = fields.Float(string='Start Time',
                            compute='_compute_end_date_fields',
                            store=True,
                            multi="end_date")
    end_time_for_mail = fields.Char(string='End Time',
                                    compute='_compute_end_date_fields',
                                    multi="end_date")
    user_ids = fields.Many2many('res.partner',
                                'res_partner_shift_shift_rel',
                                'shift_template_id',
                                'partner_id',
                                string='Shift Leaders')
    user_id = fields.Many2one(comodel_name='res.partner', default=False)
    seats_max = fields.Integer()

    _sql_constraints = [
        ('template_date_uniq',
         'unique (shift_template_id, date_begin, company_id)',
         'The same template cannot be planned several time at the same date !'
         ),
    ]

    @api.multi
    @api.depends('date_without_time')
    def _compute_week_number(self):
        for shift in self:
            if not shift.date_without_time:
                shift.week_number = False
            else:
                weekA_date = fields.Date.from_string(
                    self.env.ref('coop_shift.config_parameter_weekA').value)
                start_date = fields.Date.from_string(shift.date_without_time)
                shift.week_number =\
                    1 + (((start_date - weekA_date).days // 7) % 4)

    @api.model
    def name_search(self, name, args=None, operator='ilike', limit=100):
        args = args or []
        domain = []
        if name:
            domain = [
                '|', ('begin_date_string', operator, name),
                ('name', operator, name)
            ]
            if operator in expression.NEGATIVE_TERM_OPERATORS:
                domain = ['&', '!'] + domain[1:]
        shifts = self.search(domain + args, limit=limit)
        return shifts.name_get()

    @api.multi
    @api.depends('name', 'date_begin')
    def name_get(self):
        result = []
        for shift in self:
            name = shift.name + (shift.begin_date_string and
                                 (' ' + shift.begin_date_string) or '')
            result.append((shift.id, name))
        return result

    @api.model
    def _default_tickets(self):
        return None

    @api.model
    def _default_shift_tickets(self):
        try:
            product = self.env.ref('coop_shift.product_product_shift_standard')
            product2 = self.env.ref('coop_shift.product_product_shift_ftop')
            return [{
                'name': _('Standard'),
                'product_id': product.id,
                'price': 0,
            }, {
                'name': _('FTOP'),
                'product_id': product2.id,
                'price': 0,
            }]
        except ValueError:
            return self.env['shift.ticket']

    @api.multi
    def _compute_auto_confirm(self):
        for shift in self:
            shift.auto_confirm = False

    @api.model
    def _default_event_mail_ids(self):
        return None

    @api.multi
    @api.depends('seats_max', 'registration_ids.state')
    def _compute_seats_shift(self):
        """ Determine reserved, available, reserved but unconfirmed and used
        seats. """
        # initialize fields to 0
        for shift in self:
            shift.seats_unconfirmed = shift.seats_reserved =\
                shift.seats_used = shift.seats_available = 0
        # aggregate registrations by shift and by state
        if self.ids:
            state_field = {
                'draft': 'seats_reserved',
                'open': 'seats_reserved',
                'replacing': 'seats_reserved',
                'done': 'seats_used',
            }
            query = """ SELECT shift_id, state, count(shift_id)
                        FROM shift_registration
                        WHERE shift_id IN %s
                        AND state IN ('draft', 'open', 'done', 'replacing')
                        GROUP BY shift_id, state
                    """
            self._cr.execute(query, (tuple(self.ids), ))
            for shift_id, state, num in self._cr.fetchall():
                shift = self.browse(shift_id)
                shift[state_field[state]] += num
        # compute seats_available
        for shift in self:
            if shift.seats_max > 0:
                shift.seats_available = shift.seats_max - (
                    shift.seats_reserved + shift.seats_used)
            shift.seats_expected = shift.seats_unconfirmed +\
                shift.seats_reserved + shift.seats_used

    @api.multi
    def write(self, vals, special=[]):
        if any(shift.state == "done" for shift in self):
            raise UserError(
                _('You can only repercute changes on draft shifts.'))
        res = super(ShiftShift, self).write(vals)
        for field in special:
            if field == 'shift_ticket_ids':
                for shift in self:
                    template = shift.shift_template_id
                    ftop_ticket = template.shift_ticket_ids.filtered(
                        lambda t: t.shift_type == 'ftop')
                    standard_ticket = template.shift_ticket_ids.filtered(
                        lambda t: t.shift_type == 'standard')
                    ftop_seats_max = ftop_ticket and ftop_ticket[0].seats_max\
                        or False
                    standard_seats_max = standard_ticket and\
                        standard_ticket[0].seats_max or False
                    for ticket in shift.shift_ticket_ids:
                        if ticket.shift_type == 'ftop':
                            ticket.seats_max = ftop_seats_max
                        if ticket.shift_type == 'standard':
                            ticket.seats_max = standard_seats_max
        return res

    @api.onchange('shift_template_id')
    def _onchange_template_id(self):
        if self.shift_template_id:
            self.name = self.shift_template_id.name
            self.user_ids = self.shift_template_id.user_ids
            self.shift_type_id = self.shift_template_id.shift_type_id
            self.week_number = self.shift_template_id.week_number
            cur_date = self.date_begin and datetime.strptime(
                self.date_begin, "%Y-%m-%d %H:%M:%S").date() or\
                datetime.strptime(
                    self.shift_template_id.start_date, "%Y-%m-%d")
            self.date_begin = datetime.strftime(
                cur_date + timedelta(hours=self.shift_template_id.start_time),
                "%Y-%m-%d %H:%M:%S")
            self.date_end = datetime.strftime(
                cur_date + timedelta(hours=self.shift_template_id.end_time),
                "%Y-%m-%d %H:%M:%S")

            cur_attendees = [r.partner_id.id for r in self.registration_ids]
            vals = []
            for attendee in self.shift_template_id.registration_ids:
                if attendee.id not in cur_attendees:
                    vals.append((0, 0, {
                        'partner_id': attendee.id,
                        'state': 'draft',
                        'email': attendee.email,
                        'phone': attendee.phone,
                        'name': attendee.name,
                        'shift_id': self.id,
                    }))
                self.registration_ids = vals

    @api.depends('date_begin_tz')
    @api.multi
    def _compute_date_begin(self):
        tz_name = self._context.get('tz') or self.env.user.tz
        if not tz_name:
            raise UserError(
                _("You can not create Shift if your timezone is not defined."))
        context_tz = pytz.timezone(tz_name)
        for shift in self:
            if shift.date_begin_tz:
                start_date_object_tz = fields.Datetime.from_string(
                    shift.date_begin_tz)
                utc_timestamp = pytz.utc.localize(start_date_object_tz,
                                                  is_dst=False)
                start_date_object = utc_timestamp.astimezone(context_tz)
                start_date = start_date_object_tz + timedelta(
                    hours=start_date_object_tz.hour - start_date_object.hour)
                shift.date_begin = "%s-%02d-%02d %02d:%02d:%02d" % (
                    start_date.year,
                    start_date.month,
                    start_date.day,
                    start_date.hour,
                    start_date.minute,
                    start_date.second,
                )

    @api.depends('date_end_tz')
    @api.multi
    def _compute_date_end(self):
        tz_name = self._context.get('tz') or self.env.user.tz
        if not tz_name:
            raise UserError(
                _("You can not create Shift if your timezone is not defined."))
        context_tz = pytz.timezone(tz_name)
        for shift in self:
            if shift.date_end_tz:
                end_date_object_tz = fields.Datetime.from_string(
                    shift.date_end_tz)
                utc_timestamp = pytz.utc.localize(end_date_object_tz,
                                                  is_dst=False)
                end_date_object = utc_timestamp.astimezone(context_tz)
                end_date = end_date_object_tz + timedelta(
                    hours=end_date_object_tz.hour - end_date_object.hour)
                shift.date_end = "%s-%02d-%02d %02d:%02d:%02d" % (
                    end_date.year,
                    end_date.month,
                    end_date.day,
                    end_date.hour,
                    end_date.minute,
                    end_date.second,
                )

    @api.multi
    @api.depends('date_begin_tz')
    def _compute_begin_date_fields(self):
        for shift in self:
            if shift.date_begin_tz:
                start_date_object_tz = datetime.strptime(
                    shift.date_begin_tz, '%Y-%m-%d %H:%M:%S')
                shift.begin_time = (start_date_object_tz.hour +
                                    (start_date_object_tz.minute / 60.0))
                shift.begin_time_string = "%02d:%02d" % (
                    start_date_object_tz.hour,
                    start_date_object_tz.minute,
                )
                shift.begin_date_string = "%02d/%02d/%s %02d:%02d" % (
                    start_date_object_tz.day,
                    start_date_object_tz.month,
                    start_date_object_tz.year,
                    start_date_object_tz.hour,
                    start_date_object_tz.minute,
                )
                shift.begin_date_without_time_string = "%02d/%02d/%s" % (
                    start_date_object_tz.day,
                    start_date_object_tz.month,
                    start_date_object_tz.year,
                )
                shift.date_without_time = "%s-%02d-%02d" % (
                    start_date_object_tz.year,
                    start_date_object_tz.month,
                    start_date_object_tz.day,
                )

    @api.multi
    @api.depends('date_end')
    def _compute_end_date_fields(self):
        tz_name = self._context.get('tz') or self.env.user.tz
        if not tz_name:
            raise UserError(
                _("You can not create Shift if your timezone is not defined."))
        for shift in self:
            shift.end_date_for_mail = datetime.strftime(
                fields.Datetime.from_string(shift.date_end), "%d/%m/%Y %H:%M")
            shift.end_time_for_mail = datetime.strftime(
                fields.Datetime.from_string(shift.date_end), "%H:%M")

            if shift.date_end:
                start_date_object = datetime.strptime(shift.date_end,
                                                      '%Y-%m-%d %H:%M:%S')
                utc_timestamp = pytz.utc.localize(start_date_object,
                                                  is_dst=False)
                context_tz = pytz.timezone(tz_name)
                start_date_object_tz = utc_timestamp.astimezone(context_tz)
                shift.end_time = (start_date_object_tz.hour +
                                  (start_date_object_tz.minute / 60.0))

    @api.multi
    def button_confirm(self):
        super(ShiftShift, self).button_confirm()

    @api.model
    def run_shift_confirmation(self):
        # This method is called by the cron task
        compare_date = fields.Date.to_string(datetime.today() + timedelta(
            days=SHIFT_CONFIRMATION_DAYS))
        shifts = self.env['shift.shift'].search([('state', '=', 'draft'),
                                                 ('date_begin', '<=',
                                                  compare_date)])
        shifts.button_confirm()

    @api.one
    @api.constrains('seats_max', 'seats_available')
    def _check_seats_limit(self):
        return True
Example #17
0
class Edocument(models.AbstractModel):

    _name = 'account.edocument'
    _FIELDS = {
        'account.invoice': 'invoice_number',
        'account.retention': 'name'
    }
    SriServiceObj = SriService()

    clave_acceso = fields.Char('Clave de Acceso', size=49, readonly=True)
    numero_autorizacion = fields.Char('Número de Autorización',
                                      size=37,
                                      readonly=True)
    estado_autorizacion = fields.Char('Estado de Autorización',
                                      size=64,
                                      readonly=True)
    fecha_autorizacion = fields.Datetime('Fecha Autorización', readonly=True)
    ambiente = fields.Char('Ambiente', size=64, readonly=True)
    autorizado_sri = fields.Boolean('¿Autorizado SRI?', readonly=True)
    security_code = fields.Char('Código de Seguridad', size=8, readonly=True)
    emission_code = fields.Char('Tipo de Emisión', size=1, readonly=True)
    epayment_id = fields.Many2one('account.epayment', 'Forma de Pago')
    sent = fields.Boolean('Enviado?')

    def get_auth(self, document):
        partner = document.company_id.partner_id
        if document._name == 'account.invoice':
            return document.auth_inv_id
        elif document._name == 'account.retention':
            return partner.get_authorisation('ret_in_invoice')

    def get_secuencial(self):
        return getattr(self, self._FIELDS[self._name])[6:]

    def _info_tributaria(self, document, access_key, emission_code):
        """
        """
        company = document.company_id
        auth = self.get_auth(document)
        infoTributaria = {
            'ambiente': self.env.user.company_id.env_service,
            'tipoEmision': emission_code,
            'razonSocial': company.name,
            'nombreComercial': company.name,
            'ruc': company.partner_id.identifier,
            'claveAcceso': access_key,
            'codDoc': utils.tipoDocumento[auth.type_id.code],
            'estab': auth.serie_entidad,
            'ptoEmi': auth.serie_emision,
            'secuencial': self.get_secuencial(),
            'dirMatriz': company.street
        }
        return infoTributaria

    def get_code(self):
        code = self.env['ir.sequence'].next_by_code('edocuments.code')
        return code

    def get_access_key(self, name):
        if name == 'account.invoice':
            auth = self.company_id.partner_id.get_authorisation('out_invoice')
            ld = self.date_invoice.split('-')
            numero = getattr(self, 'invoice_number')
        elif name == 'account.retention':
            auth = self.company_id.partner_id.get_authorisation(
                'ret_in_invoice')  # noqa
            ld = self.date.split('-')
            numero = getattr(self, 'name')
            numero = numero[6:15]
        ld.reverse()
        fecha = ''.join(ld)
        tcomp = utils.tipoDocumento[auth.type_id.code]
        ruc = self.company_id.partner_id.identifier
        codigo_numero = self.get_code()
        tipo_emision = self.company_id.emission_code
        access_key = ([fecha, tcomp,
                       ruc], [numero, codigo_numero, tipo_emision])
        return access_key

    @api.multi
    def _get_codes(self, name='account.invoice'):
        ak_temp = self.get_access_key(name)
        self.SriServiceObj.set_active_env(self.env.user.company_id.env_service)
        access_key = self.SriServiceObj.create_access_key(ak_temp)
        emission_code = self.company_id.emission_code
        return access_key, emission_code

    @api.multi
    def check_before_sent(self):
        """
        """
        MESSAGE_SEQUENCIAL = ' '.join([
            u'Los comprobantes electrónicos deberán ser',
            u'enviados al SRI para su autorización en orden cronológico',
            'y secuencial. Por favor enviar primero el',
            ' comprobante inmediatamente anterior.'
        ])
        FIELD = {
            'account.invoice': 'invoice_number',
            'account.retention': 'name'
        }
        number = getattr(self, FIELD[self._name])
        sql = ' '.join([
            "SELECT autorizado_sri, %s FROM %s" %
            (FIELD[self._name], self._table),  # noqa
            "WHERE state='open' AND %s < '%s'" %
            (FIELD[self._name], number),  # noqa
            self._name == 'account.invoice' and "AND type = 'out_invoice'"
            or '',  # noqa
            "ORDER BY %s DESC LIMIT 1" % FIELD[self._name]
        ])
        self.env.cr.execute(sql)
        res = self.env.cr.fetchone()
        if not res:
            return True
        auth, number = res
        if auth is None and number:
            raise UserError(MESSAGE_SEQUENCIAL)
        return True

    def check_date(self, date_invoice):
        """
        Validar que el envío del comprobante electrónico
        se realice dentro de las 24 horas posteriores a su emisión
        """
        LIMIT_TO_SEND = 5
        MESSAGE_TIME_LIMIT = u' '.join([
            u'Los comprobantes electrónicos deben',
            u'enviarse con máximo 24h desde su emisión.'
        ])
        dt = datetime.strptime(date_invoice, '%Y-%m-%d')
        days = (datetime.now() - dt).days
        if days > LIMIT_TO_SEND:
            raise UserError(MESSAGE_TIME_LIMIT)

    @api.multi
    def update_document(self, auth, codes):
        fecha = auth.fechaAutorizacion.strftime(DEFAULT_SERVER_DATETIME_FORMAT)
        self.write({
            'numero_autorizacion': auth.numeroAutorizacion,
            'estado_autorizacion': auth.estado,
            'ambiente': auth.ambiente,
            'fecha_autorizacion': fecha,  # noqa
            'autorizado_sri': True,
            'clave_acceso': codes[0],
            'emission_code': codes[1]
        })

    @api.one
    def add_attachment(self, xml_element, auth):
        buf = StringIO.StringIO()
        buf.write(xml_element.encode('utf-8'))
        document = base64.encodestring(buf.getvalue())
        buf.close()
        attach = self.env['ir.attachment'].create(
            {
                'name': '{0}.xml'.format(self.clave_acceso),
                'datas': document,
                'datas_fname': '{0}.xml'.format(self.clave_acceso),
                'res_model': self._name,
                'res_id': self.id,
                'type': 'binary'
            }, )
        return attach

    @api.multi
    def send_document(self, attachments=None, tmpl=False):
        self.ensure_one()
        self._logger.info('Enviando documento electronico por correo')
        tmpl = self.env.ref(tmpl)
        tmpl.send_mail(  # noqa
            self.id, email_values={'attachment_ids': attachments})
        self.sent = True
        return True

    def render_document(self, document, access_key, emission_code):
        pass
Example #18
0
class WizEventDeleteAssistant(models.TransientModel):
    _name = 'wiz.event.delete.assistant'

    from_date = fields.Date(string='From date', required=True)
    to_date = fields.Date(string='To date', required=True)
    registration = fields.Many2one(comodel_name='event.registration',
                                   string='Partner registration')
    partner = fields.Many2one(comodel_name='res.partner',
                              string='Partner',
                              required=True)
    min_event = fields.Many2one(comodel_name='event.event',
                                string='Min. event')
    min_from_date = fields.Datetime(string='Min. from date', required=True)
    max_event = fields.Many2one(comodel_name='event.event',
                                string='Max. event')
    max_to_date = fields.Datetime(string='Max. to date', required=True)
    past_sessions = fields.Boolean(string='Past Sessions',
                                   compute='_compute_past_later_sessions')
    later_sessions = fields.Boolean(string='Later Sessions',
                                    compute='_compute_past_later_sessions')
    message = fields.Char(string='Message',
                          readonly=True,
                          compute='_compute_past_later_sessions')
    notes = fields.Text(string='Notes')
    removal_date = fields.Date(
        string='Removal date',
        default=lambda self: fields.Date.context_today(self))

    @api.model
    def default_get(self, var_fields):
        tz = self.env.user.tz
        res = super(WizEventDeleteAssistant, self).default_get(var_fields)
        events = self.env['event.event'].browse(
            self.env.context.get('active_ids'))
        if events:
            from_date = _convert_to_local_date(
                min(events.mapped('date_begin')), tz)
            to_date = _convert_to_local_date(max(events.mapped('date_end')),
                                             tz)
            min_event = events.sorted(key=lambda e: e.date_begin)[:1]
            max_event = events.sorted(key=lambda e: e.date_end,
                                      reverse=True)[:1]
            res.update({
                'from_date': date2str(from_date.date()),
                'to_date': date2str(to_date.date()),
                'min_from_date': datetime2str(from_date),
                'max_to_date': datetime2str(to_date),
                'min_event': min_event.id,
                'max_event': max_event.id,
            })
        return res

    @api.depends('from_date', 'to_date', 'partner')
    def _compute_past_later_sessions(self):
        event_track_obj = self.env['event.track']
        if self.from_date and self.to_date and self.partner:
            if self.registration:
                sessions = self.partner.mapped(
                    'presence_ids.session').filtered(
                        lambda x: x.event_id.id == self.registration.event_id.
                        id)
            else:
                sessions = self.partner.mapped(
                    'presence_ids.session').filtered(
                        lambda x: x.event_id.id in self.env.context.get(
                            'active_ids'))
            cond = self._prepare_track_condition_from_date(sessions)
            self.past_sessions = bool(event_track_obj.search(cond, limit=1))
            cond = self._prepare_track_condition_to_date(sessions)
            self.later_sessions = bool(event_track_obj.search(cond, limit=1))
            if self.past_sessions and self.later_sessions:
                self.message = _('This person has sessions with dates before'
                                 ' and after')
            elif self.past_sessions:
                self.message = _('This person has sessions with dates before')
            elif self.later_sessions:
                self.message = _('This person has sessions with dates after')

    @api.multi
    @api.onchange('from_date', 'to_date')
    def onchange_dates(self):
        self.ensure_one()
        res = {}
        from_date, to_date =\
            self._prepare_dates_for_search_registrations()
        min_from_date = self._prepare_date_for_control(self.min_from_date,
                                                       time=0.0)
        max_to_date = self._prepare_date_for_control(self.max_to_date,
                                                     time=24.0)
        if from_date and to_date and from_date > to_date:
            self.revert_dates()
            return {
                'warning': {
                    'title': _('Error in from date'),
                    'message': (_('From date greater than date to'))
                }
            }
        if from_date and from_date < min_from_date:
            self.revert_dates()
            return {
                'warning': {
                    'title':
                    _('Error in from date'),
                    'message':
                    (_('From date less than start date of the event %s') %
                     self.min_event.name)
                }
            }
        if to_date and to_date > max_to_date:
            self.revert_dates()
            return {
                'warning': {
                    'title':
                    _('Error in to date'),
                    'message':
                    (_('To date greater than end date of the event %s') %
                     self.max_event.name)
                }
            }
        return res

    def _prepare_date_for_control(self, date, time=0.0):
        date = str2datetime(date) if isinstance(date, str) else date
        new_date = datetime2str(
            _convert_to_utc_date(date.date(), time=time, tz=self.env.user.tz))
        return new_date

    def _prepare_track_condition_from_date(self, sessions):
        from_date, to_date = self._prepare_dates_for_search_registrations()
        cond = [('id', 'in', sessions.ids), ('date', '!=', False),
                ('date', '<', from_date)]
        return cond

    def _prepare_track_condition_to_date(self, sessions):
        from_date, to_date = self._prepare_dates_for_search_registrations()
        cond = [('id', 'in', sessions.ids), ('date', '!=', False),
                ('date', '>', to_date)]
        return cond

    @api.multi
    def action_delete(self):
        self.ensure_one()
        cond = [('event_id', 'in', self.env.context.get('active_ids')),
                ('partner_id', '=', self.partner.id), ('state', '=', 'open')]
        registrations = self.env['event.registration'].search(cond)\
            if not self.registration else self.registration
        registrations._cancel_registration(self.from_date, self.to_date,
                                           self.removal_date, self.notes)
        return self._open_event_tree_form()

    def _prepare_dates_for_search_registrations(self):
        from_date = self._prepare_date_for_control(self.from_date, time=0.0)
        to_date = self._prepare_date_for_control(self.to_date, time=24.0)
        return from_date, to_date

    def revert_dates(self):
        tz = self.env.user.tz
        self.from_date = _convert_to_local_date(self.min_from_date,
                                                tz=tz).date()
        self.to_date = _convert_to_local_date(self.max_to_date, tz=tz).date()

    def _open_event_tree_form(self):
        active_ids = self.env.context.get('active_ids', [])
        view_mode = 'kanban,calendar,tree,form' if len(active_ids) > 1 else\
            'form,kanban,calendar,tree'
        result = {
            'name': _('Event'),
            'type': 'ir.actions.act_window',
            'res_model': 'event.event',
            'view_type': 'form',
            'view_mode': view_mode,
            'res_id': active_ids[0],
            'target': 'current',
            'context': self.env.context
        }
        return result
Example #19
0
class eq_shipcloud(models.Model):

    _name = "eq.shipcloud"
    _description = "This module helps to integrate Odoo with shipcloud api"

    _rec_name = "eq_id"

    _order = "create_date desc"

    create_date = fields.Datetime(string="Creation Date")
    eq_id = fields.Char(string="Shipment ID",
                        copy=False,
                        help="Shipcloud shipments ID",
                        required=True)
    eq_carrier_tracking_no = fields.Char(string="Carrier tracking nos",
                                         copy=False,
                                         help="shipments tracking nos")
    eq_tracking_url = fields.Text(string="Tracking URL",
                                  copy=False,
                                  help="shipments tracking URL")
    eq_label_url = fields.Text(string="Label URL",
                               copy=False,
                               help="Label URL")
    eq_price = fields.Float(string="Price", help="Price")
    eq_package = fields.Many2one('stock.quant.package',
                                 string="Package",
                                 help="Denote the shipment related package")

    _sql_constraints = [
        ('eq_id_package_unique', 'unique(eq_id, eq_package)',
         'Shipments ID and Package must be unique!'),
    ]

    @api.multi
    def eq_opentrack_url(self):
        if self.eq_tracking_url:
            webbrowser.open(self.eq_tracking_url)

    @api.multi
    def eq_openlabel_url(self):
        if self.eq_label_url:
            webbrowser.open(self.eq_label_url)

    @api.v7
    def eq_check_pack_valid(self, cr, uid, pack_operation_data, context):
        if pack_operation_data.result_package_id.ul_id.height <=0  or pack_operation_data.result_package_id.ul_id.length <=0 or \
                    pack_operation_data.result_package_id.ul_id.width <=0 or pack_operation_data.eq_gross_weight <= 0:
            return False

        return True

    @api.v7
    def eq_create_shipcloud(self, cr, uid, result, context=None):

        if result:
            """ Converting unicode string dictionary into dictionary in python """

            for res in result:
                d = ast.literal_eval(res.get('response').text)

                if d.get('id') == None:
                    return False
                data = {
                    'eq_id': d.get('id') or None,
                    'eq_carrier_tracking_no': d.get('carrier_tracking_no')
                    or None,
                    'eq_tracking_url': d.get('tracking_url') or None,
                    'eq_label_url': d.get('label_url') or None,
                    'eq_price': d.get('price') or None,
                    'eq_package': res.get('package_id') or None
                }
                eq_shipcloud_id = self.create(cr, uid, data, context=None)

        return True

    @api.v7
    def eq_shipcloud_service_url(self, cr, uid, context=None):
        """         
            Get the shipcloud service url 
        """
        url = self.pool.get('ir.config_parameter').get_param(
            cr, uid, "eq.shipcloud.service.url", False) or None
        return url

    @api.v7
    def eq_shipcloud_api_key(self, cr, uid, context=None):
        """         
            Get the shipcloud apikey 
        """
        config_obj = self.pool.get('ir.config_parameter')
        if config_obj.get_param(cr, uid, "eq.is.sandbox.apikey",
                                False) == 'True':
            key = config_obj.get_param(cr, uid, "eq.shipcloud.sandbox.apikey",
                                       False)
        else:
            key = config_obj.get_param(cr, uid, "eq.shipcloud.apikey", False)
        return key

    @api.v7
    def _get_to_data(self, cr, uid, picking_data):
        res = {}
        partner = picking_data.partner_id

        if not partner.eq_house_no:
            raise (_('Error!'),
                   _('The house no. for the delivery address is not defined.'))

        if partner.type in ('default', 'delivery', 'pobox', 'other'):
            if partner.eq_name2:
                res["to[company]"] = partner.name
                res["to[last_name]"] = partner.eq_name2
            else:
                res["to[last_name]"] = partner.name
        elif partner.type == "contact":
            if partner.eq_name2:
                res["to[company]"] = partner.eq_name2
                res["to[first_name]"] = partner.eq_firstname
                res["to[last_name]"] = partner.name

        if partner.use_parent_address:
            res["to[street]"] = partner.street or None,
            res["to[street_no]"] = partner.eq_house_no or None,
            res["to[city]"] = partner.city or None,
            res["to[zip_code]"] = partner.zip or None,
            res["to[country]"] = partner.country_id.name or None,
        else:
            res["to[street]"] = partner.parent_id.street or None,
            res["to[street_no]"] = partner.parent_id.eq_house_no or None,
            res["to[city]"] = partner.parent_id.city or None,
            res["to[zip_code]"] = partner.parent_id.zip or None,
            res["to[country]"] = partner.parent_id.country_id.name or None,
        return res

    @api.v7
    def _get_from_data(self, cr, uid, picking_data):

        company = picking_data.company_id

        if not company.eq_house_no:
            raise Warning(_('The house no. for the company is not defined.'))

        res = {
            "from[last_name]": company.name or None,
            "from[street]": company.street or None,
            "from[street_no]": company.eq_house_no or None,
            "from[city]": company.city or None,
            "from[zip_code]": company.zip or None,
            "from[country]": company.country_id.name or None,
        }

        return res

    @api.v7
    def eq_create_shipments(self, cr, uid, picking_id, context=None):
        """
            If Delivery order has no package, then shipments will not be created.
        """
        data = {}
        result = {}
        final_result = []
        count = 0
        if picking_id:
            #             Get the shipcloud apikey
            api_key = self.eq_shipcloud_api_key(cr, uid, context=None)
            if api_key == None:
                raise osv.except_osv(_('Error!'),
                                     _('Please provide shipcloud apikey.'))
            stock_pick_obj = self.pool.get("stock.picking")
            stock_quant_package_obj = self.pool.get('stock.quant.package')
            shipcloud_deliverymethod_obj = self.pool.get(
                'eq.shipcloud.deliverymethod')
            picking_data = stock_pick_obj.browse(cr,
                                                 uid,
                                                 picking_id,
                                                 context=None)

            delivery_ids = shipcloud_deliverymethod_obj.search(
                cr,
                uid,
                [('eq_deliverymethod_id', '=', picking_data.carrier_id.id)],
                context=None)
            if delivery_ids:
                delivery_data = shipcloud_deliverymethod_obj.browse(
                    cr, uid, delivery_ids, context=None)[0]

                if (not delivery_data.eq_sc_carrier) or (
                        not delivery_data.eq_sc_service_id):
                    raise osv.except_osv(
                        _('Error!'),
                        _(' Only when a delivery method is connected with shipcloud carrier and Service a shipment at shipcloud is created.'
                          ))
            else:
                raise osv.except_osv(
                    _('Error!'),
                    _(' Only when a delivery method is connected with shipcloud carrier and Service a shipment at shipcloud is created.'
                      ))

            if picking_data.pack_operation_ids:
                for pack_operation_data in picking_data.pack_operation_ids:

                    #                     If the Delivery Order has no destination package - throws exception
                    if not pack_operation_data.result_package_id:
                        raise osv.except_osv(
                            _('Error!'),
                            _('Please provide Destination packages for Shipments.'
                              ))

#                     Check valid package dimensions
                    is_package_valid = self.eq_check_pack_valid(
                        cr, uid, pack_operation_data, context=None)
                    if not is_package_valid:
                        raise osv.except_osv(
                            _('Error!'),
                            _('Please provide valid dimensions values for packages.'
                              ))

#                     Avoid creating duplicate entries
                    if stock_quant_package_obj.browse(
                            cr,
                            uid,
                            pack_operation_data.result_package_id.id,
                            context=None).eq_is_processed:
                        continue

                    data = {
                        "carrier":
                        delivery_data.eq_sc_carrier or None,
                        "package[weight]":
                        pack_operation_data.result_package_id.
                        eq_gross_weight_changed or
                        pack_operation_data.result_package_id.eq_gross_weight,
                        "package[length]":
                        pack_operation_data.result_package_id.ul_id.length,
                        "package[width]":
                        pack_operation_data.result_package_id.ul_id.width,
                        "package[height]":
                        pack_operation_data.result_package_id.ul_id.height,
                        "service":
                        delivery_data.eq_sc_service_id.eq_name or None,
                        "create_shipping_label":
                        'true',
                    }

                    to_data = self._get_to_data(cr, uid, picking_data)
                    from_data = self._get_from_data(cr, uid, picking_data)

                    data.update(to_data)
                    data.update(from_data)

                    #Creating a shipment
                    try:
                        #Get the shipcloud serice url
                        service_url = self.eq_shipcloud_service_url(
                            cr, uid, context=None)
                        res = requests.post(service_url + '/v1/shipments',
                                            data=data,
                                            auth=(api_key, ''))
                        count += 1
                        #adding package id to the result
                        result = {
                            'package_id':
                            pack_operation_data.result_package_id.id,
                            'response': res,
                            'picking_id': picking_id,
                        }

                        final_result.append(result)
                        stock_quant_package_obj.write(
                            cr,
                            uid,
                            pack_operation_data.result_package_id.id,
                            {'eq_is_processed': True},
                            context=context)

                    except Exception, e:
                        _logger.exception(e)

                stock_pick_obj.write(cr,
                                     uid,
                                     picking_id, {
                                         'eq_is_shipped': True,
                                         'eq_is_processed': True
                                     },
                                     context=context)
                return final_result

        return False
Example #20
0
class CenitDataTypeTrigger(models.Model):
    _name = "cenit.data_type.trigger"

    data_type = fields.Many2one("cenit.data_type", "Data Type")
    name = fields.Selection([
        ("on_create", "On creation"),
        ("on_write", "On update"),
        ("on_create_or_write", "On creation or update"),
        ("interval", "On interval"),
        ("only_manual", "Only manually"),
    ],
                            required=True)

    cron = fields.Many2one('ir.cron', string='Cron rules')
    cron_lapse = fields.Integer("Interval number", default=10)
    cron_units = fields.Selection([('minutes', 'Minutes'), ('hours', 'Hours'),
                                   ('work_days', 'Work Days'),
                                   ('days', 'Days'), ('weeks', 'Weeks'),
                                   ('months', 'Months')],
                                  string="Interval units",
                                  default='minutes')
    cron_restrictions = fields.Selection([("create", "Newly created"),
                                          ("update", "Newly updated"),
                                          ("all", "All")],
                                         string="Restrictions",
                                         default="all")
    base_action_rules = fields.Many2many('base.action.rule',
                                         string='Action Rules')

    last_execution = fields.Datetime()

    @api.one
    def unlink(self):
        if self.cron:
            self.cron.unlink()
        if self.base_action_rules:
            for bar in self.base_action_rules:
                bar.server_action_ids.unlink()
            self.base_action_rules.unlink()

        return super(CenitDataTypeTrigger, self).unlink()

    @api.one
    def sync(self):
        if not self.data_type.enabled:
            if self.cron:
                self.cron.unlink()
            if self.base_action_rules:
                for bar in self.base_action_rules:
                    bar.server_action_ids.unlink()
                self.base_action_rules.unlink()

        if self.name == 'only_manual':

            if self.base_action_rules:
                for bar in self.base_action_rules:
                    bar.server_action_ids.unlink()
                self.base_action_rules.unlink()

            elif self.cron:
                self.cron.unlink()

        if self.name == 'interval':
            ic_obj = self.env['ir.cron']

            if self.cron:
                vals_ic = {
                    'name':
                    'send_%s_%s' %
                    (self.cron_restrictions, self.data_type.model.model),
                    'interval_number':
                    self.cron_lapse,
                    'interval_type':
                    self.cron_units,
                }
                _logger.info("\n\nWRITE IC: %s\n", vals_ic)
                self.cron.write(vals_ic)
            else:
                vals_ic = {
                    'name':
                    'send_%s_%s' %
                    (self.cron_restrictions, self.data_type.model.model),
                    'interval_number':
                    self.cron_lapse,
                    'interval_type':
                    self.cron_units,
                    'numbercall':
                    -1,
                    'model':
                    'cenit.data_type',
                    'function':
                    'perform_scheduled_action',
                    'args':
                    '(%s,)' % str(self.data_type.id)
                }
                _logger.info("\n\nCREATE IC: %s\n", vals_ic)
                ic = ic_obj.create(vals_ic)
                self.with_context(local=True).write({'cron': ic.id})

            if self.base_action_rules:
                for bar in self.base_action_rules:
                    bar.server_action_ids.unlink()
                self.base_action_rules.unlink()

        elif self.name in ('on_create', 'on_write', 'on_create_or_write'):
            ias_obj = self.env['ir.actions.server']
            bar_obj = self.env['base.action.rule']

            if self.base_action_rules:
                for bar in self.base_action_rules:
                    bar.server_action_ids.unlink()
                self.base_action_rules.unlink()

            rules = []
            action_name = 'send_one_%s_as_%s' % (self.data_type.model.model,
                                                 self.data_type.cenit_root)
            cd = "self.pool.get('{}').browse(cr, uid, {}).trigger_flows(obj)".format(
                self.data_type._name, self.data_type.id)
            vals_ias = {
                'name': action_name,
                'model_id': self.data_type.model.id,
                'state': 'code',
                'code': cd
            }
            ias = ias_obj.create(vals_ias)
            vals_bar = {
                'name': action_name,
                'active': True,
                'kind': self.name,
                'model_id': self.data_type.model.id,
                'server_action_ids': [(6, False, [ias.id])]
            }
            bar = bar_obj.create(vals_bar)
            rules.append((4, bar.id, False))

            self.with_context(local=True).write({'base_action_rules': rules})

            if self.cron:
                self.cron.unlink()

        return True
Example #21
0
class MgmtSystemAction(models.Model):
    """Model class that manage action."""

    _name = "mgmtsystem.action"
    _description = "Action"
    _inherit = ['mail.thread', 'ir.needaction_mixin']

    def _default_company(self):
        """Return the user company id."""
        return self.env.user.company_id

    def _default_owner(self):
        """Return the user."""
        return self.env.user

    def _default_stage(self):
        """Return the default stage."""
        return self.env['mgmtsystem.action.stage'].search(
            [('is_starting', '=', True)], limit=1)

    @api.model
    def _elapsed_days(self, dt1_text, dt2_text):
        res = 0
        if dt1_text and dt2_text:
            dt1 = fields.Datetime.from_string(dt1_text)
            dt2 = fields.Datetime.from_string(dt2_text)
            res = (dt2 - dt1).days
        return res

    @api.depends('opening_date', 'create_date')
    def _compute_number_of_days_to_open(self):
        for action in self:
            action.number_of_days_to_close_open = action._elapsed_days(
                action.create_date, action.opening_date)

    @api.depends('date_closed', 'create_date')
    def _compute_number_of_days_to_close(self):
        for action in self:
            action.number_of_days_to_close_open = action._elapsed_days(
                action.create_date, action.date_closed)

    name = fields.Char('Subject', required=True)
    active = fields.Boolean('Active', default=True)
    date_deadline = fields.Date('Deadline')

    create_date = fields.Datetime('Create Date',
                                  readonly=True,
                                  default=fields.datetime.now())
    cancel_date = fields.Datetime('Cancel Date', readonly=True)
    opening_date = fields.Datetime('Opening Date', readonly=True)
    date_closed = fields.Datetime('Closed Date', readonly=True)
    number_of_days_to_open = fields.Integer(
        '# of days to open',
        compute=_compute_number_of_days_to_open,
        store=True)
    number_of_days_to_close = fields.Integer(
        '# of days to close',
        compute=_compute_number_of_days_to_close,
        store=True)
    reference = fields.Char('Reference',
                            required=True,
                            readonly=True,
                            default="NEW")
    user_id = fields.Many2one('res.users',
                              'Responsible',
                              default=_default_owner,
                              required=True)
    description = fields.Text('Description')
    type_action = fields.Selection(
        [('immediate', 'Immediate Action'),
         ('correction', 'Corrective Action'),
         ('prevention', 'Preventive Action'),
         ('improvement', 'Improvement Opportunity')],
        'Response Type',
        required=True)

    system_id = fields.Many2one('mgmtsystem.system', 'System')
    company_id = fields.Many2one('res.company',
                                 'Company',
                                 default=_default_company)
    stage_id = fields.Many2one('mgmtsystem.action.stage',
                               'Stage',
                               default=_default_stage)

    @api.model
    def _stage_groups(self, present_ids, domain, **kwargs):
        """This method is used by Kanban view to show empty stages."""
        # perform search
        # We search here only stage ids
        stage_ids = self.env['mgmtsystem.action.stage']._search([])
        # We search here stages objects
        result = self.env['mgmtsystem.action.stage'].search([]).name_get()
        # restore order of the search
        result.sort(
            lambda x, y: cmp(stage_ids.index(x[0]), stage_ids.index(y[0])))
        return result, None

    _group_by_full = {'stage_id': _stage_groups}

    @api.model
    def _get_stage_new(self):
        return self.env['mgmtsystem.action.stage'].search(
            [('is_starting', '=', True)], limit=1)

    @api.model
    def _get_stage_open(self):
        return self.env.ref('mgmtsystem_action.stage_open')

    @api.model
    def _get_stage_close(self):
        return self.env.ref('mgmtsystem_action.stage_close')

    @api.model
    def _get_stage_cancel(self):
        return self.env.ref('mgmtsystem_action.stage_cancel')

    @api.multi
    def case_open(self):
        """ Opens case """
        for case in self:
            case.write({'active': True, 'stage_id': case._get_stage_open().id})
        return True
Example #22
0
class MrpSegment(models.Model):
    _name = "mrp.segment"
    _description = "MRP Segment"
    _rec_name = 'name'

    def _default_stock_location(self):
        try:
            warehouse = self.env['ir.model.data'].get_object(
                'stock', 'warehouse0')
            return warehouse.lot_stock_id.id
        except:
            return False

    name = fields.Char(string=_('Segment Reference'),
                       required=True,
                       readonly=True,
                       states={'draft': [('readonly', False)]},
                       help=_('Segment Name.'))

    date = fields.Datetime(
        string=_('Segment Date'),
        required=True,
        readonly=True,
        default=fields.Datetime.now,
        help=_('The date that will be used for the segment.'))

    state = fields.Selection([('draft', 'Draft'), ('cancel', 'Cancelled'),
                              ('confirm', 'In Progress'),
                              ('done', 'Validated')],
                             string=_('Status'),
                             readonly=True,
                             select=True,
                             default='draft',
                             copy=False)

    location_id = fields.Many2one('stock.location',
                                  string=_('Segment Location'),
                                  required=True,
                                  readonly=True,
                                  states={'draft': [('readonly', False)]},
                                  default=_default_stock_location)

    company_id = fields.Many2one('res.company',
                                 string=_('Company'),
                                 required=True,
                                 select=True,
                                 readonly=True,
                                 default=lambda self: self.env.user.company_id,
                                 states={'draft': [('readonly', False)]})

    line_ids = fields.One2many('mrp.segment.line',
                               'segment_id',
                               string=_('Manufacturing Order Line'),
                               readonly=False,
                               states={'done': [('readonly', True)]},
                               help=_("Segment Lines."),
                               copy=True)

    @api.multi
    def prepare_segment(self):
        for segment in self:
            line_ids = [line.id for line in segment.line_ids]
            if not line_ids:
                vals = self._get_segment_lines()

                for production_line in vals:
                    self.env['mrp.segment.line'].create(production_line)

        return self.write({'state': 'confirm'})

    def _get_segment_lines(self):
        domain = [('missing_qty', '>', 0),
                  ('production_id.location_dest_id', '=', self.location_id.id),
                  ('production_id.state', 'in', ["confirmed", "ready"])]

        segment_lines = self.env['mrp.production.product.line'].search(domain)

        vals = []
        for line in segment_lines:
            product_line = dict((fn, 0.0) for fn in [
                'segment_id', 'mrp_production_id', 'product_id', 'quantity',
                'sale_name', 'mrp_production_line_id'
            ])

            product_line['segment_id'] = self.id
            product_line['mrp_production_id'] = line.production_id.id
            product_line['product_id'] = line.product_id.id
            product_line['quantity'] = line.missing_qty
            product_line['sale_name'] = line.production_id.sale_name
            product_line['mrp_production_line_id'] = line.id
            vals.append(product_line)
        return vals
Example #23
0
class TestScript(models.Model):
    _name = "hc.res.test.script"
    _description = "Test Script"

    url = fields.Char(
        string="URI",
        required="True",
        help="Logical uri to reference this test script (globally unique).")
    identifier_id = fields.Many2one(
        comodel_name="hc.test.script.identifier",
        string="Identifier",
        help="Additional identifier for the test script.")
    version = fields.Char(string="Version",
                          help="Business version of the test script.")
    name = fields.Char(string="Name",
                       required="True",
                       help="Name for this test script (Computer friendly).")
    title = fields.Text(string="Title",
                        help="Name for this test script (Human friendly).")
    status = fields.Selection(
        string="Test Script Status",
        required="True",
        selection=[("draft", "Draft"), ("active", "Active"),
                   ("retired", "Retired")],
        help=
        "The status of this test script. Enables tracking the life-cycle of the content."
    )
    is_experimental = fields.Boolean(
        string="Experimental", help="If for testing purposes, not real usage.")
    publisher = fields.Char(
        string="Publisher",
        help="Name of the publisher (Organization or individual).")
    contact_ids = fields.One2many(comodel_name="hc.test.script.contact",
                                  inverse_name="test_script_id",
                                  string="Contacts",
                                  help="Contact details for the publisher.")
    date = fields.Datetime(string="Date", help="Date this was last changed.")
    description = fields.Text(
        string="Description",
        help="Natural language description of the test script.")
    use_context_ids = fields.One2many(
        comodel_name="hc.test.script.use.context",
        inverse_name="test_script_id",
        string="Use Contexts",
        help="Content intends to support these contexts.")
    jurisdiction_ids = fields.Many2many(
        comodel_name="hc.vs.jurisdiction",
        relation="test_script_jurisdiction_rel",
        string="Jurisdictions",
        help="Intended jurisdiction for test script (if applicable).")
    purpose = fields.Text(string="Purpose",
                          help="Why this test script is defined.")
    copyright = fields.Text(string="Copyright",
                            help="Use and/or publishing restrictions.")
    profile_ids = fields.One2many(comodel_name="hc.test.script.profile",
                                  inverse_name="test_script_id",
                                  string="Profiles",
                                  help="Reference of the validation profile.")
    origin_ids = fields.One2many(
        comodel_name="hc.test.script.origin",
        inverse_name="test_script_id",
        string="Origins",
        help=
        "An abstract server representing a client or sender in a message exchange."
    )
    destination_ids = fields.One2many(
        comodel_name="hc.test.script.destination",
        inverse_name="test_script_id",
        string="Destinations",
        help=
        "An abstract server representing a destination or receiver in a message exchange."
    )
    metadata_ids = fields.One2many(
        comodel_name="hc.test.script.metadata",
        inverse_name="test_script_id",
        string="Metadata",
        help=
        "Required capability that is assumed to function correctly on the FHIR server being tested."
    )
    fixture_ids = fields.One2many(
        comodel_name="hc.test.script.fixture",
        inverse_name="test_script_id",
        string="Fixtures",
        help=
        "Fixture in the test script - either by reference (uri) or embedded (Resource)."
    )
    variable_ids = fields.One2many(comodel_name="hc.test.script.variable",
                                   inverse_name="test_script_id",
                                   string="Variables",
                                   help="Placeholder for evaluated elements.")
    rule_ids = fields.One2many(comodel_name="hc.test.script.rule",
                               inverse_name="test_script_id",
                               string="Rules",
                               required="True",
                               help="The referenced rule within the ruleset.")
    ruleset_ids = fields.One2many(
        comodel_name="hc.test.script.ruleset",
        inverse_name="test_script_id",
        string="Rulesets",
        help="Assert ruleset used within the test script.")
    setup_ids = fields.One2many(
        comodel_name="hc.test.script.setup",
        inverse_name="test_script_id",
        string="Setups",
        help="A series of required setup operations before tests are executed."
    )
    test_ids = fields.One2many(comodel_name="hc.test.script.test",
                               inverse_name="test_script_id",
                               string="Tests",
                               help="A test in this script.")
    teardown_ids = fields.One2many(comodel_name="hc.test.script.teardown",
                                   inverse_name="test_script_id",
                                   string="Teardowns",
                                   help="A series of required clean up steps.")
Example #24
0
class AccountInvoicePresentation(models.Model):
    _name = 'account.invoice.presentation'

    def get_period(self):
        """
        Genera un string con el periodo seleccionado.
        :return: string con periodo ej : '201708'
        """
        split_from = self.date_from.split('-')
        return split_from[0] + split_from[1]

    def get_invoices(self):
        return self.env['account.invoice'].search([
            ('state', 'not in', ('cancel', 'draft')),
            ('date', '>=', self.date_from),
            ('date', '<=', self.date_to),
            ('company_id', '=', self.company_id.id),
        ])

    @staticmethod
    def get_total_notTaxed_taxes(invoice, data):
        not_taxed_taxes = invoice.tax_line_ids.filtered(
            lambda t: t.tax_id in [data.tax_sale_ng, data.tax_purchase_ng])
        return sum(not_taxed_taxes.mapped('amount'))

    def validate_invoices(self, data):
        """
        Validamos que las facturas tengan los datos necesarios.
        """

        foreign_fiscal_positions = [
            self.env.ref(
                'l10n_ar_afip_tables.account_fiscal_position_cliente_ext'),
            self.env.ref(
                'l10n_ar_afip_tables.account_fiscal_position_prov_ext'),
        ]

        errors = []
        for partner in self.invoices.mapped('partner_id'):
            if not partner.property_account_position_id:
                errors.append("El partner {} no posee posicion fiscal.".format(
                    partner.name))

            if not partner.partner_document_type_id:
                errors.append(
                    "El partner {} no posee tipo de documento.".format(
                        partner.name))

            if not partner.vat and partner.property_account_position_id not in foreign_fiscal_positions:
                errors.append(
                    "El partner {} no posee numero de documento.".format(
                        partner.name))

            if partner.property_account_position_id in foreign_fiscal_positions and not \
                    (partner.country_id and partner.country_id.vat):
                errors.append(
                    "El partner {} no posee pais con documento.".format(
                        partner.name))

        for invoice in self.invoices:

            if not invoice.move_id.line_ids.filtered(
                    lambda x: x.account_id == invoice.account_id):
                errors.append(
                    "La cuenta de la factura {} no se encuentra en el asiento de la misma."
                    .format(invoice.name_get()[0][1]))

            if invoice.amount_total == 0:
                errors.append("El total de la factura {} es cero.".format(
                    invoice.name))

            if not invoice.move_id.line_ids:
                errors.append(
                    "La factura {} no posee lineas de asientos.".format(
                        invoice.name))

            if self.get_total_notTaxed_taxes(invoice, data):
                errors.append(
                    "La factura {} posee montos en los impuestos no gravados.".
                    format(invoice.name))

        if errors:
            raise Warning(
                "ERROR\nLa presentacion no pudo ser generada por los siguientes motivos:\n{}"
                .format("\n".join(errors)))

    def generate_header_file(self):
        raise NotImplementedError

    def generate_presentations(self, data):
        purchase_builder = presentation.Presentation('ventasCompras',
                                                     'comprasCbte')
        purchase_iva_builder = presentation.Presentation(
            'ventasCompras', 'comprasAlicuotas')
        purchase_import_builder = presentation.Presentation(
            'ventasCompras', 'comprasImportaciones')
        sale_builder = presentation.Presentation('ventasCompras', 'ventasCbte')
        sale_iva_builder = presentation.Presentation('ventasCompras',
                                                     'ventasAlicuotas')

        self.purchase_presentation = PurchaseInvoicePresentation(
            data=data,
            builder=purchase_builder,
            with_prorate=self.with_prorate)
        self.purchase_iva_presentation = PurchaseIvaPresentation(
            data=data, builder=purchase_iva_builder)
        self.purchase_import_presentation = PurchaseImportationPresentation(
            data=data, builder=purchase_import_builder)
        self.sale_presentation = SaleInvoicePresentation(data=data,
                                                         builder=sale_builder)
        self.sale_iva_presentation = SaleVatInvoicePresentation(
            data=data, builder=sale_iva_builder)

    def generate_files(self):
        """
        Genera todas las presentaciones. A cada archivo generado le pone un nombre que se usa para
        crear el nombre del fichero. Luego llama a la funcion que colocara todos los archivos en
        un fichero zip.
        """
        # Traemos datos generales
        invoice_proxy = self.env['account.invoice']
        data = GeneralData(invoice_proxy)

        # Traemos y validamos todas las facturas del periodo seleccionado
        self.invoices = self.get_invoices()
        self.validate_invoices(data)

        # Instanciamos presentaciones
        self.generate_presentations(data)

        # Creamos nombre base para los archivos
        base_name = "REGINFO_CV_{}" + self.get_period() + ".{}"

        header_file = self.generate_header_file()
        header_file.file_name = base_name.format("CABECERA_", "txt")

        sale_file = self.sale_presentation.generate(self.invoices)
        sale_file.file_name = base_name.format("VENTAS_CBTE_", "txt")

        sale_vat_file = self.sale_iva_presentation.generate(self.invoices)
        sale_vat_file.file_name = base_name.format("VENTAS_ALICUOTAS_", "txt")

        purchase_file = self.purchase_presentation.generate(self.invoices)
        purchase_file.file_name = base_name.format("COMPRAS_CBTE_", "txt")

        purchase_vat_file = self.purchase_iva_presentation.generate(
            self.invoices)
        purchase_vat_file.file_name = base_name.format("COMPRAS_ALICUOTAS_",
                                                       "txt")

        purchase_imports_file = self.purchase_import_presentation.generate(
            self.invoices)
        purchase_imports_file.file_name = base_name.format(
            "COMPRAS_IMPORTACION_", "txt")

        fiscal_credit_service_import_file = self.generate_fiscal_credit_service_import_file(
        )
        fiscal_credit_service_import_file.file_name = base_name.format(
            "CREDITO_FISCAL_SERVICIOS_", "txt")

        # Se genera el archivo zip que contendra los archivos
        reginfo_zip_file = self.generate_reginfo_zip_file([
            header_file, sale_file, sale_vat_file, purchase_file,
            purchase_vat_file, purchase_imports_file,
            fiscal_credit_service_import_file
        ])
        #Se escriben en la presentacion los datos generados
        self.write({
            'generation_time':
            datetime.now(),
            'header_filename':
            header_file.file_name,
            'header_file':
            header_file.get_encoded_string(),
            'sale_filename':
            sale_file.file_name,
            'sale_file':
            sale_file.get_encoded_string(),
            'sale_vat_filename':
            sale_vat_file.file_name,
            'sale_vat_file':
            sale_vat_file.get_encoded_string(),
            'purchase_filename':
            purchase_file.file_name,
            'purchase_file':
            purchase_file.get_encoded_string(),
            'purchase_vat_filename':
            purchase_vat_file.file_name,
            'purchase_vat_file':
            purchase_vat_file.get_encoded_string(),
            'purchase_imports_filename':
            purchase_imports_file.file_name,
            'purchase_imports_file':
            purchase_imports_file.get_encoded_string(),
            'fiscal_credit_service_import_filename':
            fiscal_credit_service_import_file.file_name,
            'fiscal_credit_service_import_file':
            fiscal_credit_service_import_file.get_encoded_string(),
            'reginfo_zip_filename':
            base_name.format("", "zip"),
            'reginfo_zip_file':
            reginfo_zip_file,
        })

    name = fields.Char(
        string="Nombre",
        required=True,
    )

    generation_time = fields.Datetime(string="Fecha y hora de generacion", )

    date_from = fields.Date(
        string="Desde",
        required=True,
    )

    date_to = fields.Date(
        string="Hasta",
        required=True,
    )

    sequence = fields.Char(
        string="Secuencia",
        size=2,
        required=True,
        default='00',
    )

    with_prorate = fields.Boolean(
        string="Con prorrateo",
        default=True,
    )

    header_file = fields.Binary(
        string="Cabecera",
        filename="header_filename",
    )

    header_filename = fields.Char(string="Nombre de archivo de cabecera", )

    sale_file = fields.Binary(
        string="Ventas",
        filename="sale_filename",
    )

    sale_filename = fields.Char(string="Nombre de archivo de ventas", )

    sale_vat_file = fields.Binary(
        string="Ventas alicuotas",
        filename="sale_vat_filename",
    )

    sale_vat_filename = fields.Char(
        string="Nombre de archivo de ventas alicuotas", )

    purchase_file = fields.Binary(
        string="Compras",
        filename="purchase_filename",
    )

    purchase_filename = fields.Char(string="Nombre de archivo de compras", )

    purchase_vat_file = fields.Binary(
        string="Compras alicuotas",
        filename="purchase_vat_filename",
    )

    purchase_vat_filename = fields.Char(
        string="Nombre de archivo de compras alicuotas", )

    purchase_imports_file = fields.Binary(
        string="Compras importaciones",
        filename="purchase_imports_filename",
    )

    purchase_imports_filename = fields.Char(
        string="Nombre de archivo de compras importaciones", )

    fiscal_credit_service_import_file = fields.Binary(
        string="Credito fiscal de importacion de servicios",
        filename="fiscal_credit_service_import_filename",
    )

    fiscal_credit_service_import_filename = fields.Char(
        string=
        "Nombre de archivo de credito fiscal de importacion de servicios", )

    reginfo_zip_file = fields.Binary(
        string="ZIP de regimen de informacion",
        filename="reginfo_zip_filename",
    )

    reginfo_zip_filename = fields.Char(
        string="Nombre de archivo ZIP de regimen de informacion", )

    company_id = fields.Many2one(
        string="Compania",
        comodel_name="res.company",
        required=True,
        default=lambda self: self.pool['res.company']._company_default_get(
            self.env.user.company_id),
    )

    @staticmethod
    def generate_fiscal_credit_service_import_file():
        """
        Esta presentacion no se utiliza actualmente
        """
        raise NotImplementedError

    @staticmethod
    def generate_reginfo_zip_file(files):
        """
        Instancia el exportador en zip de ficheros de la API, y exporta todas las presentaciones.
        :param files: generators de las presentaciones
        :return: archivo zip
        """
        exporter = presentation.PresentationZipExporter()
        map(lambda file: exporter.add_element(file), files)
        return exporter.export_elements()

    @api.constrains('date_from', 'date_to')
    def check_dates(self):
        if self.date_from > self.date_to:
            raise ValidationError(
                "La fecha 'desde' no puede ser mayor a la fecha 'hasta'.")
Example #25
0
class maintenance_project(models.Model):
    _inherit = 'maintenance.project'

    state = fields.Selection(
        selection=[('draft', 'Draft'), (
            'quotation_todo',
            'Quote To Do'), ('quotation_done',
                             'Quote Done'), ('active',
                                             'Active'), ('disabled',
                                                         'Disabled')])
    quotation_todo_date = fields.Datetime('Ask Date',
                                          readonly=True,
                                          translate=True)
    quotation_done_date = fields.Datetime('Date Done',
                                          readonly=True,
                                          translate=True)
    quotation_prices = fields.One2many('maintenance.project.quotation.price',
                                       'project_id', 'Quotation prices')

    @api.one
    def _get_mail_users(self):
        #TODO: Add filter in another module to filter Project Warehouse with user warehouse - In order to extend it easily, created function _get_mail_users
        """
        @return users:A recordset with users
        """
        users = self.env['res.users'].search([
            ('receive_project_quotation_request', '=', True)
        ])

        return users

    # Send a mail to people that belongs to the same sale shop and
    # whom have checked that they want to be warned
    @api.one
    def _send_todo_mail(self):
        res = False

        if (not self.sale_order_id):
            return False

        body = _(
            'A new maintenance quotation(Project : %s) has just been asked by %s<br/>'
        ) % (self.code, self.env.user.name)

        for user in self._get_mail_users():
            self.env['mail.mail'].create({
                'email_from':
                self.env.user.partner_id.email,
                'email_to':
                user.partner_id.email,
                'subject':
                _('New maintenance quotation asked: %s') % (self.code),
                'body_html':
                body,
                'res_id':
                self.id,
                'model':
                'maintenance.project'
            })
            res = True

        return res

    # Send a confirmation mail to the salesman linked to the sale
    @api.one
    def _send_done_mail(self):
        res = False

        if (not self.sale_order_id):
            return False

        body = _('A maintenance quotation(%s) has just been done by %s<br/>'
                 ) % (self.code, self.env.user.name)

        for user in self._get_mail_users():
            self.env['mail.mail'].create({
                'email_from':
                self.env.user,
                'email_to':
                user.partner_id.email,
                'subject':
                _('Maintenance quotation done: %s') % (self.code),
                'body_html':
                body,
                'res_id':
                self.id,
                'model':
                'maintenance.project'
            })
            res = True

        return res

    @api.one
    def draft(self):
        self.state = 'draft'

    @api.one
    def quotation_todo(self):
        self.state = 'quotation_todo'
        self.quotation_todo_date = datetime.now()
        self._send_todo_mail()
        return True

    @api.one
    def quotation_done(self):
        self.state = 'quotation_done'
        self.quotation_done_date = datetime.now()
        self._send_done_mail()

    @api.one
    def active(self):
        self.state = 'active'

    @api.one
    def disabled(self):
        self.state = 'disabled'

    ''' UNUSED
    def _get_status(self,cr,uid,ids):
        
        
        return False
    '''

    @api.one
    def generate_quotation_prices(self):

        for project_type in self.env['maintenance.project.type'].search([]):

            #find contract type and associated budget rules
            budget_rules = self.env['maintenance.project.budget.rule'].search([
                ('project_type_id', '=', project_type.id)
            ])

            total_cost_price = 0
            total_sale_price = 0
            for budget_line in self.budget_lines:
                budget = budget_rules.filtered(
                    lambda r: r.intervention_type_id == budget_line.
                    intervention_type_id)
                if not budget_line.intervention_type_id or not budget.mapped(
                        'budget_line_type_id'):
                    raise Warning(
                        _('Please configure budget rule for project type "%s", intervention type "%s" and budget line type "%s".'
                          ) % (project_type.name,
                               budget_line.intervention_type_id.name,
                               budget_line.budget_line_type_id.name))

                if budget.filtered(
                        lambda r: r.budget_line_type_id == budget_line.
                        budget_line_type_id and r.included):
                    total_cost_price = total_cost_price + budget_line.cost_price * budget_line.quantity
                    total_sale_price = total_sale_price + budget_line.sale_price * budget_line.quantity

            self.env['maintenance.project.quotation.price'].create({
                'project_id':
                self.id,
                'project_type_id':
                project_type.id,
                'brut_sale_price':
                total_sale_price,
                'cost_price':
                total_cost_price
            })

        return True
Example #26
0
class StockDdT(models.Model):

    _inherit = 'stock.ddt'

    #imposta l'ora di creazione del ddt sempre a 00:00:00 indipendentemente dal timezone
    def _getDefaultDate(self):
        src_tstamp_str = tools.datetime.now().strftime('%Y-%m-%d')
        dst_format = "%Y-%m-%d %H:%M:%S"  #format you want to get time in.
        dst_tz_name = self.env.user.tz
        to_date_time = (datetime.datetime.combine(datetime.datetime.now(),
                                                  datetime.time(0, 0)))

        return to_date_time

    def _get_company_default(self):
        if self.partner_id and self.partner_id.company_id:
            return self.partner_id.company_id
        return self.env['res.users'].browse(self._uid).company_id

    weight = fields.Float(string='Peso', copy=False)
    weight_net = fields.Float(string='Peso Netto', copy=False)

    date_done = fields.Date(string='Data consegna')

    carrier_id = fields.Many2one('delivery.carrier', string='Carrier')

    company_id = fields.Many2one('res.company',
                                 string='Company',
                                 default=_get_company_default)

    incoterm_id = fields.Many2one(
        'stock.incoterms',
        string='Condizione di Consegna (Incoterm)',
        help=
        "International Commercial Terms are a series of predefined commercial terms used in international transactions."
    )

    user_id = fields.Many2one('res.users', string='Commerciale')

    payment_term = fields.Many2one('account.payment.term',
                                   string='Termine di Pagamento')

    invoice_id = fields.Many2one('account.invoice', string='Fattura')

    to_be_invoiced = fields.Boolean(string='Da Fatturare',
                                    compute='_get_to_be_invoiced',
                                    store=True)

    picking_ids_return = fields.One2many('stock.picking',
                                         'ddt_id',
                                         string='Returned Pickings',
                                         readonly=True,
                                         compute='_get_pickings_return')

    ddt_lines_return = fields.One2many('stock.move',
                                       'ddt_id',
                                       string='Returned DdT Line',
                                       readonly=True,
                                       compute='_get_lines_return')

    total_value = fields.Float(string='Imponibile Totale',
                               compute='_get_total_value',
                               store=False,
                               copy=False)

    note2 = fields.Text('Note')

    ddt_date = fields.Date('Data DDT',
                           required=False,
                           store=True,
                           compute='_compute_ddt_date')

    date = fields.Datetime(required=True, default=_getDefaultDate)

    @api.depends('date')
    def _compute_ddt_date(self):
        for record in self:
            if not record.date:
                return
            date_obj = datetime.datetime.strptime(self.date,
                                                  '%Y-%m-%d %H:%M:%S')
            record.ddt_date = date_obj.date()

    @api.multi
    #@api.depends('picking_ids', 'picking_ids.state')
    def _get_total_value(self):
        for ddt in self:
            tot = 0.0
            for ddt_line in ddt.ddt_lines:
                if ddt_line.procurement_id and ddt_line.procurement_id.sale_line_id:
                    line = ddt_line.procurement_id.sale_line_id
                    tot += line.price_subtotal * (ddt_line.product_uom_qty /
                                                  line.product_uom_qty)
                elif ddt_line.procurement_id and ddt_line.procurement_id.purchase_line_id:
                    line = ddt_line.procurement_id.purchase_line_id
                    tot += line.price_subtotal * (ddt_line.product_uom_qty /
                                                  line.product_qty)
                elif ddt_line.purchase_line_id:
                    line = ddt_line.purchase_line_id
                    tot += line.price_subtotal * (ddt_line.product_uom_qty /
                                                  line.product_qty)

            for ddt_line in ddt.ddt_lines_return:
                if ddt_line.procurement_id and ddt_line.procurement_id.sale_line_id:
                    line = ddt_line.procurement_id.sale_line_id
                    tot -= line.price_subtotal * (ddt_line.product_uom_qty /
                                                  line.product_uom_qty)
                elif ddt_line.procurement_id and ddt_line.procurement_id.purchase_line_id:
                    line = ddt_line.procurement_id.purchase_line_id
                    tot -= line.price_subtotal * (ddt_line.product_uom_qty /
                                                  line.product_qty)
                elif ddt_line.purchase_line_id:
                    line = ddt_line.purchase_line_id
                    tot -= line.price_subtotal * (ddt_line.product_uom_qty /
                                                  line.product_qty)
            ddt.total_value = tot

    @api.multi
    @api.depends('picking_ids', 'picking_ids.invoice_state')
    def _get_to_be_invoiced(self):
        for ddt in self:
            ddt.to_be_invoiced = False
            for picking in ddt.picking_ids:
                if picking.invoice_state == '2binvoiced':
                    ddt.to_be_invoiced = True
                    break

    @api.multi
    def _get_pickings_return(self):

        for ddt in self:
            for picking in ddt.picking_ids:
                back_ids = self.pool.get('stock.picking').search(
                    self._cr,
                    self._uid, [('origin', '=', picking.name)],
                    context=self._context)
                if back_ids:
                    ddt.picking_ids_return |= self.pool.get(
                        'stock.picking').browse(self._cr, self._uid, back_ids)

        for ddt in self:
            for picking in ddt.picking_ids_return:
                ddt.ddt_lines_return |= picking.move_lines

    @api.multi
    def _get_lines_return(self):
        for ddt in self:
            for picking in ddt.picking_ids:
                ddt.ddt_lines |= picking.move_lines

    @api.onchange('partner_id')
    def onchange_partner_id(self):
        self.delivery_address_id = None

    @api.multi
    def set_number(self):
        for ddt in self:
            if not ddt.name:
                for pick in ddt.picking_ids:
                    if pick.picking_type_id.ddt_sequence_id:
                        ddt_number = self.pool.get('ir.sequence').next_by_id(
                            self._cr, self._uid,
                            pick.picking_type_id.ddt_sequence_id.id)
                        if ddt_number:
                            ddt.name = ddt_number
                            break

    @api.multi
    def action_confirm(self):
        for ddt in self:
            if not ddt.ddt_lines:
                raise except_orm(_('Errore!'),
                                 _('Non puoi confermare un DDT senza righe!'))
            self.write({
                'state': 'confirmed',
                'delivery_date': time.strftime('%Y-%m-%dT%H:%M:%S')
            })

    @api.one
    def copy(self, default=None):
        default = dict(default or {})
        default.update(name=None)
        return super(StockDdT, self).copy(default)

    def view_partner_pickings(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        if isinstance(ids, (int, long)):
            ids = [ids]

        t_partner_list = []

        for ddt_data in self.browse(cr, uid, ids, context):
            if ddt_data.partner_id:
                t_partner_list.append(ddt_data.partner_id.id)

        if t_partner_list:
            mod_obj = self.pool.get('ir.model.data')
            result = mod_obj.get_object_reference(
                cr, uid, 'l10n_it_ddt_makeover', 'view_picking_makeover_form')
            view_id = result and result[1] or False

            return {
                'domain':
                "[('picking_type_id.code','=','outgoing'),('invoice_state','in', ['2binvoiced','none']),('ddt_id','not in', ["
                + ','.join(map(str, ids)) + "]),('partner_id','in', [" +
                ','.join(map(str, t_partner_list)) +
                "]),'|',('ddt_id','=', None),('ddt_id','=', False)]",
                'name':
                _("Picking del Cliente"),
                'view_type':
                'form',
                'view_mode':
                'tree,form',
                'res_model':
                'stock.picking',
                'type':
                'ir.actions.act_window',
                'context':
                context,
                'views': [(False, 'tree'), (view_id, 'form')],
            }
        return True

    @api.multi
    def write(self, values):
        '''
        if 'ddt_date' in values and values['ddt_date']:
            values.update({'date': values.get('ddt_date')})
        '''
        return super(StockDdT, self).write(values)

    @api.model
    def create(self, values):
        return super(StockDdT, self).create(values)
Example #27
0
File: event.py Project: orgis/odoo
class event_registration(models.Model):
    _name = 'event.registration'
    _description = 'Attendee'
    _inherit = ['mail.thread', 'ir.needaction_mixin']
    _order = 'name, create_date desc'

    origin = fields.Char(
        string='Source Document',
        readonly=True,
        help=
        "Reference of the document that created the registration, for example a sale order"
    )
    event_id = fields.Many2one('event.event',
                               string='Event',
                               required=True,
                               readonly=True,
                               states={'draft': [('readonly', False)]})
    partner_id = fields.Many2one('res.partner',
                                 string='Contact',
                                 states={'done': [('readonly', True)]})
    date_open = fields.Datetime(string='Registration Date',
                                readonly=True,
                                default=lambda self: fields.datetime.now()
                                )  # weird crash is directly now
    date_closed = fields.Datetime(string='Attended Date', readonly=True)
    event_begin_date = fields.Datetime(string="Event Start Date",
                                       related='event_id.date_begin',
                                       readonly=True)
    event_end_date = fields.Datetime(string="Event End Date",
                                     related='event_id.date_end',
                                     readonly=True)
    company_id = fields.Many2one('res.company',
                                 string='Company',
                                 related='event_id.company_id',
                                 store=True,
                                 readonly=True,
                                 states={'draft': [('readonly', False)]})
    state = fields.Selection([('draft', 'Unconfirmed'),
                              ('cancel', 'Cancelled'), ('open', 'Confirmed'),
                              ('done', 'Attended')],
                             string='Status',
                             default='draft',
                             readonly=True,
                             copy=False,
                             track_visibility='onchange')
    email = fields.Char(string='Email')
    phone = fields.Char(string='Phone')
    name = fields.Char(string='Attendee Name', select=True)

    @api.one
    @api.constrains('event_id', 'state')
    def _check_seats_limit(self):
        if self.event_id.seats_availability == 'limited' and self.event_id.seats_max and self.event_id.seats_available < (
                1 if self.state == 'draft' else 0):
            raise ValidationError(_('No more seats available for this event.'))

    @api.multi
    def _check_auto_confirmation(self):
        if self._context.get('registration_force_draft'):
            return False
        if any(registration.event_id.state != 'confirm'
               or not registration.event_id.auto_confirm or (
                   not registration.event_id.seats_available
                   and registration.event_id.seats_availability == 'limited')
               for registration in self):
            return False
        return True

    @api.model
    def create(self, vals):
        registration = super(event_registration, self).create(vals)
        if registration._check_auto_confirmation():
            registration.sudo().confirm_registration()
        return registration

    @api.model
    def _prepare_attendee_values(self, registration):
        """ Method preparing the values to create new attendees based on a
        sale order line. It takes some registration data (dict-based) that are
        optional values coming from an external input like a web page. This method
        is meant to be inherited in various addons that sell events. """
        partner_id = registration.pop('partner_id', self.env.user.partner_id)
        event_id = registration.pop('event_id', False)
        data = {
            'name': registration.get('name', partner_id.name),
            'phone': registration.get('phone', partner_id.phone),
            'email': registration.get('email', partner_id.email),
            'partner_id': partner_id.id,
            'event_id': event_id and event_id.id or False,
        }
        data.update({
            key: registration[key]
            for key in registration.keys() if key in self._fields
        })
        return data

    @api.one
    def do_draft(self):
        self.state = 'draft'

    @api.one
    def confirm_registration(self):
        self.state = 'open'

        # auto-trigger after_sub (on subscribe) mail schedulers, if needed
        onsubscribe_schedulers = self.event_id.event_mail_ids.filtered(
            lambda s: s.interval_type == 'after_sub')
        onsubscribe_schedulers.execute()

    @api.one
    def button_reg_close(self):
        """ Close Registration """
        today = fields.Datetime.now()
        if self.event_id.date_begin <= today:
            self.write({'state': 'done', 'date_closed': today})
        else:
            raise UserError(
                _("You must wait for the starting day of the event to do this action."
                  ))

    @api.one
    def button_reg_cancel(self):
        self.state = 'cancel'

    @api.onchange('partner_id')
    def _onchange_partner(self):
        if self.partner_id:
            contact_id = self.partner_id.address_get().get('contact', False)
            if contact_id:
                contact = self.env['res.partner'].browse(contact_id)
                self.name = self.name or contact.name
                self.email = self.email or contact.email
                self.phone = self.phone or contact.phone

    @api.multi
    def message_get_suggested_recipients(self):
        recipients = super(event_registration,
                           self).message_get_suggested_recipients()
        try:
            for attendee in self:
                if attendee.partner_id:
                    attendee._message_add_suggested_recipient(
                        recipients,
                        partner=attendee.partner_id,
                        reason=_('Customer'))
                elif attendee.email:
                    attendee._message_add_suggested_recipient(
                        recipients,
                        email=attendee.email,
                        reason=_('Customer Email'))
        except AccessError:  # no read access rights -> ignore suggested recipients
            pass
        return recipients

    @api.multi
    def action_send_badge_email(self):
        """ Open a window to compose an email, with the template - 'event_badge'
            message loaded by default
        """
        self.ensure_one()
        template = self.env.ref('event.event_registration_mail_template_badge')
        compose_form = self.env.ref('mail.email_compose_message_wizard_form')
        ctx = dict(
            default_model='event.registration',
            default_res_id=self.id,
            default_use_template=bool(template),
            default_template_id=template.id,
            default_composition_mode='comment',
        )
        return {
            'name': _('Compose Email'),
            'type': 'ir.actions.act_window',
            'view_type': 'form',
            'view_mode': 'form',
            'res_model': 'mail.compose.message',
            'views': [(compose_form.id, 'form')],
            'view_id': compose_form.id,
            'target': 'new',
            'context': ctx,
        }
Example #28
0
class BuktiPotongTaxform1721A1(models.Model):
    _name = "l10n_id.bukti_potong_taxform_1721a1"
    _inherit = [
        "mail.thread",
        "tier.validation",
        "base.sequence_document",
        "base.workflow_policy_object",
        "base.cancel.reason_common",
        "custom.info.mixin",
    ]
    _description = "Bukti Potong Taxform 1721 A1"

    _state_from = ["draft", "confirm"]
    _state_to = ["done"]

    @api.model
    def _default_company_id(self):
        return self.env.user.company_id.id

    @api.model
    def _default_pemotong_pajak_id(self):
        return self.env.user.company_id.partner_id.id

    @api.model
    def _default_date(self):
        return datetime.now().strftime("%Y-%m-%d")

    @api.depends(
        "penghasilan_01",
        "penghasilan_02",
        "penghasilan_03",
        "penghasilan_04",
        "penghasilan_05",
        "penghasilan_06",
        "penghasilan_07",
    )
    @api.multi
    def _compute_penghasilan(self):
        for penghasilan in self:
            penghasilan.penghasilan_08 = 0.0
            penghasilan.penghasilan_08 = (
                penghasilan.penghasilan_01
                + penghasilan.penghasilan_02
                + penghasilan.penghasilan_03
                + penghasilan.penghasilan_04
                + penghasilan.penghasilan_05
                + penghasilan.penghasilan_06
                + penghasilan.penghasilan_07
            )

    @api.depends("penghasilan_08")
    @api.multi
    def _compute_jabatan(self):
        for jabatan in self:
            obj_biaya_jabatan = self.env["l10n_id.pph_21_biaya_jabatan"]
            perhitungan_biaya_jabatan = obj_biaya_jabatan.find(
                jabatan.date
            ).get_biaya_jabatan(
                0.0,
                jabatan.penghasilan_08,
                0,
                True,
            )
            jabatan.pengurang_09 = perhitungan_biaya_jabatan["biaya_jabatan_setahun"]

    @api.depends("pengurang_09", "pengurang_10")
    @api.multi
    def _compute_pengurang(self):
        for pengurang in self:
            pengurang.pengurang_11 = 0.0
            pengurang.pengurang_11 = pengurang.pengurang_09 + pengurang.pengurang_10

    @api.depends("penghasilan_08", "pengurang_11")
    @api.multi
    def _compute_penghasilan_netto(self):
        for pn in self:
            pn.perhitungan_12 = 0.0
            pn.perhitungan_12 = pn.penghasilan_08 - pn.pengurang_11

    @api.depends("perhitungan_12", "perhitungan_13")
    @api.multi
    def _compute_penghasilan_netto_setahun(self):
        for pns in self:
            pns.perhitungan_14 = 0.0
            pns.perhitungan_14 = pns.perhitungan_12 + pns.perhitungan_13

    @api.depends("wajib_pajak_ptkp_category_id", "date")
    @api.multi
    def _compute_ptkp(self):
        for getptkp in self:
            getptkp.perhitungan_15 = 0.0
            ptkp_category = getptkp.wajib_pajak_ptkp_category_id
            if ptkp_category:
                ptkp = ptkp_category.get_rate(getptkp.date)
                getptkp.perhitungan_15 = ptkp

    @api.depends(
        "perhitungan_14",
        "perhitungan_15",
    )
    @api.multi
    def _compute_pkp(self):
        for pkp in self:
            pkp.perhitungan_16 = 0.0
            if pkp.perhitungan_14 > pkp.perhitungan_15:
                pkp.perhitungan_16 = float(
                    int((pkp.perhitungan_14 - pkp.perhitungan_15) / 1000) * 1000
                )

    @api.depends(
        "perhitungan_16",
    )
    @api.multi
    def _compute_pph21(self):
        for pph in self:
            pph_21 = 0.0
            if pph.perhitungan_16 > 0:
                tunj_lain = (
                    pph.penghasilan_03
                    + pph.penghasilan_04
                    + pph.penghasilan_05
                    + pph.penghasilan_06
                )
                perhitungan_pph = pph.wajib_pajak_id.compute_pph_21_2110001(
                    1,
                    pph.end_tax_period_id.date_end,
                    pph.penghasilan_01,
                    pph.penghasilan_02,
                    tunj_lain,
                    pph.penghasilan_07,
                    pph.pengurang_10,
                    0,
                    0,
                    0,
                    0,
                    0,
                    0,
                    True,
                    not pph.wajib_pajak_karyawan_asing,
                )
                pph_21 = perhitungan_pph["pph"]
            pph.perhitungan_17 = pph_21

    @api.depends(
        "perhitungan_17",
        "perhitungan_18",
    )
    @api.multi
    def _compute_hutang_pph(self):
        for hutpph in self:
            hutpph.perhitungan_19 = hutpph.perhitungan_17 + hutpph.perhitungan_18

    name = fields.Char(
        string="# Form A1721 A1",
        required=True,
        default="/",
        copy=False,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    company_id = fields.Many2one(
        string="Company",
        comodel_name="res.company",
        required=True,
        default=lambda self: self._default_company_id(),
        ondelete="restrict",
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    kode_objek_pajak_id = fields.Many2one(
        string="Kode Objek Pajak",
        comodel_name="l10n_id.taxform_objek_pajak",
        ondelete="restrict",
        required=True,
    )
    date = fields.Date(
        string="Date",
        required=True,
        default=lambda self: self._default_date(),
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    tax_year_id = fields.Many2one(
        string="Tax Year",
        comodel_name="l10n_id.tax_year",
        compute=False,
        readonly=True,
        required=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    start_tax_period_id = fields.Many2one(
        string="Period Awal",
        comodel_name="l10n_id.tax_period",
        required=True,
        readonly=True,
        ondelete="restrict",
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    end_tax_period_id = fields.Many2one(
        string="Period Akhir",
        comodel_name="l10n_id.tax_period",
        compute=False,
        required=True,
        readonly=True,
        ondelete="restrict",
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    pemotong_pajak_id = fields.Many2one(
        string="Pemotong Pajak",
        comodel_name="res.partner",
        required=True,
        ondelete="restrict",
        default=lambda self: self._default_pemotong_pajak_id(),
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_id = fields.Many2one(
        string="Wajib Pajak",
        comodel_name="res.partner",
        required=True,
        ondelete="restrict",
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_npwp = fields.Char(
        string="NPWP",
        required=True,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_alamat = fields.Char(
        string="Alamat",
        readonly=True,
        required=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_alamat2 = fields.Char(
        string="Alamat2",
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_zip = fields.Char(
        string="ZIP",
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_kota = fields.Char(
        string="Kota",
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_state_id = fields.Many2one(
        string="State",
        comodel_name="res.country.state",
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_country_id = fields.Many2one(
        string="Negara",
        comodel_name="res.country",
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )

    wajib_pajak_nik = fields.Char(
        string="NIK",
        required=True,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_jenis_kelamin = fields.Selection(
        [
            ("male", "Male"),
            ("female", "Female"),
            ("other", "Other"),
        ],
        string="Jenis Kelamin",
        related="wajib_pajak_id.gender",
        store=False,
        readonly=True,
    )
    wajib_pajak_ptkp_category_id = fields.Many2one(
        string="PTKP Kategori",
        comodel_name="l10n_id.ptkp_category",
        readonly=True,
        required=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_job_position = fields.Char(
        string="Jabatan",
        readonly=True,
        required=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_karyawan_asing = fields.Boolean(
        string="Karyawan Asing",
        default=False,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    wajib_pajak_kode_negara = fields.Char(
        string="Kode Negara Domisili",
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    penghasilan_01 = fields.Float(
        string="GAJI/PENSIUN ATAU THT/JHT",
        default=0.0,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    penghasilan_02 = fields.Float(
        string="TUNJANGAN PPh",
        default=0.0,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    penghasilan_03 = fields.Float(
        string="TUNJANGAN LAINNYA, UANG LEMBUR DAN SEBAGAINYA",
        default=0.0,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    penghasilan_04 = fields.Float(
        string="HONORARIUM DAN IMBALAN LAIN SEJENISNYA",
        default=0.0,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    penghasilan_05 = fields.Float(
        string="PREMI ASURANSI YANG DIBAYAR PEMBERI KERJA",
        default=0.0,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    penghasilan_06 = fields.Float(
        string="PENERIMAAN DALAM BENTUK NATURA DAN KENIKMATAN \
           LAINNYA YANG DIKENAKAN PEMOTONGAN PPh PASAL 21",
        default=0.0,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    penghasilan_07 = fields.Float(
        string="TANTIEM, BONUS, GRATIFIKASI, JASA PRODUKSI DAN THR",
        default=0.0,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    penghasilan_08 = fields.Float(
        string="JUMLAH PENGHASILAN BRUTO (1 S.D. 7)",
        compute="_compute_penghasilan",
        store=True,
        readonly=True,
    )
    pengurang_09 = fields.Float(
        string="BIAYA JABATAN/BIAYA PENSIUN",
        compute="_compute_jabatan",
        store=True,
        readonly=True,
    )
    pengurang_10 = fields.Float(
        string="IURAN PENSIUN ATAU IURAN THT/JHT",
        default=0.0,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    pengurang_11 = fields.Float(
        string="JUMLAH PENGURANGAN (9 S.D. 10)",
        compute="_compute_pengurang",
        store=True,
        readonly=True,
    )
    perhitungan_12 = fields.Float(
        string="JUMLAH PENGHASILAN NETO (8 ­ 11)",
        compute="_compute_penghasilan_netto",
        store=True,
        readonly=True,
    )
    perhitungan_13 = fields.Float(
        string="PENGHASILAN NETO MASA SEBELUMNYA",
        default=0.0,
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    perhitungan_14 = fields.Float(
        string="JUMLAH PENGHASILAN NETO UNTUK PENGHITUNGAN PPh \
            PASAL 21 (SETAHUN/DISETAHUNKAN)",
        compute="_compute_penghasilan_netto_setahun",
        store=True,
        readonly=True,
    )
    perhitungan_15 = fields.Float(
        string="PENGHASILAN TIDAK KENA PAJAK (PTKP)",
        compute="_compute_ptkp",
        store=True,
        readonly=True,
    )
    perhitungan_16 = fields.Float(
        string="PENGHASILAN KENA PAJAK SETAHUN/DISETAHUNKAN",
        compute="_compute_pkp",
        store=True,
        readonly=True,
    )
    perhitungan_17 = fields.Float(
        string="PPh PASAL 21 ATAS PENGHASILAN KENA PAJAK SETAHUN/DISETAHUNKAN",
        compute="_compute_pph21",
        store=True,
        readonly=True,
    )
    perhitungan_18 = fields.Float(
        string="PPh PASAL 21 YANG TELAH DIPOTONG MASA SEBELUMNYA",
        readonly=True,
        default=0.0,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    perhitungan_19 = fields.Float(
        string="PPh PASAL 21 TERUTANG",
        compute="_compute_hutang_pph",
        store=True,
        readonly=True,
    )
    perhitungan_20 = fields.Float(
        string="PPh PASAL 21 DAN PPh PASAL 26 YANG TELAH DIPOTONG DAN DILUNASI",
        readonly=True,
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    company_partner_id = fields.Many2one(
        string="Company Partner",
        comodel_name="res.partner",
        store=True,
        readonly=True,
        related="company_id.partner_id",
    )

    ttd_id = fields.Many2one(
        string="TTD",
        comodel_name="res.partner",
        readonly=True,
        required=True,
        ondelete="restrict",
        states={
            "draft": [
                ("readonly", False),
            ],
        },
    )
    state = fields.Selection(
        string="State",
        selection=[
            ("draft", "Draft"),
            ("confirm", "Waiting for Approval"),
            ("done", "Done"),
            ("cancel", "Cancelled"),
        ],
        default="draft",
        required=True,
        readonly=True,
    )
    confirm_date = fields.Datetime(
        string="Confirmation Date",
        readonly=True,
        copy=False,
    )
    confirm_user_id = fields.Many2one(
        string="Confirmed By",
        comodel_name="res.users",
        readonly=True,
        copy=False,
    )
    done_date = fields.Datetime(
        string="Finish Date",
        readonly=True,
        copy=False,
    )
    done_user_id = fields.Many2one(
        string="Finished By",
        comodel_name="res.users",
        readonly=True,
        copy=False,
    )
    cancel_date = fields.Datetime(
        string="Cancel Date",
        readonly=True,
        copy=False,
    )
    cancel_user_id = fields.Many2one(
        string="Cancelled By",
        comodel_name="res.users",
        readonly=True,
        copy=False,
    )
    confirm_ok = fields.Boolean(
        string="Can Confirm",
        compute="_compute_policy",
    )
    restart_approval_ok = fields.Boolean(
        string="Can Restart Approval",
        compute="_compute_policy",
    )
    cancel_ok = fields.Boolean(
        string="Can Cancel",
        compute="_compute_policy",
    )
    restart_ok = fields.Boolean(
        string="Can Restart",
        compute="_compute_policy",
    )

    @api.multi
    def action_confirm(self):
        for record in self:
            record.write(record._prepare_confirm_data())
            record.request_validation()

    @api.multi
    def action_approve(self):
        for record in self:
            record.write(record._prepare_approve_data())

    @api.multi
    def action_cancel(self):
        for record in self:
            record.write(record._prepare_cancel_data())

    @api.multi
    def action_restart(self):
        for record in self:
            record.write(record._prepare_restart_data())

    @api.multi
    def _prepare_confirm_data(self):
        self.ensure_one()
        return {
            "state": "confirm",
            "confirm_date": fields.Datetime.now(),
            "confirm_user_id": self.env.user.id,
        }

    @api.multi
    def _prepare_approve_data(self):
        self.ensure_one()
        sequence = self._create_sequence()
        return {
            "state": "done",
            "done_date": fields.Datetime.now(),
            "done_user_id": self.env.user.id,
            "name": sequence,
        }

    @api.multi
    def _prepare_cancel_data(self):
        self.ensure_one()
        return {
            "state": "cancel",
            "cancel_date": fields.Datetime.now(),
            "cancel_user_id": self.env.user.id,
        }

    @api.multi
    def _prepare_restart_data(self):
        self.ensure_one()
        return {
            "state": "draft",
            "confirm_date": False,
            "confirm_user_id": False,
            "done_date": False,
            "done_user_id": False,
            "cancel_date": False,
            "cancel_user_id": False,
        }

    @api.multi
    def unlink(self):
        strWarning = _("You can only delete data on draft state")
        for record in self:
            if record.state != "draft":
                if not self.env.context.get("force_unlink", False):
                    raise UserError(strWarning)
        _super = super(BuktiPotongTaxform1721A1, self)
        _super.unlink()

    @api.multi
    def validate_tier(self):
        _super = super(BuktiPotongTaxform1721A1, self)
        _super.validate_tier()
        for record in self:
            if record.validated:
                record.action_approve()

    @api.multi
    def restart_validation(self):
        _super = super(BuktiPotongTaxform1721A1, self)
        _super.restart_validation()
        for record in self:
            record.request_validation()

    def _get_localdict(self):
        self.ensure_one()
        return {
            "env": self.env,
            "document": self,
        }

    @api.onchange("wajib_pajak_id")
    def onchange_wajib_pajak_id(self):
        if self.wajib_pajak_id:
            self.wajib_pajak_nik = self.wajib_pajak_id.ektp_number
            self.wajib_pajak_npwp = self.wajib_pajak_id.vat
            self.wajib_pajak_alamat = self.wajib_pajak_id.street
            self.wajib_pajak_alamat2 = self.wajib_pajak_id.street2
            self.wajib_pajak_zip = self.wajib_pajak_id.zip
            self.wajib_pajak_kota = self.wajib_pajak_id.city
            self.wajib_pajak_state_id = self.wajib_pajak_id.state_id
            self.wajib_pajak_country_id = self.wajib_pajak_id.country_id
            self.wajib_pajak_ptkp_category_id = self.wajib_pajak_id.ptkp_category_id
            self.wajib_pajak_job_position = self.wajib_pajak_id.function

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_penghasilan_01(self):
        self.penghasilan_01 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_penghasilan_01,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.penghasilan_01 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_penghasilan_02(self):
        self.penghasilan_02 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_penghasilan_02,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.penghasilan_02 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_penghasilan_03(self):
        self.penghasilan_03 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_penghasilan_03,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.penghasilan_03 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_penghasilan_04(self):
        self.penghasilan_04 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_penghasilan_04,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.penghasilan_04 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_penghasilan_05(self):
        self.penghasilan_05 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_penghasilan_05,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.penghasilan_05 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_penghasilan_06(self):
        self.penghasilan_06 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_penghasilan_06,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.penghasilan_06 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_penghasilan_07(self):
        self.penghasilan_07 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_penghasilan_07,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.penghasilan_07 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_pengurang_10(self):
        self.pengurang_10 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_pengurang_10,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.pengurang_10 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_perhitungan_13(self):
        self.perhitungan_13 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_perhitungan_13,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.perhitungan_13 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_perhitungan_18(self):
        self.perhitungan_18 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_perhitungan_18,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.perhitungan_18 = result

    @api.onchange(
        "company_id",
        "wajib_pajak_id",
        "start_tax_period_id",
        "end_tax_period_id",
    )
    def onchange_perhitungan_20(self):
        self.perhitungan_20 = 0.0
        if self.company_id:
            localdict = self._get_localdict()
            try:
                eval(
                    self.company_id.python_code_1721a1_perhitungan_20,
                    localdict,
                    mode="exec",
                    nocopy=True,
                )
                result = localdict["result"]
            except Exception:
                result = 0.0
            self.perhitungan_20 = result

    @api.onchange("tax_year_id")
    def onchange_tax_year_id(self):
        self.start_tax_period_id = False
        self.end_tax_period_id = False
Example #29
0
class Specimen(models.Model):
    _name = "hc.res.specimen"
    _description = "Specimen"

    name = fields.Char(
        string="Event Name",
        compute="_compute_name",
        store="True",
        help=
        "Text representation of the specimen event. Subject Name + Accession Identifier + Received Time."
    )
    identifier_ids = fields.One2many(comodel_name="hc.specimen.identifier",
                                     inverse_name="specimen_id",
                                     string="Identifiers",
                                     help="External Identifier.")
    accession_identifier_id = fields.Many2one(
        comodel_name="hc.specimen.accession.identifier",
        string="Accession Identifier",
        help="Identifier assigned by the lab.")
    status = fields.Selection(string="Status",
                              selection=[("available", "Available"),
                                         ("unavailable", "Unavailable"),
                                         ("unsatisfactory", "Unsatisfactory"),
                                         ("entered-in-error",
                                          "Entered-In-Error")],
                              help="The availability of the specimen.")
    type_id = fields.Many2one(comodel_name="hc.vs.v2.specimen.type",
                              string="Type",
                              help="Kind of material that forms the specimen.")
    subject_type = fields.Selection(string="Subject Type",
                                    required="True",
                                    selection=[("patient", "Patient"),
                                               ("group", "Group"),
                                               ("device", "Device"),
                                               ("substance", "Substance")],
                                    help="Type of who has the condition.")
    subject_name = fields.Char(
        string="Subject",
        compute="_compute_subject_name",
        required="True",
        help=
        "Where the specimen came from. This may be from the patient(s) or from the environment or a device."
    )
    subject_patient_id = fields.Many2one(
        comodel_name="hc.res.patient",
        string="Subject Patient",
        help="Patient where the specimen came from.")
    subject_group_id = fields.Many2one(
        comodel_name="hc.res.group",
        string="Subject Group",
        help="Group where the specimen came from.")
    subject_device_id = fields.Many2one(
        comodel_name="hc.res.device",
        string="Subject Device",
        help="Device where the specimen came from.")
    subject_substance_id = fields.Many2one(
        comodel_name="hc.res.substance",
        string="Subject Substance",
        help="Substance where the specimen came from.")
    received_time = fields.Datetime(
        string="Received Time",
        help="The time when specimen was received for processing.")
    parent_specimen_ids = fields.Many2many(
        comodel_name="hc.specimen.parent",
        string="Parent Specimens",
        help="Specimen from which this specimen originated.")
    request_ids = fields.One2many(comodel_name="hc.specimen.request",
                                  inverse_name="specimen_id",
                                  string="Requests",
                                  help="Why the specimen was collected.")
    note_ids = fields.One2many(comodel_name="hc.specimen.note",
                               inverse_name="specimen_id",
                               string="Notes",
                               help="Comments.")
    collection_ids = fields.One2many(comodel_name="hc.specimen.collection",
                                     inverse_name="specimen_id",
                                     string="Collections",
                                     help="Collection details.")
    treatment_ids = fields.One2many(
        comodel_name="hc.specimen.treatment",
        inverse_name="specimen_id",
        string="Treatments",
        help="Treatment and processing step details.")
    container_ids = fields.One2many(
        comodel_name="hc.specimen.container",
        inverse_name="specimen_id",
        string="Containers",
        help="Direct container of specimen (tube/slide, etc).")
Example #30
0
class dym_cancel_kwitansi(models.Model):
    _name = "dym.cancel.kwitansi"
    _description = "Cancel Kwitansi"

    STATE_SELECTION = [('draft', 'Draft'), ('validate', 'Posted'),
                       ('cancel', 'Cancelled')]

    @api.cr_uid_ids_context
    def _get_default_branch(self, cr, uid, ids, context=None):
        user_obj = self.pool.get('res.users')
        user_browse = user_obj.browse(cr, uid, uid)
        branch_ids = False
        branch_ids = user_browse.branch_ids and len(
            user_browse.branch_ids
        ) == 1 and user_browse.branch_ids[0].id or False
        return branch_ids

    name = fields.Char(string="Name", readonly=True, default='')
    branch_id = fields.Many2one('dym.branch',
                                string='Branch',
                                required=True,
                                default=_get_default_branch)
    state = fields.Selection(STATE_SELECTION,
                             string='State',
                             readonly=True,
                             default='draft')
    date = fields.Date(string="Date",
                       required=True,
                       readonly=True,
                       default=fields.Date.context_today)
    reason = fields.Char(string="Reason")
    division = fields.Selection([('Unit', 'Showroom'),
                                 ('Sparepart', 'Workshop'),
                                 ('Umum', 'General'), ('Finance', 'Finance')],
                                string='Division',
                                default='Unit',
                                required=True,
                                change_default=True,
                                select=True)
    voucher_id = fields.Many2one(related='kwitansi_id.payment_id',
                                 string='Payment No')
    kwitansi_id = fields.Many2one(
        'dym.register.kwitansi.line',
        string="Kwitansi No",
        domain=
        "[('state','=','cancel'),('branch_id','=',branch_id),('payment_id','!=',False)]"
    )
    confirm_uid = fields.Many2one('res.users', string="Validated by")
    confirm_date = fields.Datetime('Validated on')
    cancel_uid = fields.Many2one('res.users', string="Cancelled by")
    cancel_date = fields.Datetime('Cancelled on')
    voucher_id_show = fields.Many2one('account.voucher', string="Payment No")

    @api.onchange('voucher_id')
    def changekwitansi(self):
        self.voucher_id_show = self.voucher_id.id

    @api.model
    def create(self, vals, context=None):

        vals['name'] = self.env['ir.sequence'].get_per_branch(
            vals['branch_id'], 'CKW', division=vals['division'])
        vals['date'] = time.strftime('%Y-%m-%d')
        kwitansi_id = super(dym_cancel_kwitansi, self).create(vals)

        return kwitansi_id

    @api.cr_uid_ids_context
    def unlink(self, cr, uid, ids, context=None):
        for item in self.browse(cr, uid, ids, context=context):
            if item.state != 'draft':
                raise osv.except_osv(('Perhatian !'), (
                    "Form Cancel Kwitansi tidak bisa didelete karena sudah di validate !"
                ))
        return super(dym_cancel_kwitansi, self).unlink(cr,
                                                       uid,
                                                       ids,
                                                       context=context)

    @api.multi
    def validate_kwitansi(self):
        voucher = self.env['account.voucher']
        kwitansi = self.env['dym.register.kwitansi.line']

        kwitansi_id = kwitansi.search([('id', '=', self.kwitansi_id.id)])
        if not kwitansi_id:
            raise osv.except_osv(('Perhatian !'),
                                 ("Nomor Kwitansi sudah dihapus !"))

        kwitansi_id.write({
            'state': 'open',
            'payment_id': False,
            'reason': False
        })
        self.state = 'validate'
        self.confirm_uid = self._uid
        self.confirm_date = datetime.now()
        self.voucher_id_show = self.voucher_id.id
        self.date = datetime.today()