orden_servicio.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. # -*- coding: utf-8 -*-
  2. # License, author and contributors information in:
  3. # __openerp__.py file at the root folder of this module.
  4. from openerp import api, models, fields
  5. from openerp.exceptions import ValidationError, except_orm, Warning, RedirectWarning
  6. from openerp.tools import DEFAULT_SERVER_TIME_FORMAT
  7. from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
  8. from datetime import datetime
  9. import logging
  10. _log = logging.getLogger(__name__)
  11. class OrdenServicio(models.Model):
  12. _name = 'orden.servicio'
  13. _description = 'Orden de servicio'
  14. _inherit = ['mail.thread', 'ir.needaction_mixin']
  15. def _get_user(self):
  16. return self.env.uid
  17. def _get_number(self):
  18. return self.env['ir.sequence'].get('orden.servicio') or '*'
  19. name = fields.Char(
  20. string=u'Referencia',
  21. default=_get_number
  22. )
  23. user_id = fields.Many2one(
  24. comodel_name='res.users',
  25. string='Usuario',
  26. default=_get_user
  27. )
  28. partner_id = fields.Many2one(
  29. comodel_name='res.partner',
  30. string='Cliente'
  31. )
  32. celular_partner = fields.Char(related='partner_id.mobile', string='Móvil', store=True)
  33. telefono_partner = fields.Char(related='partner_id.phone', string='Teléfono', store=True)
  34. ubicacion_google_link = fields.Char(string='Ubicación Google Link')
  35. name_obra = fields.Char(
  36. string='Obra'
  37. )
  38. name_local = fields.Char(
  39. string='Local'
  40. )
  41. order_date = fields.Datetime(
  42. string='Fecha de pedido de servicio',
  43. default=fields.Datetime.now
  44. )
  45. planned_start_date = fields.Datetime(
  46. string='Fecha y hora inicio de obra'
  47. )
  48. planned_end_date = fields.Datetime(
  49. string='Fecha y hora fin de obra'
  50. )
  51. contacto_obra = fields.Char(
  52. string='Persona de contacto de la obra'
  53. )
  54. responsable = fields.Char(
  55. string='Técnico Responsable'
  56. )
  57. celular_obra = fields.Char(
  58. string='Celular/Tel. de la Obra'
  59. )
  60. nro_factura = fields.Char(
  61. string='N° de factura'
  62. )
  63. distancia_obra = fields.Float(
  64. string='Distancia en km'
  65. )
  66. croquis = fields.Char(
  67. string='Croquis de la obra/Ubicación'
  68. )
  69. hrs_total = fields.Char(
  70. string='Hora total del trabajo'
  71. )
  72. zona_obra = fields.Text(
  73. string='Zona obra de trabajo'
  74. )
  75. obs_obra = fields.Text(
  76. string='Obs.'
  77. )
  78. fotos_obras = fields.Many2many(comodel_name='ir.attachment', relation='obra_attachment_rel', column1='obra_id', column2='attachment_id', string='Fotos del trabajo')
  79. horarios_dia = fields.One2many('horario.dia', 'servicio_id', 'Horarios por día')
  80. sale_order_id = fields.Many2one('sale.order', string='Orden de venta')
  81. product_ids = fields.One2many(
  82. comodel_name='servicio.producto',
  83. inverse_name='servicio_id',
  84. string='Productos a utilizar'
  85. )
  86. insumos_ids = fields.One2many(
  87. comodel_name='servicio.insumo',
  88. inverse_name='servicio_id',
  89. string='Insumos a utilizar'
  90. )
  91. logistica_ids = fields.One2many(
  92. comodel_name='servicio.logistica',
  93. inverse_name='servicio_id',
  94. string='Gastos de lógistica'
  95. )
  96. devolucion_ids = fields.One2many(
  97. comodel_name='devolucion.insumo',
  98. inverse_name='servicio_id',
  99. string='Devolución de productos e insumos'
  100. )
  101. recepcion_ids = fields.One2many(
  102. comodel_name='recepcion.fabrica',
  103. inverse_name='servicio_id',
  104. string='Recepción en fábrica'
  105. )
  106. invoice_ids = fields.One2many('account.invoice', 'servicio_invoice_id')
  107. invoice_count = fields.Integer(
  108. string='Facturas',
  109. compute='_get_invoice_count',
  110. )
  111. state = fields.Selection([
  112. ('draft', 'Pendiente'),
  113. ('in_progress', 'En progreso'),
  114. ('done', 'Realizado'),
  115. ('canceled', 'Cancelado')],
  116. string='Estado',
  117. default='draft'
  118. )
  119. @api.one
  120. @api.depends('invoice_ids')
  121. def _get_invoice_count(self):
  122. self.invoice_count = len(self.invoice_ids)
  123. @api.one
  124. def button_in_progress(self):
  125. self.state = 'in_progress'
  126. @api.one
  127. def button_in_progress_back(self):
  128. self.state = 'draft'
  129. @api.one
  130. def button_done_back(self):
  131. self.state = 'in_progress'
  132. @api.one
  133. def button_done(self):
  134. self.state = 'done'
  135. @api.one
  136. def button_cancel(self):
  137. self.state = 'canceled'
  138. @api.one
  139. def onchange_partner_id(self, partner_id):
  140. _log.info('-'*100)
  141. _log.info(partner_id)
  142. @api.onchange('ubicacion_google_link')
  143. def on_ubicacion_google_link_change(self):
  144. for record in self:
  145. if record.ubicacion_google_link:
  146. # Abrir la ubicación en otra pestaña
  147. # Esto puede requerir personalización adicional dependiendo de tu requisito exacto
  148. url = record.ubicacion_google_link
  149. class ProductoServicio(models.Model):
  150. _name = 'servicio.producto'
  151. servicio_id = fields.Many2one(
  152. comodel_name='orden.servicio',
  153. string='Orden de servicio'
  154. )
  155. product_id = fields.Many2one('product.product', 'Producto', domain=[('type', '=', 'product')])
  156. categ_id = fields.Char('Categoría de producto')
  157. quantity = fields.Float(
  158. string='Cantidad',
  159. default=1,
  160. digits=(5, 3)
  161. )
  162. price_unit = fields.Float('Precio de costo')
  163. subtotal = fields.Float('Subtotal', compute='compute_subtotal', store=True)
  164. @api.one
  165. @api.depends('quantity', 'price_unit')
  166. def compute_subtotal(self):
  167. self.subtotal = self.quantity * self.price_unit
  168. @api.onchange('product_id')
  169. def onchange_product_id(self):
  170. if self.product_id:
  171. self.description = self.product_id.name
  172. self.categ_id = self.product_id.categ_id.name
  173. self.type = 'product' if self.product_id.type == 'product' \
  174. else 'service'
  175. # @ TODO impuestos??
  176. # Obtener el precio del producto a partir de la tarifa del cliente
  177. self.price_unit = self.product_id.list_price
  178. class ServicioInsumo(models.Model):
  179. _name = 'servicio.insumo'
  180. _description = 'Lista de Materiales proveidos'
  181. _inherit = ['mail.thread', 'ir.needaction_mixin']
  182. servicio_id = fields.Many2one(
  183. comodel_name='orden.servicio',
  184. string='Orden de servicio'
  185. )
  186. product_id = fields.Many2one('product.product', 'Producto', domain=[('type', '=', 'product')])
  187. descripcion = fields.Char(
  188. string='Descripcion',
  189. required=True
  190. )
  191. quantity = fields.Float(
  192. string='Cantidad',
  193. default=1,
  194. digits=(5, 3)
  195. )
  196. price_unit = fields.Float(
  197. string='Precio Unit.'
  198. )
  199. subtotal = fields.Float(
  200. string='Subtotal',
  201. compute='compute_subtotal',
  202. digits=(10, 0)
  203. )
  204. @api.one
  205. @api.depends('quantity', 'price_unit')
  206. def compute_subtotal(self):
  207. self.subtotal = self.quantity * self.price_unit
  208. @api.onchange('product_id')
  209. def onchange_product_id(self):
  210. if self.product_id:
  211. self.description = self.product_id.name
  212. self.price_unit = self.product_id.list_price
  213. class ServicioLogistica(models.Model):
  214. _name = 'servicio.logistica'
  215. _description = 'Gastos de logística'
  216. _inherit = ['mail.thread', 'ir.needaction_mixin']
  217. servicio_id = fields.Many2one(
  218. comodel_name='orden.servicio',
  219. string='Orden de servicio'
  220. )
  221. fecha = fields.Date(
  222. string='Fecha',
  223. required=True
  224. )
  225. product_id = fields.Many2one('product.product', 'Servicio', domain=[('type', '=', 'service'), ('categ_id', '=', 'Gastos')])
  226. descripcion = fields.Char(
  227. string='Descripcion',
  228. required=True
  229. )
  230. quantity = fields.Float(
  231. string='Km recorrido',
  232. default=1
  233. )
  234. price_unit = fields.Float(
  235. string='Precio Unit.'
  236. )
  237. subtotal = fields.Float(
  238. string='Subtotal',
  239. compute='compute_subtotal'
  240. )
  241. @api.one
  242. @api.depends('quantity', 'price_unit')
  243. def compute_subtotal(self):
  244. self.subtotal = self.quantity * self.price_unit
  245. @api.onchange('product_id')
  246. def onchange_product_id(self):
  247. if self.product_id:
  248. self.description = self.product_id.name
  249. self.price_unit = self.product_id.list_price
  250. class DevolucionInsumo(models.Model):
  251. _name = 'devolucion.insumo'
  252. _description = 'Devolución de productos e insumos'
  253. _inherit = ['mail.thread', 'ir.needaction_mixin']
  254. servicio_id = fields.Many2one(
  255. comodel_name='orden.servicio',
  256. string='Orden de servicio'
  257. )
  258. product_id = fields.Many2one('product.product', 'Producto', domain=[('type', '=', 'product')])
  259. descripcion = fields.Char(
  260. string='Descripcion',
  261. required=True
  262. )
  263. quantity = fields.Float(
  264. string='Cantidad',
  265. default=1,
  266. digits=(5, 3)
  267. )
  268. price_unit = fields.Float(
  269. string='Precio Unit.'
  270. )
  271. subtotal = fields.Float(
  272. string='Subtotal',
  273. compute='compute_subtotal',
  274. digits=(10, 0)
  275. )
  276. @api.one
  277. @api.depends('quantity', 'price_unit')
  278. def compute_subtotal(self):
  279. self.subtotal = self.quantity * self.price_unit
  280. @api.onchange('product_id')
  281. def onchange_product_id(self):
  282. if self.product_id:
  283. self.description = self.product_id.name
  284. self.price_unit = self.product_id.list_price
  285. class RecepcionFabrica(models.Model):
  286. _name = 'recepcion.fabrica'
  287. _description = 'Recepción en fábrica '
  288. _inherit = ['mail.thread', 'ir.needaction_mixin']
  289. servicio_id = fields.Many2one(
  290. comodel_name='orden.servicio',
  291. string='Orden de servicio'
  292. )
  293. fecha = fields.Date(
  294. string='Fecha',
  295. required=True
  296. )
  297. product_id = fields.Many2one(
  298. comodel_name='product.product',
  299. string='Productos'
  300. )
  301. descripcion = fields.Char(
  302. string='Descripcion',
  303. required=True
  304. )
  305. quantity = fields.Float(
  306. string='Cantidad',
  307. default=1
  308. )
  309. price_unit = fields.Float(
  310. string='Precio Unit.'
  311. )
  312. subtotal = fields.Float(
  313. string='Subtotal',
  314. compute='compute_subtotal',
  315. digits=(10, 0)
  316. )
  317. employee_id = fields.Many2one(
  318. 'hr.employee',
  319. string='Empleado'
  320. )
  321. @api.one
  322. @api.depends('quantity', 'price_unit')
  323. def compute_subtotal(self):
  324. self.subtotal = self.quantity * self.price_unit
  325. @api.onchange('product_id')
  326. def onchange_product_id(self):
  327. if self.product_id:
  328. self.description = self.product_id.name
  329. self.price_unit = self.product_id.list_price
  330. class AccountInvoice(models.Model):
  331. _inherit = 'account.invoice'
  332. servicio_invoice_id = fields.Many2one('orden.servicio')