stock_transfer_order.py 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. # -*- encoding: utf-8 -*-
  2. from openerp import models, fields, api, _
  3. from openerp.exceptions import Warning
  4. import openerp.addons.decimal_precision as dp
  5. from datetime import datetime
  6. from openerp.tools import float_compare
  7. class stock_transfer_details(models.TransientModel):
  8. _name = 'stock.transfer.order.details'
  9. sale_id = fields.Many2one('sale.order', 'Pedido')
  10. item_ids = fields.One2many('stock.transfer.order.details.items', 'transfer_id', 'Items', domain=[('product_id', '!=', False)])
  11. @api.model
  12. def _get_picking_type(self):
  13. picking_type = self.env['stock.picking.type'].search([('active','=',True),('warehouse_id','=',False),('code','=','internal'),('default_location_src_id','!=','default_location_dest_id')])
  14. if picking_type:
  15. return picking_type[0].id
  16. else:
  17. raise Warning(_('No existe un tipo de transferencia adecuado para esta operación'))
  18. picking_type_id = fields.Many2one('stock.picking.type', 'Tipo de transferencia', default=_get_picking_type, required=True)
  19. picking_source_location_id = fields.Many2one('stock.location', string="Head source location", related='picking_type_id.default_location_src_id', store=False, readonly=True)
  20. picking_destination_location_id = fields.Many2one('stock.location', string="Head destination location", related='picking_type_id.default_location_dest_id', store=False, readonly=True)
  21. @api.multi
  22. def wizard_view(self, transfer_details):
  23. view = self.env.ref('stock_transfer_order.wizard_transfer_details')
  24. return {
  25. 'name': _('Enter transfer details'),
  26. 'type': 'ir.actions.act_window',
  27. 'view_type': 'form',
  28. 'view_mode': 'form',
  29. 'res_model': 'stock.transfer.order.details',
  30. 'views': [(view.id, 'form')],
  31. 'view_id': view.id,
  32. 'target': 'new',
  33. 'res_id': transfer_details.id,
  34. }
  35. @api.multi
  36. def do_detailed_transfer2(self):
  37. now = datetime.now()
  38. for item in self.item_ids:
  39. if item.product_id.type == 'product':
  40. uom_record = item.product_id.uom_id
  41. qty_available = self.get_location_qty(item.product_id.id, item.sourceloc_id.id)
  42. compare_qty = float_compare(qty_available, item.quantity, precision_rounding=uom_record.rounding)
  43. if compare_qty == -1:
  44. warn_msg = _('Estas intentando transferir %.2f %s de %s pero el almacén de origen %s posee %.2f %s disponible!') % \
  45. (item.quantity, uom_record.name,
  46. item.product_id.name,
  47. item.sourceloc_id.name,
  48. max(0,qty_available), uom_record.name)
  49. raise Warning(_("No hay stock suficiente: "),_(warn_msg))
  50. picking_item = {
  51. 'origin': self.sale_id.name,
  52. 'move_type':'one',
  53. 'invoice_state':'none',
  54. 'date_done': now.strftime("%Y-%m-%d %H:%M:%S"),
  55. 'priority':'1',
  56. 'picking_type_id' : self.picking_type_id.id
  57. }
  58. picking_id = self.env['stock.picking'].create(picking_item)
  59. for item in self.item_ids:
  60. move = {
  61. 'name': item.name,
  62. 'picking_id': picking_id.id,
  63. 'product_id': item.product_id.id,
  64. 'product_uom_qty': item.quantity,
  65. 'product_uos_qty': item.quantity,
  66. 'price_unit': item.price_unit,
  67. 'product_uom': item.product_uom_id.id,
  68. 'picking_type_id': self.picking_type_id.id,
  69. 'location_id':item.sourceloc_id.id,
  70. 'location_dest_id':item.destinationloc_id.id,
  71. 'origin': self.sale_id.name,
  72. 'company_id': self.env.user.company_id.id,
  73. 'date': now.strftime("%Y-%m-%d %H:%M:%S"),
  74. 'date_expected': now.strftime("%Y-%m-%d %H:%M:%S"),
  75. 'invoice_state':'none'
  76. }
  77. move_id = self.env['stock.move'].create(move)
  78. move_id.action_done()
  79. sale = self.env['sale.order'].search([('id','=',self.sale_id.id)])
  80. sale.write({'state': 'manual'})
  81. return True
  82. @api.multi
  83. def get_location_qty(self, product_id, location_id):
  84. location_ids = self.env['stock.location'].search([('active','=',True),('usage','=','internal'),('id','!=',self.picking_type_id.default_location_dest_id.id)])
  85. for id in location_ids:
  86. suma = 0
  87. quant_ids = self.env['stock.quant'].search([('product_id','=', product_id),('location_id','=',location_id)])
  88. if quant_ids:
  89. for quant_id in quant_ids:
  90. suma = suma + quant_id.qty
  91. return suma
  92. class stock_transfer_details_items(models.TransientModel):
  93. _name = 'stock.transfer.order.details.items'
  94. select = fields.Boolean('Seleccionar')
  95. transfer_id = fields.Many2one('stock.transfer.order.details', 'Transferencia')
  96. product_id = fields.Many2one('product.product', 'Producto', required=True)
  97. name = fields.Char('Descripción')
  98. product_uom_id = fields.Many2one('product.uom', 'Unidad de medida')
  99. quantity = fields.Float('Cantidad', digits=dp.get_precision('Product Unit of Measure'), default = 1.0)
  100. price_unit = fields.Float('Precio Unitario')
  101. sourceloc_id = fields.Many2one('stock.location', 'Ubicación Origen',required=True)
  102. destinationloc_id = fields.Many2one('stock.location', 'Ubicación Destino',required=True)
  103. date = fields.Datetime('Fecha')
  104. origin = fields.Char('Pedido')
  105. owner_id = fields.Many2one('res.partner', 'Creado por:', help="Owner of the quants")
  106. @api.multi
  107. def product_id_change(self, product, uom=False):
  108. result = {}
  109. if product:
  110. prod = self.env['product.product'].browse(product)
  111. result['product_uom_id'] = prod.uom_id and prod.uom_id.id
  112. return {'value': result}
  113. class sale_order(models.Model):
  114. _inherit = 'sale.order'
  115. @api.multi
  116. def stock_transfer_action(self):
  117. for item in self:
  118. created_id = self.env['stock.transfer.order.details'].create({'sale_id': item.id or False})
  119. for each in item.order_line:
  120. line = self.env['sale.order.line'].browse(each.id)
  121. items = {
  122. 'transfer_id' : created_id.id,
  123. 'product_id' : line.product_id.id,
  124. 'name' : line.name,
  125. 'product_uom_id' : line.product_uom.id,
  126. 'quantity' : line.product_uom_qty,
  127. 'sourceloc_id' : created_id.picking_type_id.default_location_src_id.id,
  128. 'destinationloc_id' : created_id.picking_type_id.default_location_dest_id.id,
  129. 'origin' : item.name,
  130. 'price_unit' : line.price_unit,
  131. }
  132. self.env['stock.transfer.order.details.items'].create(items)
  133. return self.env['stock.transfer.order.details'].wizard_view(created_id)
  134. class stock_location(models.Model):
  135. _inherit = "stock.location"
  136. @api.multi
  137. def name_get(self):
  138. if self._context is None:
  139. self._context = {}
  140. res = []
  141. if self._context.get('nombre_para_stock_transfer', False):
  142. product = self._context.get('transfer_product_id')
  143. for location in self:
  144. suma = 0
  145. quant_ids = self.env['stock.quant'].search([('product_id','=', product),('location_id','=',location.id)])
  146. if quant_ids:
  147. for quant_id in quant_ids:
  148. suma = suma + quant_id.qty
  149. res.append((location.id, ("%(location_parent)s/%(location_name)s - %(location_qty)s") % {
  150. 'location_parent': location.location_id.name,
  151. 'location_name': location.name,
  152. 'location_qty': suma
  153. }))
  154. else:
  155. for record in self:
  156. res.append((record.id, ("%(location_parent)s/%(location_name)s") % {
  157. 'location_parent': record.location_id.name or "",
  158. 'location_name': record.name
  159. }))
  160. return res
  161. class stock_picking(models.Model):
  162. _inherit = 'stock.picking'
  163. @api.multi
  164. def entregar_producto(self):
  165. for item in self:
  166. for move in item.move_lines:
  167. move.action_done()
  168. return True