| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486 | # -*- coding: utf-8 -*-# License, author and contributors information in:# __openerp__.py file at the root folder of this module.from openerp import api, models, fields, _from openerp.exceptions import ValidationError, except_orm, Warning, RedirectWarningfrom openerp.tools import DEFAULT_SERVER_TIME_FORMATfrom openerp.tools import DEFAULT_SERVER_DATETIME_FORMATfrom datetime import datetimeimport logging_log = logging.getLogger(__name__)class OrdenServicio(models.Model):    _name = 'orden.servicio'    _description = 'Orden de servicio'    _inherit = ['mail.thread', 'ir.needaction_mixin']    def _get_user(self):        return self.env.uid    def _get_number(self):        return self.env['ir.sequence'].next_by_code('orden.servicio') or '*'    name = fields.Char(        string=u'Referencia',        readonly=True,  # Mark the field as readonly    )    @api.model    def create(self, vals):        if not vals.get('name'):            vals['name'] = self._get_number()        return super(OrdenServicio, self).create(vals)    user_id = fields.Many2one(        comodel_name='res.users',        string='Usuario',        default=_get_user    )    partner_id = fields.Many2one(        comodel_name='res.partner',        string='Cliente'    )    celular_partner = fields.Char(related='partner_id.mobile', string='Móvil', store=True, required=True)    telefono_partner = fields.Char(related='partner_id.phone', string='Teléfono', store=True)    ubicacion_google_link = fields.Char(string='Ubicación Google Link')    currency_id = fields.Many2one('res.currency', string='Moneda Base')    company_id = fields.Many2one('res.company', string='Empresa')    name_obra = fields.Char(string='Obra', required=True)    name_local = fields.Char(string='Local', required=True)    order_date = fields.Datetime(        string='Fecha de pedido de servicio', required=True,        default=fields.Datetime.now    )    planned_start_date = fields.Datetime(        string='Fecha y hora inicio de obra', required=True    )    planned_end_date = fields.Datetime(        string='Fecha y hora fin de obra', required=True    )    contacto_obra = fields.Char(        string='Persona de contacto de la obra', required=True    )    responsable = fields.Char(        string='Técnico Responsable', required=True    )    celular_obra = fields.Char(        string='Celular/Tel. de la Obra'    )    nro_factura = fields.Char(        string='N° de factura'    )    distancia_obra = fields.Float(        string='Distancia en km', required=True    )    croquis = fields.Char(        string='Croquis de la obra/Ubicación', required=True    )    hrs_total = fields.Char(        string='Hora total del trabajo', required=True    )    zona_obra = fields.Text(string='Zona obra de trabajo', required=True)    obs_obra = fields.Text(        string='Obs.'    )    fotos_obras = fields.Many2many(comodel_name='ir.attachment', relation='obra_attachment_rel', column1='obra_id', column2='attachment_id', string='Fotos del trabajo')    horarios_dia = fields.One2many('horario.dia', 'servicio_id', 'Horarios por día')    sale_order_id = fields.Many2one('sale.order', string='Orden de venta')    product_ids = fields.One2many(        comodel_name='servicio.producto',        inverse_name='servicio_id',        string='Productos a utilizar'    )    insumos_ids = fields.One2many(        comodel_name='servicio.insumo',        inverse_name='servicio_id',        string='Insumos a utilizar'    )    logistica_ids = fields.One2many(        comodel_name='servicio.logistica',        inverse_name='servicio_id',        string='Gastos de lógistica'    )    devolucion_ids = fields.One2many(        comodel_name='devolucion.insumo',        inverse_name='servicio_id',        string='Devolución de productos e insumos'    )    recepcion_ids = fields.One2many(        comodel_name='recepcion.fabrica',        inverse_name='servicio_id',        string='Recepción en fábrica'        )    # invoice_ids = fields.One2many('account.invoice', 'servicio_invoice_id')    # invoice_ids = fields.Many2many(    #     comodel_name='account.invoice',    #     relation='orden_servicio_invoice_rel',    #     column1='orden_servicio_id',    #     column2='invoice_id',    #     string='Facturas relacionadas'    #     )    sale_ids = fields.One2many(        comodel_name='sale.order',        inverse_name='servicio_sale_id',        string='Pedidos'    )    sale_count = fields.Integer(        string='Pedidos',        compute='_get_sale_count'    )    invoice_ids = fields.One2many(        comodel_name='account.invoice',        inverse_name='servicio_invoice_id',        string='Facturas'    )    invoice_count = fields.Integer(        string='Facturas',        compute='_get_invoice_count'        )    state = fields.Selection([        ('draft', 'Pendiente'),        ('in_progress', 'En progreso'),        ('done', 'Realizado'),        ('canceled', 'Cancelado')],        string='Estado',        default='draft'    )    @api.multi    @api.depends('product_ids.subtotal')    def _compute_total_producto(self):        for record in self:            record.total_producto = sum(record.product_ids.mapped('subtotal'))    @api.multi    @api.depends('insumos_ids.subtotal')    def _compute_total_insumo(self):        for record in self:            record.total_insumo = sum(record.insumos_ids.mapped('subtotal'))    @api.multi    @api.depends('product_ids.subtotal')    def _compute_total_logistica(self):        for record in self:            record.total_logistica = sum(record.logistica_ids.mapped('subtotal'))    @api.multi    @api.depends('insumos_ids.subtotal')    def _compute_total_devolucion(self):        for record in self:            record.total_devolucion = sum(record.devolucion_ids.mapped('subtotal'))    @api.multi    @api.depends('insumos_ids.subtotal')    def _compute_total_fabrica(self):        for record in self:            record.total_fabrica = sum(record.recepcion_ids.mapped('subtotal'))    @api.depends('total_producto', 'total_insumo', 'total_logistica')    def _compute_total_obra(self):        for record in self:            record.total_obra = record.total_producto + record.total_insumo + record.total_logistica    total_producto = fields.Float(compute='_compute_total_producto', string='Total Producto', store=True, digits=(10, 0))    total_insumo = fields.Float(compute='_compute_total_insumo', string='Total Insumo', store=True, digits=(10, 0))    total_logistica = fields.Float(compute='_compute_total_logistica', string='Total Logística', store=True, digits=(10, 0))    total_devolucion = fields.Float(compute='_compute_total_devolucion', string='Total Devolución', store=True, digits=(10, 0))    total_fabrica = fields.Float(compute='_compute_total_fabrica', string='Total Recepción', store=True, digits=(10, 0))    total_obra = fields.Float(compute='_compute_total_obra', string='Total Obra', store=True, digits=(10, 0))    @api.model    def defaults(self):        res = super(OrderServicio, self).defaults()        company_id = self.env['res.company']._company_default_get('order.servicio')        currency_id = company_id.currency_id.id if company_id.currency_id else False        res.update({            'currency_id': currency_id,            'company_id': company_id.id,        })        return res    @api.one    @api.depends('sale_ids')    def _get_sale_count(self):        self.sale_count = len(self.sale_ids)    @api.one    @api.depends('invoice_ids')    def _get_invoice_count(self):        self.invoice_count = len(self.invoice_ids)    @api.one    def button_in_progress(self):        self.state = 'in_progress'    @api.one    def button_in_progress_back(self):        self.state = 'draft'    @api.one    def button_done_back(self):        self.state = 'in_progress'    @api.one    def button_done(self):        self.state = 'done'    @api.one    def button_cancel(self):        self.state = 'canceled'    @api.one    def onchange_partner_id(self, partner_id):        _log.info('-'*100)        _log.info(partner_id)    @api.onchange('ubicacion_google_link')    def on_ubicacion_google_link_change(self):        for record in self:            if record.ubicacion_google_link:                # Abrir la ubicación en otra pestaña                # Esto puede requerir personalización adicional dependiendo de tu requisito exacto                url = record.ubicacion_google_linkclass ProductoServicio(models.Model):    _name = 'servicio.producto'    servicio_id = fields.Many2one(        comodel_name='orden.servicio',        string='Orden de servicio'    )    product_id = fields.Many2one('product.product', 'Producto', domain=[('type', '=', 'product')])    categ_id = fields.Char('Categoría de producto')    quantity = fields.Float(        string='Cantidad',        default=1,        digits=(5, 3)    )    price_unit = fields.Float('Precio de costo')    subtotal = fields.Float('Subtotal', compute='compute_subtotal', store=True, digits=(10, 0))    @api.one    @api.depends('quantity', 'price_unit')    def compute_subtotal(self):        self.subtotal = self.quantity * self.price_unit    @api.onchange('product_id')    def onchange_product_id(self):        if self.product_id:            self.description = self.product_id.name            self.categ_id = self.product_id.categ_id.name            self.type = 'product' if self.product_id.type == 'product' \                else 'service'            # @ TODO impuestos??            # Obtener el precio del producto a partir de la tarifa del cliente            self.price_unit = self.product_id.standard_priceclass ServicioInsumo(models.Model):    _name = 'servicio.insumo'    _description = 'Lista de Materiales proveidos'    _inherit = ['mail.thread', 'ir.needaction_mixin']    servicio_id = fields.Many2one(        comodel_name='orden.servicio',        string='Orden de servicio'    )    product_id = fields.Many2one('product.product', 'Producto', domain=[('type', '=', 'product')])    descripcion = fields.Char(        string='Descripcion',        required=True    )    quantity = fields.Float(        string='Cantidad',        default=1,        digits=(5, 3)    )    price_unit = fields.Float(        string='Precio Unit.'    )    subtotal = fields.Float(        string='Subtotal',        compute='compute_subtotal',        digits=(10, 0)    )    @api.one    @api.depends('quantity', 'price_unit')    def compute_subtotal(self):        self.subtotal = self.quantity * self.price_unit    @api.onchange('product_id')    def onchange_product_id(self):        if self.product_id:            self.descripcion = self.product_id.name            self.price_unit = self.product_id.standard_priceclass ServicioLogistica(models.Model):    _name = 'servicio.logistica'    _description = 'Gastos de logística'    _inherit = ['mail.thread', 'ir.needaction_mixin']    servicio_id = fields.Many2one(        comodel_name='orden.servicio',        string='Orden de servicio'    )    fecha = fields.Date(        string='Fecha',        required=True    )    product_id = fields.Many2one('product.product', 'Servicio', domain=[('type', '=', 'service')])    descripcion = fields.Char(        string='Descripcion',        required=True    )    quantity = fields.Float(        string='Km recorrido',        default=1    )    price_unit = fields.Float(        string='Precio Unit.'    )    subtotal = fields.Float(        string='Subtotal',        compute='compute_subtotal',        digits=(10, 0)    )    @api.one    @api.depends('quantity', 'price_unit')    def compute_subtotal(self):        self.subtotal = self.quantity * self.price_unit    @api.onchange('product_id')    def onchange_product_id(self):        if self.product_id:            self.descripcion = self.product_id.name            self.price_unit = self.product_id.standard_priceclass DevolucionInsumo(models.Model):    _name = 'devolucion.insumo'    _description = 'Devolución de productos e insumos'    _inherit = ['mail.thread', 'ir.needaction_mixin']    servicio_id = fields.Many2one(        comodel_name='orden.servicio',        string='Orden de servicio'    )    product_id = fields.Many2one('product.product', 'Producto', domain=[('type', '=', 'product')])    descripcion = fields.Char(        string='Descripcion',        required=True    )    quantity = fields.Float(        string='Cantidad',        default=1,        digits=(5, 3)    )    price_unit = fields.Float(        string='Precio Unit.'    )    subtotal = fields.Float(        string='Subtotal',        compute='compute_subtotal',        digits=(10, 0)    )    @api.one    @api.depends('quantity', 'price_unit')    def compute_subtotal(self):        self.subtotal = self.quantity * self.price_unit    @api.onchange('product_id')    def onchange_product_id(self):        if self.product_id:            self.descripcion = self.product_id.name            self.price_unit = self.product_id.standard_priceclass RecepcionFabrica(models.Model):    _name = 'recepcion.fabrica'    _description = 'Recepción en fábrica '    _inherit = ['mail.thread', 'ir.needaction_mixin']    servicio_id = fields.Many2one(        comodel_name='orden.servicio',        string='Orden de servicio'    )    fecha = fields.Date(        string='Fecha',        required=True    )    product_id = fields.Many2one(        comodel_name='product.product',        string='Productos'    )    descripcion = fields.Char(        string='Descripcion',        required=True    )    quantity = fields.Float(        string='Cantidad',        default=1    )    price_unit = fields.Float(        string='Precio Unit.'    )    subtotal = fields.Float(        string='Subtotal',        compute='compute_subtotal',        digits=(10, 0)    )    employee_id = fields.Many2one(    'hr.employee',    string='Empleado'    )    @api.one    @api.depends('quantity', 'price_unit')    def compute_subtotal(self):        self.subtotal = self.quantity * self.price_unit    @api.onchange('product_id')    def onchange_product_id(self):        if self.product_id:            self.descripcion = self.product_id.name            self.price_unit = self.product_id.standard_priceclass AccountInvoice(models.Model):    _inherit = 'account.invoice'    servicio_invoice_id = fields.Many2one(        comodel_name='orden.servicio',        string='Orden de Servicio'    )class SaleOrder(models.Model):    _inherit = 'sale.order'    servicio_sale_id = fields.Many2one(        comodel_name='orden.servicio',        string='Orden de Servicio'    )
 |