Browse Source

First commit

deisy 5 years ago
commit
f72209cb4a

+ 2 - 0
__init__.py

@@ -0,0 +1,2 @@
+# -*- coding : utf-8 -*-
+import models

BIN
__init__.pyc


+ 13 - 0
__openerp__.py

@@ -0,0 +1,13 @@
+# -*- coding: utf-8 -*-
+{
+    'name': 'Stock Transfer Order',
+    'version': '8.0.0.1',
+    'category': 'Stock',
+    'summary': 'Tranferencia interna de stock en base al pedido de venta',
+    'author': 'Eiru Software',
+    'data': [
+        'views/stock_transfer_order.xml',
+        'wizard/wizard_transfer_details.xml'],
+    'depends': ['base','sale','stock','sale_stock'],
+    'installable':True,
+}

+ 2 - 0
models/__init__.py

@@ -0,0 +1,2 @@
+# -*- coding : utf-8 -*-
+import stock_transfer_order

BIN
models/__init__.pyc


+ 192 - 0
models/stock_transfer_order.py

@@ -0,0 +1,192 @@
+# -*- 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_location_id = fields.Many2one('stock.location', string="Head source location", related='picking_type_id.default_location_src_id', store=False, readonly=True)
+    picking_destination_location_id = fields.Many2one('stock.location', string="Head destination location", related='picking_type_id.default_location_dest_id', store=False, readonly=True)
+
+
+    @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 %s posee %.2f %s disponible!') % \
+                    (item.quantity, uom_record.name,
+                    item.product_id.name,
+                    item.sourceloc_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'})
+        return True
+
+    @api.multi
+    def get_location_qty(self, product_id, location_id):
+        location_ids = self.env['stock.location'].search([('active','=',True),('usage','=','internal'),('id','!=',self.picking_type_id.default_location_dest_id.id)])
+        for id in location_ids:
+            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')
+    sourceloc_id = fields.Many2one('stock.location', 'Ubicación Origen',required=True)
+    destinationloc_id = fields.Many2one('stock.location', 'Ubicación Destino',required=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,
+                    'sourceloc_id' : created_id.picking_type_id.default_location_src_id.id,
+                    'destinationloc_id' : created_id.picking_type_id.default_location_dest_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_location(models.Model):
+    _inherit = "stock.location"
+
+    @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.id)])
+                if quant_ids:
+                    for quant_id in quant_ids:
+                        suma = suma + quant_id.qty
+
+                res.append((location.id, ("%(location_parent)s/%(location_name)s - %(location_qty)s") % {
+                    'location_parent': location.location_id.name,
+                    'location_name': location.name,
+                    'location_qty': suma
+                }))
+        else:
+            for record in self:
+                res.append((record.id, ("%(location_parent)s/%(location_name)s") % {
+                    'location_parent': record.location_id.name or "",
+                    '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:
+                move.action_done()
+        return True

BIN
models/stock_transfer_order.pyc


BIN
static/description/icon.png


+ 46 - 0
views/stock_transfer_order.xml

@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+  <data>
+
+    <!-- Override workflow -->
+    <record id="sale.trans_wait_invoice_invoice" model="workflow.transition">
+      <field name="act_from" ref="sale.act_router"/>
+      <field name="act_to" ref="sale.act_wait_invoice"/>
+    </record>
+
+    <record id="sale_order_form_invoice_credit" model="ir.ui.view">
+      <field name="name">sale_order_form_invoice_credit</field>
+      <field name="model">sale.order</field>
+      <field name="inherit_id" ref="sale.view_order_form"/>
+      <field name="arch" type="xml">
+        <button name="invoice_cancel" states="invoice_except" position="after">
+          <button name="stock_transfer_action" string="Transferencia Interna" type="object" attrs="{'invisible': ['|',('invoice_exists', '=', True),('state','!=','progress')]}" groups="stock.group_stock_manager"/>
+        </button>
+      </field>
+    </record>
+
+    <record id="inherit_view_picking_form" model="ir.ui.view">
+      <field name="name">inherit_view_picking_form</field>
+      <field name="model">stock.picking</field>
+      <field name="inherit_id" ref="stock.view_picking_form"/>
+      <field name="arch" type="xml">
+
+
+        <button name="do_enter_transfer_details" position="replace">
+          <button name="entregar_producto" string="Entregar" groups="stock.group_stock_user" type="object" class="oe_highlight"/>
+        </button>
+
+          <button name="force_assign" position="attributes">
+            <attribute name="invisible">1</attribute>
+          </button>
+
+          <button name="action_assign" position="attributes">
+            <attribute name="invisible">1</attribute>
+          </button>
+
+
+      </field>
+    </record>
+
+  </data>
+</openerp>

+ 39 - 0
wizard/wizard_transfer_details.xml

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<openerp>
+    <data>
+        <record id="wizard_transfer_details" model="ir.ui.view">
+            <field name="name">Enter transfer details</field>
+            <field name="model">stock.transfer.order.details</field>
+            <field name="arch" type="xml">
+                <form string="Transfer details" version="7">
+                  <field name="picking_source_location_id" invisible="True"/>
+                  <field name="picking_destination_location_id" invisible="True"/>
+                  <group>
+                  <field name="picking_type_id"/>
+                </group>
+
+        <group string="Productos a transferir"></group>
+                <group>
+                        <field name="item_ids" context="{'default_sourceloc_id':picking_source_location_id,
+                                  'default_destinationloc_id':picking_destination_location_id}" nolabel="1">
+                            <tree string="Detalles" editable="bottom" >
+                                <field name="product_id" context="{'uom':product_uom_id}" on_change="product_id_change(product_id,product_uom_id,context)"/>
+                                <field name="quantity"/>
+                                <field name="product_uom_id" options="{&quot;no_open&quot;: True}" groups="product.group_uom"/>
+                                <field name="sourceloc_id" domain="[('usage', '=', 'internal')]" context="{'nombre_para_stock_transfer': True, 'transfer_product_id':product_id}"/>
+                                <field name="destinationloc_id" domain="[('usage', '=', 'internal')]" context="{'nombre_para_stock_transfer': False}"/>
+                            </tree>
+                        </field>
+                      </group>
+
+                    <footer>
+                        <button name="do_detailed_transfer2" string="Transferir" type="object" class="oe_highlight"/>
+                        or
+                        <button string="_Cancel" class="oe_link" special="cancel" />
+                    </footer>
+                </form>
+            </field>
+        </record>
+
+    </data>
+</openerp>