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
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, } )
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