# -*- encoding: utf-8 -*- from openerp import models, fields, api, _ from openerp.exceptions import Warning import openerp.addons.decimal_precision as dp from datetime import datetime from openerp.tools import float_compare class stock_transfer_details(models.TransientModel): _name = 'stock.transfer.order.details' sale_id = fields.Many2one('sale.order', 'Pedido') item_ids = fields.One2many('stock.transfer.order.details.items', 'transfer_id', 'Items', domain=[('product_id', '!=', False)]) @api.model def _get_picking_type(self): picking_type = self.env['stock.picking.type'].search([('active','=',True),('warehouse_id','=',False),('code','=','internal'),('default_location_src_id','!=','default_location_dest_id')]) if picking_type: return picking_type[0].id else: raise Warning(_('No existe un tipo de transferencia adecuado para esta operación')) picking_type_id = fields.Many2one('stock.picking.type', 'Tipo de transferencia', default=_get_picking_type, required=True) picking_source_warehouse_id = fields.Many2one('stock.warehouse', string="Head source location", compute="getWarehouse", store=True) picking_destination_warehouse_id = fields.Many2one('stock.warehouse', string="Head destination location", compute="getWarehouse", store=True) @api.one @api.depends('picking_type_id') def getWarehouse(self): for rec in self: warehouse_origen = self.env['stock.warehouse'].search([('lot_stock_id','=',self.picking_type_id.default_location_src_id.id)]) warehouse_dest = self.env['stock.warehouse'].search([('lot_stock_id','=',self.picking_type_id.default_location_dest_id.id)]) self.picking_source_warehouse_id = warehouse_origen.id, self.picking_destination_warehouse_id = warehouse_dest.id @api.multi def wizard_view(self, transfer_details): view = self.env.ref('stock_transfer_order.wizard_transfer_details') return { 'name': _('Enter transfer details'), 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'stock.transfer.order.details', 'views': [(view.id, 'form')], 'view_id': view.id, 'target': 'new', 'res_id': transfer_details.id, } @api.multi def do_detailed_transfer2(self): now = datetime.now() for item in self.item_ids: if item.product_id.type == 'product': uom_record = item.product_id.uom_id qty_available = self.get_location_qty(item.product_id.id, item.sourceloc_id.id) compare_qty = float_compare(qty_available, item.quantity, precision_rounding=uom_record.rounding) if compare_qty == -1: warn_msg = _('Estas intentando transferir %.2f %s de %s pero el almacén de origen posee %.2f %s disponible!') % \ (item.quantity, uom_record.name, item.product_id.name, max(0,qty_available), uom_record.name) raise Warning(_("No hay stock suficiente: "),_(warn_msg)) picking_item = { 'origin': self.sale_id.name, 'move_type':'one', 'invoice_state':'none', 'date_done': now.strftime("%Y-%m-%d %H:%M:%S"), 'priority':'1', 'picking_type_id' : self.picking_type_id.id } picking_id = self.env['stock.picking'].create(picking_item) for item in self.item_ids: move = { 'name': item.name, 'picking_id': picking_id.id, 'product_id': item.product_id.id, 'product_uom_qty': item.quantity, 'product_uos_qty': item.quantity, 'price_unit': item.price_unit, 'product_uom': item.product_uom_id.id, 'picking_type_id': self.picking_type_id.id, 'location_id':item.sourceloc_id.id, 'location_dest_id':item.destinationloc_id.id, 'origin': self.sale_id.name, 'company_id': self.env.user.company_id.id, 'date': now.strftime("%Y-%m-%d %H:%M:%S"), 'date_expected': now.strftime("%Y-%m-%d %H:%M:%S"), 'invoice_state':'none', } move_id = self.env['stock.move'].create(move) move_id.action_done() sale = self.env['sale.order'].search([('id','=',self.sale_id.id)]) sale.write({'state': 'manual','transfered':True}) return True @api.multi def get_location_qty(self, product_id, location_id): suma = 0 quant_ids = self.env['stock.quant'].search([('product_id','=', product_id),('location_id','=',location_id)]) if quant_ids: for quant_id in quant_ids: suma = suma + quant_id.qty return suma class stock_transfer_details_items(models.TransientModel): _name = 'stock.transfer.order.details.items' select = fields.Boolean('Seleccionar') transfer_id = fields.Many2one('stock.transfer.order.details', 'Transferencia') product_id = fields.Many2one('product.product', 'Producto', required=True) name = fields.Char('Descripción') product_uom_id = fields.Many2one('product.uom', 'Unidad de medida') quantity = fields.Float('Cantidad', digits=dp.get_precision('Product Unit of Measure'), default = 1.0) price_unit = fields.Float('Precio Unitario') source_warehouse = fields.Many2one('stock.warehouse', 'Déposito Origen') dest_warehouse = fields.Many2one('stock.warehouse', 'Déposito Destino') sourceloc_id = fields.Many2one('stock.location', 'Ubicación Origen', related="source_warehouse.lot_stock_id", store=True) destinationloc_id = fields.Many2one('stock.location', 'Ubicación Destino',related="dest_warehouse.lot_stock_id", store=True) date = fields.Datetime('Fecha') origin = fields.Char('Pedido') owner_id = fields.Many2one('res.partner', 'Creado por:', help="Owner of the quants") @api.multi def product_id_change(self, product, uom=False): result = {} if product: prod = self.env['product.product'].browse(product) result['product_uom_id'] = prod.uom_id and prod.uom_id.id return {'value': result} class sale_order(models.Model): _inherit = 'sale.order' @api.multi def stock_transfer_action(self): for item in self: created_id = self.env['stock.transfer.order.details'].create({'sale_id': item.id or False}) for each in item.order_line: line = self.env['sale.order.line'].browse(each.id) items = { 'transfer_id' : created_id.id, 'product_id' : line.product_id.id, 'name' : line.name, 'product_uom_id' : line.product_uom.id, 'quantity' : line.product_uom_qty, 'source_warehouse' : created_id.picking_source_warehouse_id.id, 'dest_warehouse' : created_id.picking_destination_warehouse_id.id, 'origin' : item.name, 'price_unit' : line.price_unit, } self.env['stock.transfer.order.details.items'].create(items) return self.env['stock.transfer.order.details'].wizard_view(created_id) class stock_warehouse(models.Model): _inherit = "stock.warehouse" @api.multi def name_get(self): if self._context is None: self._context = {} res = [] if self._context.get('nombre_para_stock_transfer', False): product = self._context.get('transfer_product_id') for location in self: suma = 0 quant_ids = self.env['stock.quant'].search([('product_id','=', product),('location_id','=',location.lot_stock_id.id)]) if quant_ids: for quant_id in quant_ids: suma = suma + quant_id.qty res.append((location.id, ("%(location_name)s %(location_qty)s") % { 'location_name': location.name, 'location_qty': suma })) else: for record in self: res.append((record.id, ("%(location_name)s") % { 'location_name': record.name })) return res class stock_picking(models.Model): _inherit = 'stock.picking' @api.multi def entregar_producto(self): for item in self: for move in item.move_lines: if move.product_id.type == 'product' and move.location_id.usage == 'internal': uom_record = move.product_id.uom_id qty_available = self.get_location_qty(move.product_id.id, move.location_id.id) compare_qty = float_compare(qty_available, move.product_uom_qty, precision_rounding=uom_record.rounding) if compare_qty == -1: warn_msg = _('Estas intentando transferir %.2f %s de %s pero el almacén de origen posee %.2f %s disponible!') % \ (move.product_uom_qty, uom_record.name, move.product_id.name, max(0,qty_available), uom_record.name) raise Warning(_("No hay stock suficiente: "),_(warn_msg)) move.action_done() return True @api.multi def get_location_qty(self, product_id, location_id): suma = 0 quant_ids = self.env['stock.quant'].search([('product_id','=', product_id),('location_id','=',location_id)]) if quant_ids: for quant_id in quant_ids: suma = suma + quant_id.qty return suma