Example #1
0
def ajustar_seriesinventario_byarticulo( **kwargs ):
    # Parametros
    msg = ''
    connection_name = kwargs.get('connection_name', None)
    unidades = kwargs.get('unidades', None)
    articulo = kwargs.get('articulo', None)
    articulo_clave = kwargs.get('articulo_clave', None)
    entrada = kwargs.get('entrada', None)
    almacen = kwargs.get('almacen', None)
    salida = kwargs.get('salida', None)
    request_username = kwargs.get('request_username', None)
    series = kwargs.get('series', None)
    ubicacion = kwargs.get('ubicacion', None)
    
    detalle = None
    #DETALLES ENTRADAS
    if unidades > 0:
        detalle = InventariosDocumentoDetalle.objects.get_or_create(articulo=articulo, doctosIn=entrada, defaults={
            'id': next_id('ID_DOCTOS', connection_name),
            'doctosIn': entrada,
            'almacen': entrada.almacen,
            'concepto': entrada.concepto,
            'tipo_movto': 'E',
            'claveArticulo': articulo_clave,
            'articulo': articulo,
            'unidades': 0,
            'usuario_ult_modif': request_username,
        })[0]

    #DETALLES SALIDAS
    if unidades < 0:    
        detalle = InventariosDocumentoDetalle.objects.get_or_create(
            articulo=articulo, doctosIn=salida,
            defaults={
                'id': next_id('ID_DOCTOS', connection_name),
                'doctosIn': salida,
                'almacen': salida.almacen,
                'concepto': salida.concepto,
                'tipo_movto': 'S',
                'claveArticulo': articulo_clave,
                'articulo': articulo,
                'unidades': 0,
                'usuario_ult_modif': request_username,
            })[0]

    for serie in series:
        articulo_discreto = ArticuloDiscreto.objects.get_or_create(
            clave=serie,
            articulo=articulo,
            tipo='S',
            defaults={'id': next_id('ID_CATALOGOS', connection_name), 
            })[0]

        if detalle.tipo_movto == 'E':
            
            if ArticuloDiscretoExistencia.objects.filter(articulo_discreto__articulo=articulo, existencia__gt=0, almacen=almacen, articulo_discreto__clave=serie).exists():
                unidades =  unidades -1

            try:
                existencia_disc = ArticuloDiscretoExistencia.objects.get(articulo_discreto= articulo_discreto, almacen= almacen,)
            except ObjectDoesNotExist:
                ArticuloDiscretoExistencia.objects.create(id= next_id('ID_DOCTOS', connection_name), existencia= 1, articulo_discreto= articulo_discreto, almacen= almacen,)
            else:
                existencia_disc.existencia=1
                existencia_disc.save()

        elif detalle.tipo_movto == 'S':
            ArticuloDiscretoExistencia.objects.filter(articulo_discreto= articulo_discreto, almacen = almacen).update(existencia=0)
            
        InventariosDesgloseEnDiscretos.objects.get_or_create(
                    docto_in_det=detalle,
                    art_discreto=articulo_discreto,
                    defaults= {
                        'id': next_id('ID_DOCTOS', connection_name),
                        'unidades': 1,
                    },
                )

    if unidades < 0:
        unidades = - unidades    
    
    detalle.unidades = detalle.unidades + unidades
    detalle.costo_unitario = articulo.costo_ultima_compra
    detalle.costo_total = detalle.unidades * detalle.costo_unitario
    detalle.fechahora_ult_modif = datetime.now()

    if detalle.detalle_modificacionestime == None:
        detalle.detalle_modificacionestime = ''

    detalle.detalle_modificacionestime += '%s %s/%s=%s,'%( datetime.now().strftime("%d-%b-%Y %I:%M %p"), request_username, ubicacion, unidades)
    detalle.save( update_fields = [ 'unidades', 'fechahora_ult_modif','detalle_modificacionestime', ] )
    return msg
Example #2
0
def add_articulos_sincontar( **kwargs ):
    """ Agrega articulos almacenables de la linea indicada faltantes en los documentos de ajustes indicados.  """
    #Paramentros 
    request_username = kwargs.get( 'request_username', None )
    connection_name = kwargs.get( 'connection_name', None )
    ubicacion = kwargs.get( 'ubicacion', None )
    linea = kwargs.get( 'linea', None )
    almacen = kwargs.get( 'almacen', None )
    
    message= ''
    
    articulos_endocumentos = list( set( InventariosDocumentoDetalle.objects.filter(
        Q( doctosIn__concepto = 27 ) | Q( doctosIn__concepto = 38 ),
        almacen = almacen,
        doctosIn__descripcion = 'ES INVENTARIO'
        ).order_by( '-articulo' ).values_list( 'articulo__id', flat = True ) ) )
    inventario_descripcion = ''
    #Para agregar los articulos de los documentos de inventarios como ya contados
    if linea:
        #VALIDACIONES
        if InventariosDocumentoIF.objects.filter(descripcion= 'ARTICULOS SIN CONTAR', aplicado= 'N', almacen= almacen).exists():
            message = 'Ya se genero anteriormente un documento con articulos sin contar de todos los articulos, OPERACION RECHAZADA!!'
            return json.dumps( { 'articulos_agregados' : 0, 'articulo_pendientes' : 0, 'message': message, } )

        inventario_descripcion = 'ARTICULOS SIN CONTAR LINEA(%s)'% linea.nombre
        articulos_all = list( set( Articulo.objects.exclude(estatus = 'B').filter( es_almacenable = 'S', linea = linea ).order_by( '-id' ).values_list( 'id', flat = True ) ))
        
    else:
        inventario_descripcion = 'ARTICULOS SIN CONTAR'
        articulos_all = list( set( Articulo.objects.exclude( estatus = 'B').filter( es_almacenable = 'S').order_by( '-id' ).values_list( 'id', flat = True )))

    inventarios_fisicos =  InventariosDocumentoIF.objects.filter(descripcion__contains= inventario_descripcion, aplicado= 'N', almacen= almacen)

    for inventario_fisico in inventarios_fisicos:
        articulos_endocumentosinv = (
                list( set( InventariosDocumentoIFDetalle.objects.filter( docto_invfis = inventario_fisico, ).order_by( '-articulo' ).values_list( 'articulo__id', flat = True ) ) 
            )
        )

        articulos_endocumentos = articulos_endocumentos + articulos_endocumentosinv

    articulos_sincontar = [n for n in articulos_all if n not in articulos_endocumentos]
    total_articulos_sincontar = len(articulos_sincontar)
    articulos_sincontar = articulos_sincontar[0:9000]
    articulos_sincontar_list = split_seq( articulos_sincontar, 2000 )

    articulos_agregados = 0
    ultimofolio = Registry.objects.filter( nombre = 'SIG_FOLIO_INVFIS' )

    if total_articulos_sincontar <= 0:
        message = 'No hay articulos por agregar!!'
        return json.dumps( { 'articulos_agregados' : 0, 'articulo_pendientes' : 0, 'message': message, } )

    if not ultimofolio.exists():
        message = 'Para poder crear un inventario es nesesario Asignarles folios automaticos a los inventarios fisicos, OPERACION RECHAZADA!!'
        return json.dumps( { 'articulos_agregados' : 0, 'articulo_pendientes' : 0, 'message': message, } )

    inventario = InventariosDocumentoIF.objects.create(
            id = next_id('ID_DOCTOS', connection_name),
            folio = inventario_getnew_folio(),
            fecha = datetime.now(),
            almacen = almacen,
            descripcion = inventario_descripcion,
            usuario_creador = request_username,
            usuario_aut_creacion = 'SYSDBA',
            usuario_ult_modif = request_username,
            usuario_aut_modif = 'SYSDBA',
        )

    for articulos_sincontar_sublist in articulos_sincontar_list:
        detalles_en_ceros = 0
        for articulo_id in articulos_sincontar_sublist:
            articulo = Articulo.objects.get(pk=articulo_id)
            InventariosDocumentoIFDetalle.objects.create(
                    id = -1,
                    docto_invfis = inventario,
                    clave = first_or_none( ArticuloClave.objects.filter( articulo = articulo ) ),
                    articulo = articulo,
                    unidades = 0,
                )
            detalles_en_ceros = detalles_en_ceros + 1

        articulos_agregados = articulos_agregados + detalles_en_ceros

    articulos_pendientes = total_articulos_sincontar -  articulos_agregados
    return json.dumps( { 'articulos_agregados' : articulos_agregados, 'articulo_pendientes' : articulos_pendientes, 'message': message, } )
Example #3
0
def add_existenciasarticulo_byajustes( **kwargs ):
    """ Para agregar existencia a un articulo por ajuste 
        En caso de que el articulo no tenga costo indicado [se le aplica el de la ultima compra]
    """

    #Paramentros
    ajustar_primerconteo = kwargs.get( 'ajustar_primerconteo', None )
    ubicacion = kwargs.get( 'ubicacion', None )
    articulo_id = kwargs.get( 'articulo_id', None )
    articulo = Articulo.objects.get( pk = articulo_id )

    entrada_id = kwargs.get( 'entrada_id', None )
    entrada = InventariosDocumento.objects.get( pk = entrada_id )
    salida_id = kwargs.get( 'salida_id', None )
    salida = InventariosDocumento.objects.get( pk = salida_id )
    
    almacen_id = kwargs.get( 'almacen_id', None )
    almacen = Almacen.objects.get( pk = almacen_id)

    request_session = kwargs.get( 'request_session', 0 )
    request_user = kwargs.get( 'request_user', 0 )
    connection_name = get_conecctionname( request_session )
    
    detalle_unidades = kwargs.get( 'detalle_unidades', 0 )
    detalle_costo_unitario = kwargs.get( 'detalle_costo_unitario', articulo.costo_ultima_compra )

    puede_modificar_costos = allow_microsipuser( username = request_user.username, clave_objeto = 469) and almacen.inventario_modifcostos

    detalles_entradas_ultimocosto = first_or_none( InventariosDocumentoDetalle.objects.filter(
            Q( doctosIn__concepto = 27 ),
            articulo = articulo,
            almacen = almacen,
            doctosIn__descripcion = 'ES INVENTARIO'
            ).order_by('-fechahora_ult_modif').values_list( 'costo_unitario', flat = True ) )

    if not detalles_entradas_ultimocosto:
         detalles_entradas_ultimocosto = articulo.costo_ultima_compra

    existe_en_detalles = InventariosDocumentoDetalle.objects.filter( 
        Q( doctosIn__concepto = 27 ) | Q( doctosIn__concepto = 38 ),
        articulo = articulo,
        almacen = almacen,
        doctosIn__descripcion = 'ES INVENTARIO',
        ).count() > 0

    detalle_entradas = first_or_none( InventariosDocumentoDetalle.objects.filter( articulo = articulo, doctosIn = entrada ) )
    detalle_salidas = first_or_none( InventariosDocumentoDetalle.objects.filter( articulo = articulo, doctosIn = salida ) )
    articulo_clave = first_or_none( ArticuloClave.objects.filter( articulo = articulo ) )

    detalle = InventariosDocumentoDetalle(
        articulo = articulo,
        claveArticulo = articulo_clave,
        almacen = almacen,
        unidades = detalle_unidades,
        )
    
    #Logica
    existencia_inicial = ''
    #Si no se existe arituclo en documentos se ajustan unidades
    if not existe_en_detalles:
        existencia_inicial = get_existencias_articulo(
                articulo_id = articulo.id, 
                connection_name = connection_name, 
                fecha_inicio = datetime.now().strftime( "01/01/%Y" ),
                almacen = almacen, 
            )  
        detalle.detalle_modificacionestime ='EXISTIN=%s / COSTOIN=%s,'%(existencia_inicial, articulo.costo_ultima_compra)
        
        if ajustar_primerconteo:
            detalle.unidades = ajustar_existencias( articulo_id = articulo.id, ajustar_a = detalle.unidades ,almacen = almacen , connection_name = connection_name )
        
    es_nuevo = False

    #SALIDA
    if detalle.unidades <= 0:
        #si no existe detalle salidas
        if not detalle_salidas:
            es_nuevo = True
            detalle_salidas = detalle
            detalle_salidas.id = next_id( 'ID_DOCTOS', connection_name )
            detalle_salidas.doctosIn = salida
            detalle_salidas.concepto = salida.concepto
            detalle_salidas.tipo_movto ='S'
            detalle_salidas.unidades = -detalle_salidas.unidades
        #Si exitse detalle salidas
        elif detalle_salidas:
            detalle_salidas.unidades = detalle_salidas.unidades + ( -detalle.unidades ) 

        #Desde salida no se permite cambiar costo unitario
        detalle_salidas.costo_unitario = detalles_entradas_ultimocosto
        detalle = detalle_salidas
    
    #ENTRADA
    elif detalle.unidades > 0:
        if not detalle_entradas:
            es_nuevo = True
            detalle_entradas = detalle
            detalle_entradas.id = next_id( 'ID_DOCTOS', connection_name )
            detalle_entradas.doctosIn = entrada
            detalle_entradas.concepto = entrada.concepto
            detalle_entradas.tipo_movto ='E'

        elif detalle_entradas:
            detalle_entradas.unidades = detalle_entradas.unidades + detalle.unidades
            
        detalle = detalle_entradas
    
    costo_modificaciones = ''
    #MODIFICA COSTOS
    if puede_modificar_costos:
        if detalle.tipo_movto == 'E':
            detalle.costo_unitario = detalle_costo_unitario 
            #Afecta costo en articulo
            if articulo.costo_ultima_compra !=  detalle.costo_unitario:
                articulo.costo_ultima_compra = detalle.costo_unitario
                articulo.save(update_fields=['costo_ultima_compra',])
                costo_modificaciones = 'COSTO(%s)'%detalle.costo_unitario

        #si se ajusto el conteo pero en realidad se metieron unidades positivas cambia costo de compra
        if detalle.tipo_movto == 'S' and detalle_unidades >= 0:
            detalle.costo_unitario = detalle_costo_unitario 
            #Afecta costo en articulo
            if articulo.costo_ultima_compra !=  detalle.costo_unitario:
                articulo.costo_ultima_compra = detalle.costo_unitario
                articulo.save(update_fields=['costo_ultima_compra',])
                costo_modificaciones = 'COSTO(%s)'%detalle.costo_unitario
    else:
        #si el articulo no tiene costo de ultima compra se le manda en 0
        detalle.costo_unitario = articulo.costo_ultima_compra
        if not detalle.costo_unitario:
            detalle.costo_unitario = 0
    
    detalle.costo_total = detalle.unidades * detalle.costo_unitario
    detalle.fechahora_ult_modif = datetime.now()

    # HISTORIAL DE MODIFICACIONES
    if detalle.detalle_modificacionestime == None:
        detalle.detalle_modificacionestime = ''
    detalle_ajuste = '' 
    if not existe_en_detalles:   
        if ajustar_primerconteo:
            if detalle.tipo_movto == 'S':
                detalle_ajuste = '(AJ=-%s)'% detalle.unidades
            elif detalle.tipo_movto == 'E': 
                detalle_ajuste = '(AJ=%s)'% detalle.unidades

    detalle.detalle_modificacionestime += '%s %s/%s=%s%s%s,'%( datetime.now().strftime("%d-%b-%Y %I:%M %p"), request_user.username, ubicacion, detalle_unidades, detalle_ajuste, costo_modificaciones)

    if es_nuevo:
        detalle.save()
    else:    
        detalle.save( update_fields = [ 'unidades', 'costo_unitario', 'costo_total', 'fechahora_ult_modif','detalle_modificacionestime', ] );

    c = connections[ connection_name ].cursor()
    c.execute( "DELETE FROM SALDOS_IN where saldos_in.articulo_id = %s;"% articulo.id )
    c.execute( "EXECUTE PROCEDURE RECALC_SALDOS_ART_IN %s;"% articulo.id )
    transaction.commit_unless_managed()
    c.close()

    management.call_command( 'syncdb', database = connection_name )

    exitencia = get_existencias_articulo(
        articulo_id = articulo.id, 
        connection_name = connection_name, 
        fecha_inicio = datetime.now().strftime( "01/01/%Y" ),
        almacen = almacen, 
        )

    datos = {'error_message': '', 'alamcen_id': almacen.ALMACEN_ID, 'articulo_nombre': articulo.nombre, 'existencia_actual': str(exitencia) }
    
    return datos