def ajustar_existencias( **kwargs ): ''' Para ajustar un articulo a las unidades indicadas sin importar su existencia actual ''' #Paramentros articulo_id = kwargs.get( 'articulo_id', None ) ajustar_a = kwargs.get( 'ajustar_a', None ) almacen = kwargs.get( 'almacen', None ) connection_name = kwargs.get( 'connection_name', None ) inv_fin = get_existencias_articulo( articulo_id = articulo_id, connection_name = connection_name, fecha_inicio = datetime.now().strftime( "01/01/%Y" ), almacen = almacen, ) unidades_a_insertar = -inv_fin + ajustar_a return unidades_a_insertar
def ClonarExistencia(sender, **kwargs): ''' para en la aplicacion inventarios fisicos generar entradas y salidas en el almacen clon. ''' almacen_clon = first_or_none( Almacen.objects.filter(pk= almacen_clon_id) ) detalle = kwargs.get('instance') if almacen_clon and detalle.almacen != almacen_clon: if not almacen_clon.inventariando: almacen_clon.inventariando = True almacen_clon.inventario_conajustes = detalle.almacen.inventario_conajustes almacen_clon.inventario_modifcostos = detalle.almacen.inventario_modifcostos almacen_clon.save() entrada_clon, salida_clon = ajustes_get_or_create(almacen_id = almacen_clon.ALMACEN_ID, username = detalle.usuario_ult_modif) old_detalle = first_or_none(InventariosDocumentoDetalle.objects.filter(pk=detalle.id)) existe_en_detalles = InventariosDocumentoDetalle.objects.filter( Q( doctosIn__concepto = 27 ) | Q( doctosIn__concepto = 38 ), articulo = detalle.articulo, almacen = detalle.almacen, doctosIn__descripcion = 'ES INVENTARIO', ).count() > 0 unidades_diferencia = detalle.unidades #ajustar en primer conteo if detalle.almacen.inventario_conajustes and not existe_en_detalles: existencia_articulo = get_existencias_articulo( articulo_id = detalle.articulo.id, connection_name = kwargs.get('using'), fecha_inicio = datetime.now().strftime( "01/01/%Y" ), almacen = almacen_clon, ) detalle_existencia_articulo = get_existencias_articulo( articulo_id = detalle.articulo.id, connection_name = kwargs.get('using'), fecha_inicio = datetime.now().strftime( "01/01/%Y" ), almacen = detalle.almacen, ) if detalle.tipo_movto == 'E': detalle_existencia_final = detalle.unidades + detalle_existencia_articulo elif detalle.tipo_movto == 'S': detalle_existencia_final = detalle_existencia_articulo - detalle.unidades unidades_diferencia = -existencia_articulo + detalle_existencia_final if old_detalle: if old_detalle.tipo_movto == 'E': unidades_diferencia = detalle.unidades - old_detalle.unidades elif old_detalle.tipo_movto == 'S': unidades_diferencia = (detalle.unidades - old_detalle.unidades)*-1 else: if detalle.tipo_movto == 'E': unidades_diferencia = detalle.unidades elif detalle.tipo_movto == 'S': unidades_diferencia = detalle.unidades *-1 #Entrada if unidades_diferencia >= 0: detalle_clon = first_or_none( InventariosDocumentoDetalle.objects.filter(doctosIn=entrada_clon, articulo=detalle.articulo )) if detalle_clon: detalle_clon_unidades =detalle_clon.unidades detalle_clon.unidades = detalle_clon.unidades + unidades_diferencia detalle_clon.costo_unitario = detalle.costo_unitario detalle_clon.costo_total = detalle_clon.unidades * detalle_clon.costo_unitario detalle_clon.save() else: detalle_clon = InventariosDocumentoDetalle.objects.create( doctosIn = entrada_clon, almacen = almacen_clon, concepto = entrada_clon.concepto, claveArticulo = detalle.claveArticulo, articulo = detalle.articulo, tipo_movto = 'E', unidades = unidades_diferencia, costo_unitario = detalle.costo_unitario, costo_total = unidades_diferencia * detalle.costo_unitario, usuario_ult_modif = detalle.usuario_ult_modif ) #Salida elif unidades_diferencia < 0: detalle_clon = first_or_none( InventariosDocumentoDetalle.objects.filter(doctosIn=salida_clon, articulo=detalle.articulo )) unidades_diferencia = unidades_diferencia * -1 if detalle_clon: detalle_clon.unidades = detalle_clon.unidades + unidades_diferencia detalle_clon.costo_unitario = detalle.costo_unitario detalle_clon.costo_total = detalle_clon.unidades * detalle_clon.costo_unitario detalle_clon.save() else: detalle_clon = InventariosDocumentoDetalle.objects.create( doctosIn = salida_clon, almacen = almacen_clon, concepto = salida_clon.concepto, claveArticulo = detalle.claveArticulo, articulo = detalle.articulo, tipo_movto = 'S', unidades = unidades_diferencia, costo_unitario = detalle.costo_unitario, costo_total = unidades_diferencia * detalle.costo_unitario, usuario_ult_modif = detalle.usuario_ult_modif ) c = connections[ kwargs.get('using') ].cursor() c.execute( "DELETE FROM SALDOS_IN where saldos_in.articulo_id = %s;"% detalle_clon.articulo.id ) c.execute( "EXECUTE PROCEDURE RECALC_SALDOS_ART_IN %s;"% detalle_clon.articulo.id ) transaction.commit_unless_managed() c.close() management.call_command( 'syncdb', database = kwargs.get('using') )
def get_existenciasarticulo_byid( request, **kwargs ): """ Para obterner existencia de un articulo segun id del articulo """ #Paramentros almacen_nombre = kwargs.get( 'almacen', None) almacen = Almacen.objects.get(nombre = almacen_nombre) articulo_id = kwargs.get( 'articulo_id', None) entrada_id = kwargs.get( 'entrada_id', None ) connection_name = get_conecctionname( request.session ) detalle_modificacionestime = '' detalle_modificacionestime_salidas = '' ya_ajustado = False articulo = Articulo.objects.get( pk = articulo_id ) detalles_all = InventariosDocumentoDetalle.objects.filter( Q( doctosIn__concepto = 27 ) | Q( doctosIn__concepto = 38 ), articulo = articulo, almacen = almacen, doctosIn__descripcion = 'ES INVENTARIO').order_by('fechahora_ult_modif') if detalles_all: ya_ajustado = True else: 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 ) inv_fin = get_existencias_articulo( articulo_id = articulo_id , connection_name = connection_name, fecha_inicio = datetime.now().strftime( "01/01/%Y" ), almacen = almacen_nombre, ) detalles_entradas = InventariosDocumentoDetalle.objects.filter( Q( doctosIn__concepto = 27 ), articulo = articulo, almacen = almacen, doctosIn__descripcion = 'ES INVENTARIO').order_by('fechahora_ult_modif') detalles_salidas = InventariosDocumentoDetalle.objects.filter( Q( doctosIn__concepto = 38 ), articulo = articulo, almacen = almacen, doctosIn__descripcion = 'ES INVENTARIO').order_by('fechahora_ult_modif') for detalle_entradas in detalles_entradas: if not detalle_entradas.detalle_modificacionestime: detalle_entradas.detalle_modificacionestime = '' detalle_modificacionestime = detalle_modificacionestime + detalle_entradas.detalle_modificacionestime for detalle_salidas in detalles_salidas: if not detalle_salidas.detalle_modificacionestime: detalle_salidas.detalle_modificacionestime = '' detalle_modificacionestime_salidas = detalle_modificacionestime_salidas + detalle_salidas.detalle_modificacionestime #si el articulo no tiene costo de ultima compra se le manda en 0 costo_ultima_compra = articulo.costo_ultima_compra if not costo_ultima_compra: costo_ultima_compra = 0 if not detalle_modificacionestime: detalle_modificacionestime = '' try: articulo_linea = articulo.linea.nombre except ObjectDoesNotExist: articulo_linea = 'No indicada aun' return json.dumps( { 'existencias' : int( inv_fin ), 'ya_ajustado': ya_ajustado, 'articulo_seguimiento' : articulo.seguimiento, 'costo_ultima_compra' : str(costo_ultima_compra), 'detalle_modificacionestime': detalle_modificacionestime, 'detalle_modificacionestime_salidas': detalle_modificacionestime_salidas, 'articulo_linea' : articulo_linea })
def get_existenciasarticulo_byclave( request, **kwargs ): """ Para obterner existencia de un articulo segun clave del articulo """ #Paramentros almacen_nombre = kwargs.get( 'almacen', None) almacen = Almacen.objects.get(nombre = almacen_nombre) entrada_id = kwargs.get( 'entrada_id', None ) articulo_clave = kwargs.get( 'articulo_clave', None) connection_name = get_conecctionname( request.session ) #variables de salida error = "" inv_fin = 0 articulo_linea = '' articulo_id = '' articulo_nombre = '' articulo_seguimiento = '' costo_ultima_compra= '' clave_articulo = first_or_none( ArticuloClave.objects.filter( clave = articulo_clave, articulo__estatus = 'A')) if clave_articulo: if clave_articulo.articulo.seguimiento == 'L': clave_articulo = None opciones_clave = {} detalle_modificacionestime = '' detalle_modificacionestime_salidas = '' ya_ajustado = False if clave_articulo: articulo = Articulo.objects.get( pk = clave_articulo.articulo.id ) detalles_all = InventariosDocumentoDetalle.objects.filter( Q( doctosIn__concepto = 27 ) | Q( doctosIn__concepto = 38 ), articulo = articulo, almacen = almacen, doctosIn__descripcion = 'ES INVENTARIO').order_by('fechahora_ult_modif') if detalles_all: ya_ajustado = True else: 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 ) inv_fin = get_existencias_articulo( articulo_id = articulo.id, connection_name = connection_name, fecha_inicio = datetime.now().strftime( "01/01/%Y" ), almacen = almacen_nombre, ) articulo_id = articulo.id articulo_nombre = articulo.nombre try: articulo_linea = articulo.linea.nombre except ObjectDoesNotExist: articulo_linea = 'No indicada aun' articulo_seguimiento = articulo.seguimiento detalles_entradas = InventariosDocumentoDetalle.objects.filter( Q( doctosIn__concepto = 27 ), articulo = articulo, almacen = almacen, doctosIn__descripcion = 'ES INVENTARIO' ).order_by('fechahora_ult_modif') detalles_salidas = InventariosDocumentoDetalle.objects.filter( Q( doctosIn__concepto = 38 ), articulo = articulo, almacen = almacen, doctosIn__descripcion = 'ES INVENTARIO').order_by('fechahora_ult_modif') for detalle_entradas in detalles_entradas: if not detalle_entradas.detalle_modificacionestime: detalle_entradas.detalle_modificacionestime ='' detalle_modificacionestime = detalle_modificacionestime + detalle_entradas.detalle_modificacionestime for detalle_salidas in detalles_salidas: if not detalle_salidas.detalle_modificacionestime: detalle_salidas.detalle_modificacionestime = '' detalle_modificacionestime_salidas = detalle_modificacionestime_salidas + detalle_salidas.detalle_modificacionestime #si el articulo no tiene costo de ultima compra se le manda en 0 costo_ultima_compra = articulo.costo_ultima_compra if not costo_ultima_compra: costo_ultima_compra = 0 else: error = "no_existe_clave" claves = ArticuloClave.objects.filter( clave__contains = articulo_clave, articulo__estatus='A',) for c in claves: if c.articulo.seguimiento == 'S' or c.articulo.seguimiento == 'N': opciones_clave[ str( c.clave ) ] = c.articulo.nombre if not detalle_modificacionestime: detalle_modificacionestime = '' datos = { 'error_msg' : error, 'ya_ajustado': ya_ajustado, 'articulo_id' : articulo_id, 'articulo_seguimiento': articulo_seguimiento, 'articulo_nombre' : articulo_nombre, 'existencias' : str(inv_fin), 'costo_ultima_compra' : str(costo_ultima_compra), 'opciones_clave': opciones_clave, 'detalle_modificacionestime': detalle_modificacionestime, 'detalle_modificacionestime_salidas': detalle_modificacionestime_salidas, 'articulo_linea' : articulo_linea, } return HttpResponse( json.dumps( datos ), mimetype = "application/javascript" )
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
def add_seriesinventario_byarticulo( request, **kwargs ): # Parametros connection_name = get_conecctionname(request.session) error = False articulo_id = request.GET.get('articulo_id', None) articulo = Articulo.objects.get(pk=articulo_id) articulo_clave = first_or_none( ArticuloClave.objects.filter(articulo=articulo)) almacen_id = request.GET.get('almacen_id', None) almacen = Almacen.objects.get(ALMACEN_ID=almacen_id) entrada_id = request.GET.get('entrada_id', None) entrada = InventariosDocumento.objects.get(pk=entrada_id) salida_id = request.GET.get('salida_id', None) salida = InventariosDocumento.objects.get(pk=salida_id) ubicacion = request.GET.get('ubicacion', None) unidades = request.GET.get('unidades', None) unidades = int(unidades) ajusteprimerconteo = almacen.inventario_conajustes series = request.GET.get('series', None) series = series.split(',') msg = '' existe_en_detalles = InventariosDocumentoDetalle.objects.filter( Q(doctosIn__concepto=27) | Q(doctosIn__concepto=38), articulo=articulo, almacen=almacen, doctosIn__descripcion='ES INVENTARIO', ).count() > 0 #Checar numeros de serie for serie in series: if ArticuloDiscretoExistencia.objects.filter(articulo_discreto__articulo=articulo, existencia__gt=0, almacen=almacen, articulo_discreto__clave=serie).exists() and serie != '' and unidades > 0 : #Si es la primera ves que se cuenta if not ajusteprimerconteo or (ajusteprimerconteo and existe_en_detalles): msg = '%s El numero de serie %s ya esta registrado.' % (msg, serie) elif not ArticuloDiscretoExistencia.objects.filter(articulo_discreto__articulo=articulo, existencia__gt=0, almacen=almacen, articulo_discreto__clave=serie).exists() and serie != '' and unidades < 0: msg = '%s El numero de serie %s no esta registrado.' % (msg, serie) if serie == '': series.remove(serie) if ajusteprimerconteo and not existe_en_detalles and unidades < 0: msg= 'No esta permitido ajustar en primer conteo a valores negativos' if msg == '': request_username = request.user.username #AJUSTAR SERIES if ajusteprimerconteo and not existe_en_detalles: existdiscretos_aeliminar = ArticuloDiscretoExistencia.objects.filter(articulo_discreto__articulo=articulo, existencia__gt=0, almacen=almacen).exclude(articulo_discreto__clave__in=series) existdiscretos_aeliminar_count =existdiscretos_aeliminar.count() series_aeliminar = [] for existdiscreto in existdiscretos_aeliminar: series_aeliminar.append(existdiscreto.articulo_discreto.clave) if existdiscretos_aeliminar_count > 0: msg = ajustar_seriesinventario_byarticulo( connection_name = connection_name, unidades = -existdiscretos_aeliminar_count, articulo = articulo, articulo_clave = articulo_clave, entrada = entrada, almacen = almacen, salida = salida, request_username = request_username, series = series_aeliminar, ubicacion = ubicacion, ) msg = ajustar_seriesinventario_byarticulo( connection_name = connection_name, unidades = unidades, articulo = articulo, articulo_clave = articulo_clave, entrada = entrada, almacen = almacen, salida = salida, request_username = request_username, series = series, ubicacion = ubicacion, ) else: msg = ajustar_seriesinventario_byarticulo( connection_name = connection_name, unidades = unidades, articulo = articulo, articulo_clave = articulo_clave, entrada = entrada, almacen = almacen, salida = salida, request_username = request_username, series = series, ubicacion = ubicacion, ) 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 ) if msg == '': msg = 'Movimiento registrado correctamente' exitencia = get_existencias_articulo( articulo_id = articulo.id, connection_name = connection_name, fecha_inicio = datetime.now().strftime( "01/01/%Y" ), almacen = almacen, ) else: error = True exitencia ='' data = { 'msg' : msg, 'error': error, 'articulo_nombre': articulo.nombre, 'existencia_actual': str(exitencia), } return HttpResponse(json.dumps(data), mimetype="application/json")