Ejemplo n.º 1
0
def etiqueta_nied(rollos, mostrar_marcado = False):
    """
    Genera un PDF con tantas páginas iguales como número de elementos tenga 
    la lista de rollos recibida.
    Si el rollo va a 0.80 m de ancho, devuelve en cada página el diseño 
    de GNT11_080.pdf. Si va a un metro, el diseño de GNT11_100.pdf.
    En otro caso usa el GNT11_120.pdf por defecto.
    """
    try:
        pv = rollos[0]['objeto'].productoVenta
    except (IndexError, AttributeError):
        nomarchivo = os.path.abspath(os.path.join(os.path.dirname(__file__), 
                                                  "GNT11_120.pdf"))
    else:
        modelo = "GNT11_120.png"
        try:
            if pv.camposEspecificosRollo.ancho == 0.8:
                modelo = "GNT11_080.png"
            elif pv.camposEspecificosRollo.ancho == 1.0:
                modelo = "GNT11_100.png"
        except AttributeError:
            pass    # Uso modelo por defecto.
        pagina = os.path.abspath(os.path.join(os.path.dirname(__file__), 
                                              modelo))
        height = 12.55 * cm
        width = 8.4 * cm
        nomarchivo = os.path.join(gettempdir(),
                "etiqNied_%s.pdf" % give_me_the_name_baby())
        c = canvas.Canvas(nomarchivo, pagesize = (width, height))
        for rollo in rollos:  # @UnusedVariable
            c.drawImage(pagina, 0, 0, width, height)
            c.showPage()
        c.save()
    return nomarchivo
Ejemplo n.º 2
0
def get_nombre_archivo_from_tv(tv):
    """
    Devuelve el nombre del archivo que se generará a partir
    del nombre del widget TreeView.
    """
    nomtreeview = tv.get_name().replace(" ", "_").replace(":", "_")
    nomarchivo = os.path.join(gettempdir(),
            "%s_%s.csv" % (nomtreeview, geninformes.give_me_the_name_baby()))
    return nomarchivo
Ejemplo n.º 3
0
def get_nombre_archivo_from_tv(tv):
    """
    Devuelve el nombre del archivo que se generará a partir
    del nombre del widget TreeView.
    """
    # Algunos caracteres dan problemas en SO Windows.
    nomtreeview = tv.get_name().replace(" ", "_").replace(":", "_")
    nomarchivo = os.path.join(gettempdir(), "%s_%s.pdf" % (
                    nomtreeview, geninformes.give_me_the_name_baby()))
    return nomarchivo
Ejemplo n.º 4
0
def mandar_a_imprimir_con_ghostscript(fichero, rotate = False):
    """
    Lanza un trabajo de impresión a través de acrobat reader.
    Usa parámetros no documentados y oficialmente no soportados 
    por acrobat. Esta función es temporal, hasta que encuentre 
    un visor/impresor de PDF desde línea de comandos.
    Win-only. No funciona en posix ni aún teniendo el reader
    para esa plataforma (creo).
    NO USAR CON ROLLOS: No cuadra bien la etiqueta y además deja abierta la 
    ventana después.
    Impresora CAB harcoded (y además no es el nombre por defecto de la 
    impresora).
    ¡MENTIRA COCHINA! Lo hace a través de Ghostscript.
    """
    if rotate:
        from lib.PyPDF2 import PyPDF2
        fichrotado = os.path.join(tempfile.gettempdir(), 
                                  "gs_rotated_%s.pdf" % give_me_the_name_baby()
                                 )
        rotado = PyPDF2.PdfFileWriter()
        original = PyPDF2.PdfFileReader(open(fichero, "rb"))
        for page in range(original.getNumPages()):
            rotado.addPage(original.getPage(page).rotateClockwise(270))
        rotado.write(open(fichrotado, "wb"))
        fichero = fichrotado
    # OJO: Ruta al reader harcoded !!!
    #    comando = """"C:\\Archivos de programa\\Adobe\\Acrobat 6.0\\Reader\\AcroRd32.exe" /t "%s" GEMINI2 """ % (fichero)
    #    comando = """start /B AcroRd32 /t "%s" CAB """ % (fichero)
    comando = """gswin32c.exe -dQueryUser=3 -dNoCancel -dNOPAUSE -dBATCH"""\
              """ -sDEVICE=mswinpr2 -sOutputFile="%%printer%%CAB" %s """ % (
                fichero)
    # NOTA: Necesita que: 
    # 1.- La impresora CAB esté como predeterminada en la "carpeta" 
    #     impresoras de Windows.
    # 2.- Tenga la configuración adecuada por defecto (apaisado, tamaño de 
    #     etiqueta, etc.
    # 3.- gs esté en el PATH (añadiendo C:\Archivos de programa...\bin en la 
    #     variable de entorno PATH desde las propiedades avanzadas de Mi PC.)
    if os.system(comando):
        print "No se pudo hacer la impresión directa. Lanzo el visor."
        abrir_pdf(fichero)
Ejemplo n.º 5
0
def etiqueta_rollos_norma13(rollos, mostrar_marcado=True, lang="es"):
    """
    Construye una etiqueta por cada objeto rollo recibido y las devuelve
    en un solo PDF.
    Si lang = "en", etiqueta en inglés. Si "es", en castellano.
    """
    # Voy a tratar de reescribir esto regla en mano a ver si consigo
    # cuadrarlo bien en la etiquetadora GEMINI.
    alto = 12.55 * cm
    ancho = 8.4 * cm

    # Creo la hoja
    nomarchivo = os.path.join(gettempdir(),
                              "etiq_norma13_{}_{}.pdf".format(
                                  lang, give_me_the_name_baby()))
    canvas = reportlabcanvas.Canvas(nomarchivo, pagesize=(ancho, alto))

    # Medidas:
    logo = (3.8 * cm * 0.75, 2.8 * cm * 0.75)
    margen = 0.1 * cm
    marcado = (((ancho - logo[0]) / 2) - margen, (alto - margen - logo[1] - 2))

    # Imágenes:
    logo_marcado = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "imagenes", "CE.png"))

    # Datos fijos:
    # pylint: disable=bad-continuation
    _data = {# "00 logo_marcado": None,
             "01 texto_marcado": "1035",    # Fijo
             "02 fabricado_por": "Fabricado por: %s",
             "03 direccion1": None,
             "04 direccion2": None,
             "05 telefono": "Tfno: %s, %s",
             "06 año_certif": None,
             "07 blanco1": "",      # Separador
             "08 dni": None,
             # "09 iso1": "De EN13249:2001 a EN13257:2001",  # Fijo
             # "10 iso2": "EN13265:2001",     # Fijo
             # La norma ha cambiado. Ahora nos regimos por la del 2014
             "09 iso1": "De EN13249:2014 a EN13257:2014",  # Fijo
             "10 iso2": "EN13265:2014",     # Fijo
             "11 blanco2": "",      # Separador
             "12 producto": None,
             "13 descripcion":
                 "Geotextil no tejido de polipropileno 100% virgen",
             "14 uso": "Uso: %s",
             "15 blanco3": "",      # Separador
             "16 codigo": "Partida: %d Rollo: %s",
             "17 caracteristicas": "Gramaje: %d g/m² Ancho: %s m Largo: %d m"
            }
    if lang == "en":
        for k in _data:
            _data[k] = helene_laanest(_data[k])
    estilos = defaultdict(lambda: ("Helvetica", 9)) # Helvética a 9 por defecto
    estilos["02 fabricado_por"] = ("Helvetica-Bold", 11)
    estilos["12 producto"] = ("Helvetica-Bold", 17)
    estilos["16 codigo"] = ("Helvetica-Bold", 17)
    estilos["17 caracteristicas"] = ("Helvetica-Bold", 13)
    data = {}
    # Datos de la BD dependientes del rollo
    for rollo in rollos:
        # 0.- ¿En qué formato viene? Si es el antiguo (datos en diccionario)
        #     me quedo con el objeto de pclases en sí.
        if isinstance(rollo, dict):
            try:
                producto_venta = rollo['productoVenta']
            except KeyError:
                # Si no me lo mandan en el diccionario, tiene que traer
                # el objeto rollo. Los partes mandan producto en dicccionario
                # porque a veces se genera etiqueta antes de crear el objeto
                # en la BD. Si viene de la consulta del listado de rollos,
                # como el rollo ya existe, me viene en el objeto toda la info.
                producto_venta = rollo['objeto'].productoVenta
            numpartida = utils.parse_numero(rollo['partida'])
            numrollo = rollo['nrollo']
            barcode39 = rollo['codigo39']
        else:
            producto_venta = rollo.productoVenta
            numpartida = rollo.partida.numpartida
            numrollo = rollo.numrollo
            barcode39 = rollo.codigo
        #   1.- Empresa
        try:
            # Si hay distribuidor, este texto cambia.
            distribuidor = producto_venta.camposEspecificosRollo.cliente
            if distribuidor:
                if lang == "en":
                    data["02 fabricado_por"] = helene_laanest(
                            "%s") % (distribuidor.nombre)
                else:
                    data["02 fabricado_por"] = "%s" % (
                                                        distribuidor.nombre)
                dird = distribuidor.get_direccion_completa()
                dircompleta = textwrap.wrap(dird,
                        (len(dird) + max([len(w) for w in dird.split()])) / 2)
                data["03 direccion1"] = dircompleta[0]
                data["04 direccion2"] = dircompleta[1]
                data["05 telefono"] = _data["05 telefono"] % (
                        distribuidor.telefono, distribuidor.email)
            else:   # Sigo con los datos de "propia empresa". Distribuyo yo.
                empresa = pclases.DatosDeLaEmpresa.select()[0]
                data["02 fabricado_por"] = _data["02 fabricado_por"] % (
                                                                empresa.nombre)
                data["03 direccion1"] = empresa.direccion + ", " + empresa.cp
                data["04 direccion2"] = ", ".join((empresa.ciudad,
                                                   empresa.provincia,
                                                   empresa.pais))
                data["05 telefono"] = _data["05 telefono"] % (empresa.telefono,
                                                              empresa.email)
            # Para los clientes sin teléfono o sin email:
            data["05 telefono"] = data["05 telefono"].strip()
            if data["05 telefono"].startswith(","):
                data["05 telefono"] = data["05 telefono"][1:]
            if data["05 telefono"].endswith(","):
                data["05 telefono"] = data["05 telefono"][:-1]
            if len(data["05 telefono"]) <= 7:
                data["05 telefono"] = ""
        except IndexError:
            data["02 fabricado_por"] = ""
            data["03 direccion1"] = ""
            data["04 direccion2"] = ""
            data["05 telefono"] = ""
    #   2.- Producto
        producto = producto_venta
        if producto.annoCertificacion != None:
            data["06 año_certif"] = "%02d" % producto.annoCertificacion
        else:
            data["06 año_certif"] = ""
        data["08 dni"] = producto.dni
        if len(producto.nombre) <= 50:
            data["12 producto"] = producto.nombre
        else:
            #if "//" in producto.nombre: # Productos Intermas
            #    data["11 blanco2"], data["12 producto"] = producto.nombre.split("//")
            #else:
            data["11 blanco2"], data["12 producto"] = utils.dividir_cadena(
                    producto.nombre)
            data["11 blanco2"] = data["11 blanco2"].strip()
            data["12 producto"] = data["12 producto"].strip()
            estilos["11 blanco2"] = estilos["12 producto"]
        if producto.uso:
            if lang == "en":
                data["14 uso"] = _data["14 uso"] % helene_laanest(producto.uso)
            else:
                data["14 uso"] = _data["14 uso"] % producto.uso
        else:
            data["14 uso"] = ""
    #   3.- Rollo
        data["16 codigo"] = _data["16 codigo"] % (numpartida,
                                                  numrollo)
        data["17 caracteristicas"] = _data["17 caracteristicas"] % (
            producto.camposEspecificosRollo.gramos,
            float2str(producto.camposEspecificosRollo.ancho,
                      autodec=True, separador_decimales="."),
            producto.camposEspecificosRollo.metrosLineales)

        rectangulo(canvas, (margen, margen),
                      (ancho - margen, alto - margen))
        if mostrar_marcado:
            canvas.drawImage(logo_marcado,
                        marcado[0],
                        marcado[1],
                        width=logo[0], height=logo[1])
        else:
            data["01 texto_marcado"] = ""
        lineas = _data.keys()
        lineas.sort()
        # Posición y estilo de la primera línea.
        tamfuente = estilos[lineas[0]][1]
        crd_y = alto - logo[1] - 0.1 * cm - tamfuente
        # ¿Cuánto me desplazaré de línea a línea?
        offset_y = (crd_y - margen) / (len(lineas) + 3)   # 3 líneas para barcode
        for linea in lineas:
            try:
                dato = data[linea]
            except KeyError:    # Si no está en los valores asignados, busco
                                # en los originales. Deben ser datos fijos.
                dato = _data[linea]
            if dato is None:
                dato = ""
            canvas.setFont(*estilos[linea])
            #canvas.drawCentredString((ancho / 2),
            #                    crd_y,
            #                    escribe(dato))
            el_encogedor_de_fuentes_de_doraemon(canvas,
                                                fuente=estilos[linea][0],
                                                tamannoini=estilos[linea][1],
                                                xini=margen,
                                                xfin=ancho - margen,
                                                y=crd_y,
                                                texto=dato,
                                                alineacion=0)
            crd_y -= offset_y
        # Lo último: el código de barras:
        #######################################################################
        canvas.saveState()
        crd_y -= 2*offset_y
        crd_y -= 0.2*cm
        codigo_rollo = barcode39
        codigobarras = Extended39(codigo_rollo, xdim=.065*cm)
        codigobarras.drawOn(canvas, margen-0.5*cm, crd_y)
        xcode = ancho / 2.0
        ycode = 0.15*cm
        canvas.setFont("Courier-Bold", 9)
        try:
            canvas.drawCentredString(xcode, ycode, codigo_rollo, charSpace=0.25*cm)
        except TypeError:   # Versión antigua de ReportLab.
            canvas.drawCentredString(xcode, ycode, codigo_rollo)
        canvas.restoreState()
        # Y el QR de regalo
        # # De momento lo desactivo porque nuestras pistolas no lo reconocen.
        #try:
        #    from lib.pyqrcode import pyqrcode
        #    bidicode = pyqrcode.create(codigo_rollo)
        #    nomfichbidi = os.path.join(gettempdir(),
        #                               "bidi_%s.svg" % give_me_the_name_baby())
        #    bidicode.svg(nomfichbidi, scale=3)
        #    from lib.svglib.svglib import svglib
        #    drawing = svglib.svg2rlg(nomfichbidi)
        #    drawing.drawOn(canvas, margen - 0.25*cm, alto - margen - 3.0*cm + 0.25*cm)
        #except ImportError:
        #    pass    # No hay bidi porque no hay lxml instalado. Probablemente.
        #    print("No se generará código QR. Puede intentar lo siguiente:")
        #    print("C:\Python27\Scripts\easy_install.exe pip")
        #    print('pip install "D:\Informatica\Software\softwin python 2.7'
        #          '\lxml-3.7.2-cp27-cp27m-win32.whl"')
        #######################################################################
        canvas.showPage()
        # Y ahora la etiqueta adicional por si se pierde la otra y para cargar.
        create_etiqueta_backup(canvas, rollo)
        canvas.showPage()
    canvas.save()
    return nomarchivo
Ejemplo n.º 6
0
def crear_etiquetas_balas(balas, mostrar_marcado=True, lang="es"):
    """
    Construye una etiqueta por cada objeto bala recibido y las devuelve
    en un solo PDF.
    Si lang = "en", etiqueta en inglés. Si "es", en castellano.

    Crea etiquetas para las balas de
    un parte de la línea de fibra.
    Una por etiqueta del tamaño estándar de la impresora CAB: 12.55 x 8.4.
    Lleva el código especial para Domenech en horizontal.
    «seriep» es la serie del pedido y si no es None, se muestra en los
    3 primeros dígitos.
    «numped» es el número de pedido procedente de Domenech y si no es None se
    muestra en 6 dígitos tras la serie (si la hubiera).
    Estos dos grupos de dígitos opcionales («seriep» y «numped») son comunes
    a toda la serie de balas de las que se generarán las etiquetas.
    El formato completo es:
    * 3 dígitos: serie del pedido, completado con ceros por la izquierda.
    * 6 dígitos: número de pedido, completado con ceros por la izquierda.
    *-7-dígitos:-código-de-producto:--- YA NO (tercera vez que vuelven a ser 6)
    * 6 dígitos: código de producto:
         - 007336 FIBRA PP 6.7 Dtx NATURAL.
         - 007337 FIBRA PP 6.7 Dtx NEGRO.
         - 007674 FIBRA PP 4.5 Dtx NEGRO.
         - 007852 FIBRA PP 4.5 Dtx NATURAL.
    * 10 dígitos: número de lote, completado con ceros por la izquierda.
    * 15 dígitos: número de bala, completado con ceros por la izquierda.
    * 3 dígitos: parte entera del peso de la bala en kilogramos,
                 completado con ceros por la izquierda.
    * 2 dígitos: parte decimal del peso de la bala en kilogramos,
                 completado con ceros por la derecha.

    Por ejemplo, el código correspondiente a una bala de fibra negra de
    polipropileno de 6.7 dtex, correspondiente al lote 660, de número
    57394, con 286.50 kg de peso y solicitada en el pedido 4/2158; sería:
    004002158007337000000066000000000005739428650
    007337000000066000000000005739428650 Si no lleva serie ni pedido.
    """
    # TODO: De momento solo español. No hay inglés. Se ignora el parámetro.
    from reportlab.pdfgen import canvas
    from informes.geninformes import escribe, _build_codigo_domenech
    try:
        import Image
    except ImportError:
        from PIL import Image
    width = 12.55 * cm
    height = 8.4 * cm
    # Creo la hoja
    nomarchivo = os.path.join(gettempdir(),
                              "dh_etiqbala_%s.pdf"%give_me_the_name_baby())
    c = canvas.Canvas(nomarchivo, pagesize = (width, height))
    ancho, alto = width, height
    # arribaArriba significa linea de "arriba" de los cuadros de "Arriba"
    # El 0 vertical es el borde de abajo
    # El 0 horizontal es el margen derecho
    arriba = alto - 1.45*cm
    #arriba = alto - 5
    abajo = 5
    #abajo = 1.45*cm
    izq = width - 5
    der = 5     # ¿Va a resultar al final que también soy disléxico?
    xLogo = der + 0.5 * cm
    yLogo = arriba - 1.3 * cm
    xIzquierda = 20
    xDerecha = ancho/2 + 0.25*inch
    yPrimeraLinea = yLogo - 0.8*inch
    ySegundaLinea = yPrimeraLinea - 0.31*inch
    yTerceraLinea = ySegundaLinea - 0.31*inch
    yCuartaLinea = yTerceraLinea - 0.31*inch
    yQuintaLinea = yCuartaLinea - 0.31*inch
    xCodigo = xDerecha + 3.50 * cm
    yCodigo = arriba - 3.75 * cm
    for bala in balas:  # @UnusedVariable
        if not bala:    # Es None. Por lo que sea :o
            continue
        if isinstance(bala, pclases.Articulo):
            bala = _build_dict_etiqueta_articulo_bala(bala)
        rectangulo(c, (izq, arriba), (der, abajo))
        c.setFont("Helvetica-Bold", 28)
        c.drawString(xLogo, yLogo, "GEOTEXAN S.A.")
        c.setFont("Helvetica", 14)
        c.drawString(xIzquierda,
                     yPrimeraLinea,
                     escribe("CÓDIGO: " + bala['codigo']))
        from barcode import code39
        codigobarras = code39.Extended39(bala['codigo'], xdim = .020*inch)
        codigobarras.drawOn(c, xIzquierda - 0.5 * cm, yPrimeraLinea + 15)
        c.drawString(xIzquierda,
                     yQuintaLinea,
                     escribe("COLOR: %s" % (bala['color'])))
        c.drawString(xIzquierda,
                     ySegundaLinea,
                     escribe("LOTE: %s" % (bala['lote'])))
        c.drawString(xDerecha,
                     ySegundaLinea,
                     escribe("PESO KG: %s" % (bala['peso'])))
        c.drawString(xIzquierda,
                     yTerceraLinea,
                     escribe("TIPO: %s" % (bala['tipo'])))
        c.drawString(xDerecha,
                     yTerceraLinea,
                     escribe("LONGITUD: %s" % (bala['longitud'])))
        c.drawString(xIzquierda,
                     yCuartaLinea,
                     escribe("BALA Nº: %s" % (bala['nbala'])))
        c.drawString(xDerecha,
                     yCuartaLinea,
                     escribe("DTEX: %s" % (bala['dtex'])))
        c.drawString(xDerecha,
                     yQuintaLinea,
                     escribe("ACABADO: %s" % (bala['acabado'])))
        from barcode.EANBarCode import EanBarCode
        bar = EanBarCode()
        nombreficheroean13 = bar.getImage(bala['codigoBarra'])
        ean13rotado = Image.open(nombreficheroean13)
        ean13rotado = ean13rotado.rotate(90)
        ean13rotado.save(nombreficheroean13)
        c.drawImage(nombreficheroean13, xCodigo, yCodigo)
        # XXX: DOMENECH:
        from barcode import code128
        seriep = None   # Esto ya no se usa. Es la serie del pedido para el cliente
        numped = None   # Esto ya no se usa. Es el núm. del pedido para el cliente
        codigodomenech = _build_codigo_domenech(bala, seriep, numped)
        if codigodomenech:
            barcodedomenech = code128.Code128(codigodomenech,
                                              #xdim = 0.015 * inch,
                                              #height = 0.5 * cm)
                                              xdim = 0.0205 * inch,
                                              height = 0.95 * cm)
            #barcodedomenech = code39.Extended39(codigodomenech,
            #                                  #xdim = 0.015 * inch,
            #                                  #height = 0.5 * cm)
            #                                  xdim = 0.0094 * inch,
            #                                  height = 0.95 * cm)
            ydom = alto - 1.2 * cm
            #ydom = 0.4 * cm
            xdom = (width - barcodedomenech.width) / 2.0
            barcodedomenech.drawOn(c, xdom, ydom)
            c.saveState()
            c.setFont("Courier-Bold", 8)
            c.drawCentredString(xdom + (barcodedomenech.width / 2.0),
                                ydom - 0.20 * cm,
                                codigodomenech)
            c.restoreState()
        # XXX: EODOMENECH
        # XXX: Marca para identificar las nuevas.
        c.saveState()
        c.setFillColorRGB(0, 0, 0)
        c.circle(izq - 0.3*cm, yQuintaLinea, 0.1*cm, fill=1)
        c.restoreState()
        # XXX: EOMarca
        c.showPage()
    c.save()
    return nomarchivo
Ejemplo n.º 7
0
Archivo: cmr.py Proyecto: Virako/fpinn
def go(dde_nombre = "",
       dde_direccion1 = "",
       dde_direccion2 = "",
       cliente_nombre = "",
       cliente_direccion1 = "",
       cliente_direccion2 = "",
       entrega1 = "",
       entrega2 = "",
       transportista_nombre = "",
       transportista_direccion1 = "",
       transportista_direccion2 = "",
       observaciones = "",
       ldvs = [],
       estipulaciones = "",
       ciudad = "",
       mes = "",    # Día y mes o solo nombre del mes. Como se quiera.
       anno = "",   # OJO: Sólo los dos últimos dígitos del año.
       solo_texto = False, 
       porteador = "", 
       sucesivos = "", 
       ciudad_formalizado = ""):
    """
    A partir de los parámetros recibidos construye un PDF con el CMR.
    ldvs es una lista de bultos, embalaje y kgs.
    Si solo_texto es True, no se dibuja la plantilla del albarán, solo los
    datos.
    Devuelve en nombre del fichero generado.
    """
    # Inicialización y medidas:
    nomarchivo = os.path.join(gettempdir(), "cmr_%s.pdf" % (
                                        geninformes.give_me_the_name_baby()))
    c = canvas.Canvas(nomarchivo)
    tampag = A4
    c.setPageSize(tampag)
    tm, bm, lm, rm = 0.3*cm, 0.8*cm, 1*cm, 1*cm
    fuente, tamanno = "Helvetica", 8
    hlin = 0.7*cm
    MAXLINEAS = int(5.5*cm / hlin)
    paginas = int(len(ldvs)/ MAXLINEAS) + 1
        # Dato a imprimir, x1, x2 (o None si no va centrado) e y.
        # Si dato es una lista, se usará hlin para decrementar la y.
        # Si x1 y x2 son listas/tuplas, es porque el dato también se
        # divide en listas/tuplas (columnas) y se corresponden entre sí.
    medidas = {
     "dde_nombre":
        (dde_nombre,                   2*cm, None,      27.50*cm),
     "dde_direccion1":
        (dde_direccion1,               2*cm, None,      27   *cm),
     "dde_direccion2":
        (dde_direccion2,               2*cm, None,      26.5 *cm),
     "cliente_nombre":
        (cliente_nombre,               2*cm, None,      25   *cm),
     "cliente_direccion1":
        (cliente_direccion1,           2*cm, None,      24.50*cm),
     "cliente_direccion2":
        (cliente_direccion2,           2*cm, None,      24   *cm),
     "entrega1":
        (entrega1,                     2*cm, None,      22.25*cm),
     "entrega2":
        (entrega2,                     2*cm, None,      22.65*cm),
     "transportista1_nombre":
        (transportista_nombre,     11.35*cm, None,      25.00*cm),
     "transportista1_direccion1":
        (transportista_direccion1, 11.35*cm, None,      24.50*cm),
     "transportista1_direccion2":
        (transportista_direccion2, 11.35*cm, None,      24.00*cm),
     "transportista2_nombre":
        (transportista_nombre,      7.80*cm, 13.30*cm,   3.5 *cm),
     "transportista2_direccion1":
        (transportista_direccion1,  7.80*cm, 13.30*cm,   2.75*cm),
     "transportista2_direccion2":
        (transportista_direccion2,  7.80*cm, 13.30*cm,   2.00*cm),
     "observaciones":
        (observaciones,            11.10*cm, 19.40*cm,  20.8 *cm),
     "porteador":
        (porteador,                11.10*cm, 19.40*cm,  24.50*cm),
     "sucesivos":
        (sucesivos,                11.10*cm, 19.40*cm,  22.65*cm),
     "ldvs":
        (ldvs,                    ( 4.50*cm,
                                    7.30*cm,
                                   15.20*cm),( 7.00*cm,
                                              10.00*cm,
                                              17.45*cm), 17.25*cm),
     "estipulaciones":
        (estipulaciones,           11.10*cm, 19.40*cm,   10   *cm),
     "ciudad1":
        (ciudad_formalizado,        3.75*cm, None,        4.85 *cm),
     "mes1":
        (mes,                       7.8 *cm, None,        4.85 *cm),
     "anno1":
        (anno,                     10.0 *cm, None,        4.85 *cm),
     "ciudad2":
        (ciudad,                   14.50*cm, None,        3.10*cm),
     "mes2":
        (mes,                      17.75*cm, None,        3.10*cm),
     "anno2":
        (anno,                     19.2 *cm, None,        3.10*cm),
              }
    # Páginas del albarán
    for pag in range(1, paginas + 1):
        # Parte preimpresa:
        if not solo_texto:
            dibujar_imprenta(c, tampag)
        # Datos:
        c.setFont(fuente, tamanno)
        rellenar_datos(c, medidas, fuente, tamanno, hlin)
        rellenar_ldvs(c, ldvs[:MAXLINEAS], medidas, fuente, tamanno, hlin)
        ldvs = ldvs[MAXLINEAS:]
        c.showPage()
    c.save()
    return nomarchivo
Ejemplo n.º 8
0
def go(numalbaran = "XXXXXX", 
       fecha = "", 
       nombre_cliente = "", 
       direccion = "", 
       ciudad = "", 
       cif = "", 
       matricula = "", 
       ldvs = [], 
       total = 0.0, 
       solo_texto = False):
    """
    A partir de los parámetros recibidos construye un PDF con el albarán 
    completo.
    ldvs es una lista de cantidad (float), concepto, kgs (float), precio 
    (float) e importe (float).
    Si len(ldvs) > 12 genera (len(ldvs)/12) + 1 páginas, con el número 
    de página entre paréntesis tras el número de albarán.
    Si solo_texto es True, no se dibuja la plantulla del albarán, solo los 
    datos.
    Devuelve en nombre del fichero generado.
    """
    # Inicialización y medidas:
    nomarchivo = os.path.join(gettempdir(), "albaran_%s.pdf" % (
                                        geninformes.give_me_the_name_baby()))
    c = canvas.Canvas(nomarchivo)
    tampag = (19*cm, 14.8*cm)
    c.setPageSize(tampag)
    tm, bm, lm, rm = 1*cm, 1*cm, .7*cm, 1*cm
    fuente, tamanno = "Helvetica", 10
    hlin = 0.7*cm
    MAXLINEAS = 12
    paginas = int(len(ldvs) / MAXLINEAS) + 1
    medidas = {"Albarán": (9*cm, tampag[1] - 1.4*cm), 
               "N.º": (15.3*cm, tampag[1] - 1.3*cm),
               "Fecha": (14.3*cm, tampag[1] - 1.9*cm),
               "Cliente": (7.7*cm, tampag[1] - 2.5*cm),
               "Domicilio": (8*cm, tampag[1] - 3.1*cm),
               "Población": (2.7*cm, tampag[1] - 3.9*cm),
               "N.I.F.": (8.8*cm, tampag[1] - 3.9*cm),
               "Matrícula": (14.5*cm, tampag[1] - 3.9*cm),
              }
    xcantidad = 1.2*cm
    xconcepto = 3.4*cm
    xcateg = 9.4*cm
    xkgs = 11.25*cm
    xprecio = 13.05*cm
    ximporte = 15.7*cm
    y0 = tampag[1] - 4.2*cm
    yfinal = 1.75*cm
    y1 = yfinal + (MAXLINEAS * hlin)
    medidas_tabla = {"xcantidad": xcantidad, 
                     "xconcepto": xconcepto, 
                     "xcateg": xcateg, 
                     "xkgs": xkgs, 
                     "xprecio": xprecio, 
                     "ximporte": ximporte, 
                     "y0": y0, 
                     "yfinal": yfinal, 
                     "y1": y1, 
                     "ytotal": bm, 
                     "xfinal": tampag[0] - rm, 
                    } 
    # Páginas del albarán
    for pag in range(1, paginas + 1):
        # Parte preimpresa:
        if not solo_texto:
            dibujar_imprenta(c, hlin, tm, bm, lm, rm, tampag, medidas, 
                             fuente, tamanno, MAXLINEAS, medidas_tabla)
        # Datos:
        c.setFont(fuente, tamanno)
        if paginas > 1:
            numalb = numalbaran + "(%d)" % pag
            if pag == paginas:
                strtot = utils.float2str(total)
            else:
                strtot = ""
        else:
            numalb = numalbaran
            strtot = utils.float2str(total)
        rellenar_datos(c, numalb, fecha, nombre_cliente, direccion, ciudad, 
                       cif, matricula, medidas, fuente, tamanno)
        rellenar_ldvs(c, ldvs[:MAXLINEAS], strtot, medidas_tabla, hlin)
        ldvs = ldvs[MAXLINEAS:]
        c.showPage()
    c.save()
    return nomarchivo
Ejemplo n.º 9
0
def go_from_albaranSalida(albaranSalida):
    """
    Construye el PDF a partir de un objeto albaranSalida y no de sus datos 
    sueltos.
    """
    cliente = albaranSalida.cliente
    datos_cliente = {"código": cliente.id,
                     "cif": cliente.cif, 
                     "razón social": cliente.nombre, 
                     "dirección": cliente.direccion, 
                     "población": cliente.ciudad, 
                     "provincia": cliente.provincia}
    if cliente.cp and cliente.cp.strip():
        datos_cliente["población"] = (cliente.cp + " - " 
                                      + datos_cliente["población"])
    datos_albaran = {"fecha": utils.str_fecha(albaranSalida.fecha), 
                     "número": albaranSalida.numalbaran, 
                     "codcliente": albaranSalida.cliente 
                                    and `albaranSalida.cliente.id` 
                                    or ""}
    iva = cliente.iva
    lineas_contenido = [(ldv.producto.codigo, 
                         ldv.producto.descripcion, 
                         ldv.cantidad, 
                         ldv.precio * (1.0 - ldv.descuento) * (1 + iva), 
                         ldv.pedidoVenta and ldv.pedidoVenta.numpedido or "")
                        for ldv in albaranSalida.lineasDeVenta]
    totales = [albaranSalida.calcular_total(iva_incluido = False), 
               iva,
               albaranSalida.calcular_total(iva_incluido = True)]
    try:
        dde = pclases.DatosDeLaEmpresa.select()[0]
        datos_de_la_empresa = [os.path.join("..", "imagenes", dde.logo), 
                               dde.nombre +
                                (dde.cif and " (" + dde.str_cif_o_nif() +": " + dde.cif + ")" or ""), 
                               dde.direccion, 
                               "%s %s (%s), %s" % (dde.cp, 
                                                   dde.ciudad, 
                                                   dde.provincia, 
                                                   dde.pais), 
                               ]
        if dde.fax:
            if dde.fax.strip() == dde.telefono.strip():
                datos_de_la_empresa.append("Telf. y fax: %s" % dde.telefono)
            else:
                datos_de_la_empresa.append("Telf.: %s" % (dde.telefono))
                datos_de_la_empresa.append("Fax: %s" % (dde.fax))
        if dde.email:
            datos_de_la_empresa.append(dde.email)
    except IndexError:
        pass 
    nomarchivo = os.path.join(gettempdir(), 
                              "albaranSalida_%s.pdf" % give_me_the_name_baby())
    return go("Albaran de salida %s (%s)" % (
                albaranSalida.cliente.nombre, 
                utils.str_fecha(albaranSalida.fecha)), 
              nomarchivo, 
              datos_cliente, 
              datos_albaran, 
              lineas_contenido, 
              totales, 
              datos_de_la_empresa)
Ejemplo n.º 10
0
def etiqueta_rollos_polaco(rollos, mostrar_marcado = True):
    """
    Construye una etiqueta en polaco para Alians Trade.
    """
    # Dimensiones de la etiqueta en impresora térmica GEMINI.
    height = h = 12.55 * cm
    width = w = 8.4 * cm
    MARGEN = 0.05 * cm

    if DEBUG:
        print_debug(height = height, width = width)

    try:
        logo_marcado = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                        "..", "imagenes", "CE.png"))
    except IOError:     # Reportlab o PIL sin soporte libzip
        logo_marcado = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                        "..", "imagenes", "CE.gif"))
    logo_alians = os.path.abspath(os.path.join(os.path.dirname(__file__), 
                                    "..", "imagenes", "alians_trade.png"))
    WM = 1.0 * cm
    WA = 1.5 * cm
    im_width, im_height = Image.open(logo_marcado).size
    WH_MARCADO = (WM, im_height * (WM / im_width))
    im_width, im_height = Image.open(logo_alians).size
    WH_ALIANS = (WA, im_height * (WA / im_width))
    if DEBUG:
        print_debug(WH_MARCADO = WH_MARCADO, WH_ALIANS = WH_ALIANS)
    # Medidas relativas sobre papel.
    H_TEXTMARCADO = 0.2 * cm
    xy_logo = (1.5*mm, h - (WH_MARCADO[1] + H_TEXTMARCADO + WH_ALIANS[1]))
    xy_ce = ((w - WH_MARCADO[0]) / 2, h - WH_MARCADO[1] - 1.5*mm)
    xy_textmarcado = (w/2, xy_logo[1] + WH_ALIANS[1] - H_TEXTMARCADO)
    if DEBUG:
        print_debug(xy_ce = xy_ce, xy_textmarcado = xy_textmarcado, 
                    xy_logo = xy_logo)
    # Datos
    texto_marcado1 = "1488-CPD-0275/Z"
    texto_marcado2 = "12"
    X_HEADER = WH_ALIANS[0] + 0.2*cm
    data = [("PRODUCENT/PRODUCER:", {'x': X_HEADER, 
                                     'format': CENTER}), 
            ("ALIANS TRADE SP. Z O.O.", {'x': X_HEADER, 
                                         'format': BOLD + CENTER}), 
            ("ul. Wyzwolenia 367a, 43-300 Bielsko-Biała", 
                {'x': X_HEADER, 'format': CENTER}), 
            ("www.alians-trade.eu", {'x': X_HEADER, 'format': CENTER}), 
            ("ZAKŁAD PRODUKCYJNY/FACTORY CODE: 34-133", 
                {'x': X_HEADER, 'format': CENTER}), 
            ("NAZWA PRODUKTU/ PRODUCT NAME:", {'format': CENTER}), 
            #("Geowłóknina PINEMA® ST ", {'format': CENTER}), 
            ("$PRODUCTO", {'format': CENTER}), 
                # Geowłóknina PINEMA® ST + Texto variable {80, 100, 180, 250} 
            ("geowłóknina wyprodukowana ze 100% polipropylenu/", 
                {'format': CENTER}), 
            ("nonwoven geotextile composed of 100% polypropilene", 
                {'format': CENTER}), 
            "NORMY/ APPLICATION STANDARDS:", 
            ("EN 13249:2000, EN 13250:2000, EN 13251:2000, EN 13252:2000,", 
                {'format': BOLD}), 
            ("EN 13253:2000, EN 13254:2000, EN 13255:2000, EN 13256:2000,", 
                {'format': BOLD}), 
            ("EN 13257:2000, EN 13265:2000,",    # Negrita
                {'format': BOLD}), 
            # Las siguientes 5 líneas en fuente más pequeña. 
            ("EN 13249:2000/A1:2005, EN 13250:2000/A1:2005, EN 13251:2000/A1:2005,", 
                {'size': SIZE-1}), 
            ("EN 13252:2000/A1:2005, EN 13253:2000/A1:2005, EN 13254:2000/AC:2003,", 
                {'size': SIZE-1}), 
            ("EN 13254:2000/A1:2005, EN 13255:2000/AC:2003, EN 13255:2000/A1:2005,", 
                {'size': SIZE-1}), 
            ("EN 13256:2000/AC:2003,EN 13256:2000/A1:2005, EN 13257:2000/AC:2003,", 
                {'size': SIZE-1}), 
            # Esta última, además de pequeña, en negrita.
            ("EN 13257:2000/A1:2005, EN 13265:2000/AC:2003, EN 13265:2000/A1:2005", 
                {'format': BOLD, 'size': SIZE-1}), 
            "ZASTOSOWANIE/ APPLICATION: w drogownictwie, kolejnictwie, w robotach ", 
            "ziemnych i konstrukcjach oporowych, w systemach drenażowych, w ", 
            "zabezpieczeniach antyerozyjnych, w budowie zbiorników wodnych i zapór, ", 
            "w budowie kanałów, tuneli i konstrukcji podziemnych, w budowie ", 
            "składowisk odpadów stałych i zbiorników odpadów ciekłych.", 
            "PRZEZNACZENIE/ INTENDED FUNCTIONS: rozdzielenie, filtracja, ", 
            "drenaż, wzmocnienie.", 
            # De aquí para abajo, en dos columnas
            (("NR ROLKI/ ", "GRAMATURA/"), 
                {'size': SIZE - 2}), 
            (("ROLL NO.:", "$NUMROLLO", "NOMINAL MASS (g/m2):", "$GRAMAJE"), 
                {'format': ITALIC, 'size': SIZE - 2}),
            (("DŁUGOŚĆ/", "SZEROKOŚĆ/"), 
                {'size': SIZE - 2}), 
            (("LENGHT (m):", "$LARGO", "WIDTH (m):", "$ANCHO"), 
                {'format': ITALIC, 'size': SIZE - 2}), 
            (("WAGA BRUTTO/", "DATA PRODUKCJI/"), 
                {'size': SIZE - 2}), 
            (("GROSS WEIGHT (kg):", "$PESO", "DATE OF PRODUCTION:", "$FECHA"), 
                {'format': ITALIC, 'size': SIZE - 2})
           ]

    # 31 líneas. En principio distribuyo uniformemente:
    alto_linea = (xy_textmarcado[1] - 2*H_TEXTMARCADO) / (len(data) + 1)
    # (0,0) está abajo. Yo relleno la etiqueta de arriba a abajo.
    y_lines = [(xy_textmarcado[1] - 2*H_TEXTMARCADO) - (y * alto_linea) 
                for y in range(len(data) +1)[1:]]
    if DEBUG:
        print_debug(y_lines = y_lines)
        print_debug(alto_linea = alto_linea)

    # Creo la hoja
    nomarchivo = os.path.join(gettempdir(),
        "etiqAliansT_%s.pdf" % give_me_the_name_baby())
    c = canvas.Canvas(nomarchivo, pagesize = (width, height))
    
    # import code; code.interact(local = locals())

    for rollo in rollos:
        # Elementos gráficos: borde etiqueta y logos.
        rectangulo(c, (MARGEN, MARGEN),
                      (width - MARGEN, height - MARGEN))
        c.drawImage(logo_alians, xy_logo[0], xy_logo[1], 
                    WH_ALIANS[0], WH_ALIANS[1])
        if mostrar_marcado and not rollo['defectuoso']:
            c.drawImage(logo_marcado, 
                        xy_ce[0], xy_ce[1],  
                        width = WH_MARCADO[0], 
                        height = WH_MARCADO[1])
            c.setFont("Helvetica-Bold", SIZE)
            c.drawCentredString(xy_textmarcado[0], 
                                xy_textmarcado[1], 
                                escribe(texto_marcado1))
            c.drawCentredString(xy_textmarcado[0], 
                                xy_textmarcado[1] - H_TEXTMARCADO, 
                                escribe(texto_marcado2))
            c.setFont(FONT, SIZE)
        # Texto de la etiqueta
        c.setFont(FONT, SIZE)
        for i in range(len(data)):
            #c.drawString(0, y_lines[i], escribe(data[i]))
            #c.drawString(2*mm, y_lines[i], data[i])
            if isinstance(data[i], (list, tuple)):
                texto = data[i][0]
                opciones = data[i][1]
                if not isinstance(opciones, dict):
                    texto = (texto, opciones)
            else:
                texto = data[i]
                opciones = {}
            render(c, 2*mm, y_lines[i], texto, opciones = opciones, 
                   fuente = FONT, tamanno = SIZE, w = w, h = h, 
                   margen = MARGEN, rollo = rollo)
        c.showPage()
    c.save()
    return nomarchivo
Ejemplo n.º 11
0
 def imprimir(self, boton):
     # OJO: Como no hay catálogo de pruebas en la base de datos, las 
     # unidades, métodos y descripciones de las pruebas sobre geotextiles 
     # están HARCODED aquí.
     # PLAN: Meter todo esto en el tablas.sql, como debe de ser.
     data_prueba = {
         "Resistencia longitudinal": 
             {"descripción": "Resistencia a la tracción DM", 
              "método": "EN ISO 10319", 
              "unidad": "kN/m"}, 
         "Resistencia transversal":  
             {"descripción": "Resistencia a la tracción DT", 
              "método": "EN ISO 10319", 
              "unidad": "kN/m"}, 
         "Alargamiento longitudinal":  
             {"descripción": "Alargamiento DM", 
              "método": "EN ISO 10319", 
              "unidad": "%"}, 
         "Alargamiento transversal":  
             {"descripción": "Alargamiento DT", 
              "método": "EN ISO 10319", 
              "unidad": "%"}, 
         "Perforación":  
             {"descripción": 
                 "Resistencia a la perforación dinámica (Caída de cono)", 
              "método": "EN ISO 13433", 
              "unidad": "mm"}, 
         "Resistencia a la compresión":  
             {"descripción": 
                 "Resistencia al punzonado estático (CBR a perforación)", 
              "método": "EN ISO 12236", 
              "unidad": "kN"}, 
         "Apertura de poros":  
             {"descripción": "Medida de apertura (Porometría 090)", 
              "método": "EN ISO 12956", 
              "unidad": "mm"}, 
         "Punzonado piramidal":  
             {"descripción": "Resistencia al punzonado piramidal", 
              "método": "NF G38-019", 
              "unidad": "kN"}, 
         "Permeabilidad":  
             {"descripción": "Permeabilidad perpendicular al agua", 
              "método": "EN ISO 11058", 
              "unidad": "l/m²/s"}, 
         "Gramaje":  
             {"descripción": "Gramaje", 
              "método": "EN ISO 9864", 
              "unidad": "g/m²"}, 
         "Espesor": 
             {"descripción": "Espesor bajo 2 kPa", 
              "método": "EN ISO 9863-1", 
              "unidad": "mm"}
         }
     if not self.objeto:
         return
     #tv = self.wids['tv_datos']
     #from informes.treeview2pdf import treeview2pdf
     from formularios.reports import abrir_pdf
     #strfecha = "%s - %s" % (utils.str_fecha(mx.DateTime.localtime()), 
     #                        utils.str_hora(mx.DateTime.localtime()))
     #abrir_pdf(treeview2pdf(tv, 
     #    titulo = "Certificado de calidad de albarán %s" % (
     #        self.objeto.numalbaran),
     #    fecha = strfecha, 
     #    apaisado = False))
     from informes import informe_certificado_calidad
     from informes.geninformes import give_me_the_name_baby
     from time import sleep
     dic_productos = {}
     model = self.wids['tv_datos'].get_model()
     for fila in model:
         producto = pclases.getObjetoPUID(fila[-1])
         dic_productos[producto] = {}
         for hijo in fila.iterchildren():
             caracteristica = hijo[0]
             valor = hijo[-2]
             dic_productos[producto][caracteristica] = {
                 "descripción": data_prueba[caracteristica]["descripción"], 
                 "método": data_prueba[caracteristica]["método"], 
                 "unidad": data_prueba[caracteristica]["unidad"], 
                 "valor": valor}
     for producto in dic_productos:
         dic_valores = dic_productos[producto]
         if producto.es_rollo():
             orden = ("Resistencia longitudinal", 
                      "Resistencia transversal", 
                      "Alargamiento longitudinal", 
                      "Alargamiento transversal", 
                      "Perforación", 
                      "Resistencia a la compresión", 
                      "Apertura de poros", 
                      "Permeabilidad", 
                      "Gramaje", 
                      "Espesor", 
                      "Punzonado piramidal")
         nomfich = informe_certificado_calidad.go(
             "certcalidad_%s.pdf" % give_me_the_name_baby(), 
             producto, 
             dic_valores, 
             pclases.DatosDeLaEmpresa.select()[0], 
             self.objeto, 
             orden = orden)
         sleep(1)
         abrir_pdf(nomfich)
Ejemplo n.º 12
0
def etiqueta_rollos_norma13(rollos, mostrar_marcado = True, lang = "es"):
    """
    Construye una etiqueta por cada objeto rollo recibido y las devuelve 
    en un solo PDF.
    Si lang = "en", etiqueta en inglés. Si "es", en castellano.
    """
    # Voy a tratar de reescribir esto regla en mano a ver si consigo 
    # cuadrarlo bien en la etiquetadora GEMINI.
    alto = 12.55 * cm
    ancho = 8.4 * cm

    # Creo la hoja
    nomarchivo = os.path.join(gettempdir(),
        "etiq_norma13_%s_%s.pdf" % (lang, give_me_the_name_baby()))
    c = canvas.Canvas(nomarchivo, pagesize = (ancho, alto))
    
    # Medidas:
    logo = (3.8 * cm * 0.75, 2.8 * cm * 0.75)
    margen = 0.1 * cm
    marcado = (((ancho - logo[0]) / 2) - margen, (alto - margen - logo[1] - 2))
    
    # Imágenes:
    logo_marcado = os.path.abspath(os.path.join(os.path.dirname(__file__), 
                                   "..", "imagenes", "CE.png"))

    # Datos fijos:
    _data = {# "00 logo_marcado": None, 
             "01 texto_marcado": "1035",    # Fijo
             "02 fabricado_por": "Fabricado por: %s", 
             "03 direccion1": None, 
             "04 direccion2": None, 
             "05 telefono": "Tfno: %s, %s", 
             "06 año_certif": None, 
             "07 blanco1": "",      # Separador
             "08 dni": None, 
             #"09 iso1": "De EN13249:2001 a EN13257:2001",  # Fijo
             #"10 iso2": "EN13265:2001",     # Fijo
             # La norma ha cambiado. Ahora nos regimos por la del 2014
             "09 iso1": "De EN13249:2014 a EN13257:2014",  # Fijo
             "10 iso2": "EN13265:2014",     # Fijo
             "11 blanco2": "",      # Separador
             "12 producto": None, 
             "13 descripcion": 
                 "Geotextil no tejido de polipropileno 100% virgen", 
             "14 uso": "Uso: %s", 
             "15 blanco3": "",      # Separador 
             "16 codigo": "Partida: %d Rollo: %s", 
             "17 caracteristicas": "Gramaje: %d g/m² Ancho: %s m Largo: %d m" 
            }
    if lang == "en":
        for k in _data:
            _data[k] = helene_laanest(_data[k])
    estilos = defaultdict(lambda: ("Helvetica", 9)) # Helvética a 9 por defecto
    estilos["02 fabricado_por"] = ("Helvetica-Bold", 11)
    estilos["12 producto"] = ("Helvetica-Bold", 17)
    estilos["16 codigo"] = ("Helvetica-Bold", 17)
    estilos["17 caracteristicas"] = ("Helvetica-Bold", 13)
    data = {}
    # Datos de la BD dependientes del rollo
    for rollo in rollos:
        # 0.- ¿En qué formato viene? Si es el antiguo (datos en diccionario) 
        #     me quedo con el objeto de pclases en sí.
        if isinstance(rollo, dict):
            try:
                productoVenta = rollo['productoVenta']
            except KeyError:
                # Si no me lo mandan en el diccionario, tiene que traer 
                # el objeto rollo. Los partes mandan producto en dicccionario 
                # porque a veces se genera etiqueta antes de crear el objeto 
                # en la BD. Si viene de la consulta del listado de rollos, 
                # como el rollo ya existe, me viene en el objeto toda la info.
                productoVenta = rollo['objeto'].productoVenta
            numpartida = utils.parse_numero(rollo['partida'])
            numrollo = rollo['nrollo']
        else:
            productoVenta = rollo.productoVenta
            numpartida = rollo.partida.numpartida
            numrollo = rollo.numrollo
        #   1.- Empresa
        try:
            # Si hay distribuidor, este texto cambia.
            distribuidor = productoVenta.camposEspecificosRollo.cliente
            if distribuidor:
                if lang == "en":
                    data["02 fabricado_por"] = helene_laanest(
                            "Distribuido por: %s") % (distribuidor.nombre)
                else:
                    data["02 fabricado_por"] = "Distribuido por: %s" % (
                                                        distribuidor.nombre)
                d = distribuidor.get_direccion_completa()
                dircompleta = textwrap.wrap(d, 
                        (len(d) + max([len(w) for w in d.split()])) / 2)
                data["03 direccion1"] = dircompleta[0]
                data["04 direccion2"] = dircompleta[1]
                data["05 telefono"] = _data["05 telefono"] % (
                        distribuidor.telefono, distribuidor.email)
            else:   # Sigo con los datos de "propia empresa". Distribuyo yo.
                empresa = pclases.DatosDeLaEmpresa.select()[0]
                data["02 fabricado_por"] = _data["02 fabricado_por"] % (
                                                                empresa.nombre)
                data["03 direccion1"] = empresa.direccion + ", " + empresa.cp
                data["04 direccion2"] = ", ".join((empresa.ciudad, 
                                                   empresa.provincia, 
                                                   empresa.pais))
                data["05 telefono"] = _data["05 telefono"] % (empresa.telefono,
                                                              empresa.email)
            # Para los clientes sin teléfono o sin email:
            data["05 telefono"] = data["05 telefono"].strip()
            if data["05 telefono"].startswith(","):
                data["05 telefono"] = data["05 telefono"][1:]
            if data["05 telefono"].endswith(","):
                data["05 telefono"] = data["05 telefono"][:-1]
            if len(data["05 telefono"]) <= 7: 
                data["05 telefono"] = ""
        except IndexError:
            data["02 fabricado_por"] = ""
            data["03 direccion1"] = ""
            data["04 direccion2"] = ""
            data["05 telefono"] = ""
    #   2.- Producto
        producto = productoVenta
        if producto.annoCertificacion != None:
            data["06 año_certif"] = "%02d" % producto.annoCertificacion
        else:
            data["06 año_certif"] = ""
        data["08 dni"] = producto.dni
        if len(producto.nombre) <= 50:
            data["12 producto"] = producto.nombre
        else:
            #if "//" in producto.nombre: # Productos Intermas
            #    data["11 blanco2"], data["12 producto"] = producto.nombre.split("//")
            #else:
            data["11 blanco2"], data["12 producto"] = utils.dividir_cadena(
                    producto.nombre)
            data["11 blanco2"] = data["11 blanco2"].strip()
            data["12 producto"] =data["12 producto"].strip()
            estilos["11 blanco2"] = estilos["12 producto"]
        if producto.uso:
            if lang == "en":
                data["14 uso"] = _data["14 uso"] % helene_laanest(producto.uso)
            else:
                data["14 uso"] = _data["14 uso"] % producto.uso
        else:
            data["14 uso"] = ""
    #   3.- Rollo
        data["16 codigo"] = _data["16 codigo"] % (numpartida, 
                                                  numrollo)
        data["17 caracteristicas"] = _data["17 caracteristicas"] % (
            producto.camposEspecificosRollo.gramos, 
            float2str(producto.camposEspecificosRollo.ancho, 
                      autodec = True, separador_decimales = "."), 
            producto.camposEspecificosRollo.metrosLineales)

        rectangulo(c, (margen, margen),
                      (ancho - margen, alto - margen))
        if mostrar_marcado: 
            c.drawImage(logo_marcado, 
                        marcado[0], 
                        marcado[1],
                        width = logo[0], height = logo[1])
        else:
            data["01 texto_marcado"] = ""
        lineas = _data.keys()
        lineas.sort()
        # Posición y estilo de la primera línea.
        tamfuente = estilos[lineas[0]][1]
        y = alto - logo[1] - 0.1 * cm - tamfuente
        # ¿Cuánto me desplazaré de línea a línea?
        offset_y = (y - margen) / len(lineas)
        for linea in lineas:
            try:
                dato = data[linea]
            except KeyError:    # Si no está en los valores asignados, busco  
                                # en los originales. Deben ser datos fijos.
                dato = _data[linea]
            if dato is None:
                dato = ""
            c.setFont(*estilos[linea])
            #c.drawCentredString((ancho / 2), 
            #                    y, 
            #                    escribe(dato))
            el_encogedor_de_fuentes_de_doraemon(c, 
                                                fuente = estilos[linea][0], 
                                                tamannoini = estilos[linea][1],
                                                xini = margen, 
                                                xfin = ancho - margen, 
                                                y = y, 
                                                texto = dato, 
                                                alineacion = 0)
            y -= offset_y
        c.showPage()
    c.save()
    return nomarchivo
Ejemplo n.º 13
0
def go_from_presupuesto(presupuesto):
    """
    Construye el PDF a partir de un objeto presupuesto y no de sus datos 
    sueltos.
    """
    try:
        dde = pclases.DatosDeLaEmpresa.select()[0]
        lineas_empresa = [dde.nombre, 
                          dde.direccion, 
                          "%s %s (%s), %s" % (dde.cp, 
                                              dde.ciudad, 
                                              dde.provincia, 
                                              dde.pais), 
                          "Telf.: %s" % (dde.telefono)]
        if dde.fax:
            lineas_empresa.append("Fax: %s" % (dde.fax))
        if dde.email:
            lineas_empresa.append(dde.email)
    except IndexError:
        lineas_empresa = []
    lineas_contenido = presupuesto.lineasDePedido + presupuesto.servicios
    datos_cliente = []
    if presupuesto.personaContacto != "":
        datos_cliente.append("A la atención de %s" % (presupuesto.personaContacto))
    datos_cliente.append(presupuesto.nombrecliente)
    datos_cliente.append(presupuesto.direccion)
    listadireccion = [presupuesto.cp, presupuesto.ciudad]
    if presupuesto.ciudad.strip() != presupuesto.provincia.strip():
        listadireccion.append(presupuesto.provincia)
    listadireccion.append(presupuesto.pais)
    segunda_linea_direccion = " ".join([token.strip() 
                                        for token in listadireccion 
                                        if token.strip() != ""])
    datos_cliente.append(segunda_linea_direccion)
    if presupuesto.telefono.strip() != "":
        datos_cliente.append("Tlf.: %s" % (presupuesto.telefono))
    if presupuesto.fax.strip() != "":
        datos_cliente.append("Fax.: %s" % (presupuesto.fax))
    fecha_entradilla = utils.str_fecha(presupuesto.fecha)
    try:
        dde = pclases.DatosDeLaEmpresa.select()[0]
        iva = dde.iva
    except IndexError:
        iva = 0.21
    totales = {"orden": ["Base imponible", 
                         "IVA %d%%" % (iva * 100), 
                         "TOTAL"], 
               "Base imponible":
                    utils.float2str(presupuesto.calcular_base_imponible()), 
               "IVA %d%%" % (iva * 100): 
                    utils.float2str(presupuesto.calcular_total_iva()), 
               "TOTAL": 
                    utils.float2str(presupuesto.calcular_importe_total())
               }
    if presupuesto.descuento:
        fila_descuento = "Descuento %s %%" % (
            utils.float2str(presupuesto.descuento*100, autodec = True))
        totales['orden'].insert(0, fila_descuento) 
        totales[fila_descuento] = utils.float2str(
            presupuesto.calcular_subtotal(incluir_descuento = False) 
            * presupuesto.descuento * -1)
        fila_subtotal = "Subtotal"
        totales['orden'].insert(0, fila_subtotal) 
        totales[fila_subtotal] = utils.float2str(
            presupuesto.calcular_subtotal(incluir_descuento = False))
    total_irpf = presupuesto.calcular_total_irpf()
    if total_irpf != 0:
        try:
            dde = pclases.DatosDeLaEmpresa.select()[0]
            irpf = dde.irpf
        except IndexError:
            irpf = None
        texto_irpf = "IRPF"
        if irpf:
            texto_irpf += " (%d%%)" % (irpf*100)
        totales[texto_irpf] = utils.float2str(total_irpf)
        totales["orden"].insert(-2, texto_irpf)
    try:
        dde = pclases.DatosDeLaEmpresa.select()[0]
        logo = dde.get_ruta_completa_logo()
    except IndexError:
        logo = None
    if presupuesto.validez:
        validez = presupuesto.validez
    else:
        validez = None

    nomarchivo = os.path.join(gettempdir(), 
                              "presupuesto_%s.pdf" % give_me_the_name_baby())
    go("Presupuesto %s (%s)" % (presupuesto.cliente.nombre, 
                                utils.str_fecha(presupuesto.fecha)), 
       nomarchivo, 
       lineas_empresa, 
       datos_cliente, 
       lineas_contenido, 
       fecha_entradilla, 
       totales, 
       presupuesto.texto, 
       presupuesto.despedida, 
       ruta_logo = logo, 
       validez = validez, 
       numpresupuesto = presupuesto.numpresupuesto)
    return nomarchivo
Ejemplo n.º 14
0
def go_from_albaranSalida(albaranSalida, 
                          kilos = None, 
                          imprimir_recogida = True):
    """
    Construye el PDF a partir de un objeto albaranSalida y no de sus datos 
    sueltos.
    «kilos» es un texto que se imprimirá en el cuadro correspondiente. Si es 
    none intenta calcularlo.
    «imprimir_recogida» es un booleano. Si es False no genera la última página.
    """
    cliente = albaranSalida.cliente
    datos_cliente = {"código": cliente.id,
                     "cif": cliente.cif, 
                     "razón social": cliente.nombre, 
                     "dirección": cliente.direccion, 
                     "población": cliente.ciudad, 
                     "provincia": cliente.provincia}
    if cliente.cp and cliente.cp.strip():
        datos_cliente["población"] = (cliente.cp + " - " 
                                      + datos_cliente["población"])
    if kilos is None:
        try:
            kilos = utils.float2str(
                        sum([ldv.producto.calcular_kilos() * ldv.cantidad  
                             for ldv in albaranSalida.lineasDeVenta]))
        except (TypeError, ValueError):
            kilos = ""
    datos_albaran = {"fecha": utils.str_fecha(albaranSalida.fecha), 
                     "número": albaranSalida.numalbaran, 
                     "kilos": kilos, 
                     "bultos": utils.float2str(
                                sum([ldv.cantidad for ldv 
                                    in albaranSalida.lineasDeVenta]), 
                                autodec = True)}
    iva = cliente.iva
    lineas_contenido = [(ldv.producto.codigo, 
                         ldv.producto.descripcion, 
                         ldv.cantidad, 
                         #ldv.precio * (1.0 - ldv.descuento) * (1 + iva), 
                         # CWT: Ahora prefiere los precios sin IVA.
                         ldv.precio * (1.0 - ldv.descuento), 
                         ldv.pedidoVenta and ldv.pedidoVenta.numpedido or "")
                        for ldv in albaranSalida.lineasDeVenta]
    totales = [albaranSalida.calcular_total(iva_incluido = False), 
               iva,
               albaranSalida.calcular_total(iva_incluido = True)]
    try:
        dde = pclases.DatosDeLaEmpresa.select()[0]
        datos_de_la_empresa = [os.path.join("..", "imagenes", dde.logo), 
                               dde.nombre +
                                (dde.cif and " (" + dde.str_cif_o_nif() +": " + dde.cif + ")" or ""), 
                               dde.direccion, 
                               "%s %s (%s), %s" % (dde.cp, 
                                                   dde.ciudad, 
                                                   dde.provincia, 
                                                   dde.pais), 
                               ]
        if dde.fax:
            if dde.fax.strip() == dde.telefono.strip():
                datos_de_la_empresa.append("Telf. y fax: %s" % dde.telefono)
            else:
                datos_de_la_empresa.append("Telf.: %s" % (dde.telefono))
                datos_de_la_empresa.append("Fax: %s" % (dde.fax))
        if dde.email:
            datos_de_la_empresa.append(dde.email)
        titular = dde.nombreContacto
    except IndexError:
        datos_de_la_empresa = [None]
        titular = ""
    nomarchivo = os.path.join(gettempdir(), 
                              "albaranSalida_%s.pdf" % give_me_the_name_baby())
    return go("Albaran de salida - Carta de portes %s (%s)" % (
                albaranSalida.cliente.nombre, 
                utils.str_fecha(albaranSalida.fecha)), 
              nomarchivo, 
              datos_cliente, 
              datos_albaran, 
              lineas_contenido, 
              totales, 
              datos_de_la_empresa, 
              titular, 
              imprimir_recogida)
Ejemplo n.º 15
0
def crear_etiquetas_bigbags(bigbags, mostrar_marcado=True, lang="es"):
    """
    Construye una etiqueta por cada objeto bigbag recibido y las devuelve
    en un solo PDF.
    Si lang = "en", etiqueta en inglés. Si "es", en castellano.
    """
    # Voy a tratar de reescribir esto regla en mano a ver si consigo
    # cuadrarlo bien en la etiquetadora GEMINI.
    alto = 12.55 * cm
    ancho = 8.4 * cm

    # Creo la hoja
    nomarchivo = os.path.join(
        gettempdir(), "etiq_bigbag13_%s_%s.pdf" % (lang, give_me_the_name_baby()))
    canvas = reportlabcanvas.Canvas(nomarchivo, pagesize=(ancho, alto))

    # Medidas:
    logo = (3.8 * cm * 0.75, 2.8 * cm * 0.75)
    margen = 0.1 * cm
    marcado = (((ancho - logo[0]) / 2) - margen, (alto - margen - logo[1] - 2))

    # Imágenes:
    logo_marcado = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "imagenes", "CE.png"))

    # Datos fijos:
    # pylint: disable=bad-continuation
    _data = {# "00 logo_marcado": None,
             "01 texto_marcado": "1035",    # Fijo
             "02 fabricado_por": "Fabricado por: %s",
             "03 direccion1": None,
             "04 direccion2": None,
             "05 telefono": "Tfno: %s, %s",
             "06 año_certif": None,
             "07 blanco1": "",      # Separador
             "08 dni": None,
             "09 iso1": "EN 14889-2:2008",  # Fijo
             "11 blanco2": "",      # Separador
             "12 producto": None,
             "13 descripcion": "",
             "14 uso": None,
             "15 blanco3": "",      # Separador
             # "16 1 separador": "",     # Fijo
             "16 codigo": "Lote {} · Bigbag {}",  # Código bigbag y código lote.
             "17 caracteristicas": "Corte: {} mm · Peso: {} kg/br"  # Corte y peso.
            }
    if lang == "en":
        for k in _data:
            _data[k] = helene_laanest(_data[k])
    estilos = defaultdict(lambda: ("Helvetica-Bold", 11)) # Helvética a 11 por defecto
    estilos["01 texto_marcado"] = ("Times-Bold", 9)
    estilos["02 fabricado_por"] = ("Helvetica-Bold", 13)
    estilos["12 producto"] = ("Courier-Bold", 17)
    estilos["14 uso"] = ("Helvetica-Bold", 10)
    estilos["15 blanco3"] = ("Helvetica-Bold", 10)
    estilos["16 codigo"] = ("Courier-Bold", 13)
    estilos["17 caracteristicas"] = ("Helvetica-Bold", 14)
    data = {}
    # Datos de la BD dependientes del bigbag
    for bigbag in bigbags:
        # 0.- ¿En qué formato viene? Si es el antiguo (datos en diccionario)
        #     me quedo con el objeto de pclases en sí.
        producto_venta = bigbag.articulo.productoVenta
        numpartida = bigbag.articulo.loteCem.codigo
        numbigbag = bigbag.codigo
        #   1.- Empresa
        try:
            # Si hay distribuidor, este texto cambia.
            distribuidor = bigbag.articulo.productoVenta.camposEspecificosBala.cliente
            if distribuidor:
                if lang == "en":
                    data["02 fabricado_por"] = helene_laanest(
                            "%s") % (distribuidor.nombre)
                else:
                    data["02 fabricado_por"] = "%s" % (
                                                        distribuidor.nombre)
                dird = distribuidor.get_direccion_completa()
                dircompleta = textwrap.wrap(dird,
                        (len(dird) + max([len(w) for w in dird.split()])) / 2)
                data["03 direccion1"] = dircompleta[0]
                data["04 direccion2"] = dircompleta[1]
                data["05 telefono"] = _data["05 telefono"] % (
                        distribuidor.telefono, distribuidor.email)
            else:   # Sigo con los datos de "propia empresa". Distribuyo yo.
                empresa = pclases.DatosDeLaEmpresa.select()[0]
                data["02 fabricado_por"] = _data["02 fabricado_por"] % (
                                                                empresa.nombre)
                data["03 direccion1"] = empresa.direccion + ", " + empresa.cp
                data["04 direccion2"] = ", ".join((empresa.ciudad,
                                                   empresa.provincia,
                                                   empresa.pais))
                data["05 telefono"] = _data["05 telefono"] % (empresa.telefono,
                                                              empresa.email)
            # Para los clientes sin teléfono o sin email:
            data["05 telefono"] = data["05 telefono"].strip()
            if data["05 telefono"].startswith(","):
                data["05 telefono"] = data["05 telefono"][1:]
            if data["05 telefono"].endswith(","):
                data["05 telefono"] = data["05 telefono"][:-1]
            if len(data["05 telefono"]) <= 7:
                data["05 telefono"] = ""
        except IndexError:
            data["02 fabricado_por"] = ""
            data["03 direccion1"] = ""
            data["04 direccion2"] = ""
            data["05 telefono"] = ""
    #   2.- Producto
        producto = producto_venta
        if producto.annoCertificacion != None:
            data["06 año_certif"] = "%02d" % producto.annoCertificacion
        else:
            data["06 año_certif"] = ""
        data["08 dni"] = producto.dni
        data["12 producto"] = producto.nombre
        if producto.uso:
            if lang == "en":
                produso = helene_laanest(producto.uso)
            else:
                produso = producto.uso
            if len(produso) > 30:   # Wrap si el texto es largo.
                produso = textwrap.wrap(produso,
                    (len(produso) + max([len(w) for w in produso.split()])) / 2)
                data["14 uso"] = produso[0]
                data["15 blanco3"] = produso[1]     # Era un separador, pero
                                                    # necesito el espacio.
            else:
                data["14 uso"] = produso
        else:
            data["14 uso"] = ""
    #   3.- Bigbag
        data["16 codigo"] = _data["16 codigo"].format(numpartida,
                                                      numbigbag)
        corte = producto.camposEspecificosBala.corte
        peso = float2str(bigbag.articulo.peso_bruto)
        corte_peso = _data["17 caracteristicas"].format(corte, peso)
        data["17 caracteristicas"] = corte_peso

        rectangulo(canvas, (margen, margen),
                      (ancho - margen, alto - margen))
        if mostrar_marcado:
            canvas.drawImage(logo_marcado,
                        marcado[0],
                        marcado[1],
                        width=logo[0], height=logo[1])
        else:
            data["01 texto_marcado"] = ""
        lineas = _data.keys()
        lineas.sort()
        # Posición y estilo de la primera línea.
        tamfuente = estilos[lineas[0]][1]
        crd_y = alto - logo[1] - 0.1 * cm - tamfuente
        # ¿Cuánto me desplazaré de línea a línea?
        offset_y = (crd_y - margen) / len(lineas)
        for linea in lineas:
            try:
                dato = data[linea]
            except KeyError:    # Si no está en los valores asignados, busco
                                # en los originales. Deben ser datos fijos.
                dato = _data[linea]
            if dato is None:
                dato = ""
            canvas.setFont(*estilos[linea])
            #canvas.drawCentredString((ancho / 2),
            #                    crd_y,
            #                    escribe(dato))
            el_encogedor_de_fuentes_de_doraemon(canvas,
                                                fuente=estilos[linea][0],
                                                tamannoini=estilos[linea][1],
                                                xini=margen,
                                                xfin=ancho - margen,
                                                y=crd_y,
                                                texto=dato,
                                                alineacion=0)
            crd_y -= offset_y
        canvas.showPage()
    canvas.save()
    return nomarchivo
Ejemplo n.º 16
0
def go(titulo, 
       ruta_archivo, 
       lineas_datos_empresa, 
       datos_cliente, 
       lineas_contenido, 
       fecha_entradilla, 
       totales = {}, 
       texto = None, 
       despedida = None, 
       ruta_logo = None, 
       validez = None, 
       condicionado = None, 
       texto_riesgo = None, 
       numpresupuesto = "", 
       incluir_condicionado_general = True, 
       forma_de_pago = None, 
       dir_fiscal = None, 
       firma_comercial = None, 
       para_estudio = False,
       idioma = "es"):
    """
    Recibe el título del documento y la ruta completa del archivo.
    Si validez != None escribe una frase con la validez del presupuesto.
    """
    if idioma not in ("en", "es"):
        raise NotImplementedError,\
                __file__ + ": Idioma '%s' no implementado." % idioma
    doc = SimpleDocTemplate(ruta_archivo, title = titulo)
    encabezado = build_encabezado(lineas_datos_empresa)
    try:
        nombrecliente = datos_cliente[0].replace(" ", "_")
    except:
        nombrecliente = ""
    datos_cliente = build_datos_cliente(datos_cliente)
    entradilla = build_entradilla(fecha_entradilla, numpresupuesto, 
                                  para_estudio, 
                                  lang = idioma)
    texto = build_texto(texto)
    contenido = build_tabla_contenido(lineas_contenido, lang = idioma)
    totales = build_tabla_totales(totales)
    despedida = build_texto(despedida)
    forma_pago = build_texto(forma_de_pago)
    comercial = build_texto(firma_comercial)
    story = [encabezado, 
             datos_cliente, 
             entradilla, 
             Spacer(1, 0.2 * cm), 
             contenido, 
             Spacer(1, 0.25 * cm), 
             totales, 
             Spacer(1, 1 * cm),
             forma_pago, 
             Spacer(1, 2 * cm), 
             texto, 
             Spacer(1, 0.2 * cm), 
             despedida, 
             Spacer(1, 0.5 * cm), 
             comercial]
    #if validez:
        #story.insert(9, build_validez(validez))
    if texto_riesgo:
        story.insert(-8, build_texto_riesgo(texto_riesgo))
    #if condicionado: # El condicionado es el texto en sí.
    #    story.insert(-2, Spacer(1, 2 * cm))
    #    story.insert(-2, build_condicionado(condicionado))
    story = utils.aplanar([i for i in story if i])
    _dibujar_logo = lambda c, d: dibujar_logo(c, d, ruta_logo, idioma)
    _dibujar_dir_fiscal = lambda c, d: dibujar_dir_fiscal(c, d, dir_fiscal)
    def dibujar_logo_y_dir_fiscal(c, d):
        _dibujar_logo(c, d)
        _dibujar_dir_fiscal(c, d)
    doc.build(story, onFirstPage = dibujar_logo_y_dir_fiscal, 
                     onLaterPages = _dibujar_dir_fiscal)
    # Agrego condiciones generales:
    if incluir_condicionado_general:
        from lib.PyPDF2 import PyPDF2
        pdf_presupuesto = open(ruta_archivo, "rb")
        if idioma == "en":
            fcond = "condiciones_generales_en.pdf"
        else:
            fcond = "condiciones_generales.pdf"
        pdf_condiciones = open(
            os.path.join(os.path.dirname(os.path.abspath(__file__)), 
                         fcond), 
            "rb")
        merger = PyPDF2.PdfFileMerger()
        merger.append(pdf_presupuesto)
        merger.append(pdf_condiciones)
        combinado = os.path.join(gettempdir(),
                    "oferta_%d_%s_%s.pdf" % (numpresupuesto, 
                        sanitize(nombrecliente, strict = True), 
                        give_me_the_name_baby()))
        merger.write(open(combinado, "wb"))
        ruta_archivo = combinado
    return ruta_archivo
Ejemplo n.º 17
0
def etiqueta_rollos_portrait(rollos, mostrar_marcado = True):
    """
    Construye una etiqueta 
    """
    # Voy a tratar de reescribir esto regla en mano a ver si consigo 
    # cuadrarlo bien en la etiquetadora GEMINI.
    height = 12.55 * cm
    width = 8.4 * cm

    # Escala
    ancho = 7.2  # @UnusedVariable
    alto = 11.3
    scale = height / alto 
    
    # Medidas en papel.
    brand = (0.4 * scale, (alto - 2.0) * scale)
    logo = (3.8 * scale, (alto - 2.8) * scale)
    marcado = ((7.2/2) * scale, (alto - 3.0) * scale)
    column1 = .35 * scale
    column2 = logo[0]
    lineas = map(lambda x: (alto - x) * scale, 
                 [3.4 + (i*.6) for i in range(13)])
    
    # Datos
    data = {'brand': "EkoTex", 
            "c100": "UK Distributor", 
            "c108": "Product Name", 
            "c109": "Roll Number", 
            "c110": "Product Dimensions", 
            "c111": "Polymer", 
            "c112": "Product Classification", 
            "c200": "Geosynthetics Limited", 
            "c201": "Fleming Road", 
            "c202": "Harrowbrook Ind Est", 
            "c203": "Hinckley", 
            "c204": "Leicestershire", 
            "c205": "LE10 3 DU", 
            "c206": "Tel 01455 617139", 
            "c207": "Fax 01455 617140", 
            "c211": "Polypropylene", 
            "c212": "GTX-N", 
            "marcado": "0799-CPD", # Hay que incluirle el logotipo CE delante.
            }
    data["logo"] = os.path.abspath(os.path.join(os.path.dirname(__file__), 
                                   "..", "imagenes", "logo_ekotex.png")) 
                                                # Ruta absoluta 
                                                # a la imagen del logotipo. 
    try:
        logo_marcado = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                       "..", "imagenes", "CE.png"))
    except IOError:     # Reportlab o PIL sin soporte libzip
        logo_marcado = os.path.abspath(os.path.join(os.path.dirname(__file__),
                                       "..", "imagenes", "CE.gif"))
    # Creo la hoja
    nomarchivo = os.path.join(gettempdir(),
        "etiqEkotex_%s.pdf" % give_me_the_name_baby())
    c = canvas.Canvas(nomarchivo, pagesize = (width, height))

    for rollo in rollos:
        try:
            data["c208"] = rollo['objeto'].productoVenta.nombre
            data["c209"] = rollo['objeto'].numrollo
            cer = rollo['objeto'].productoVenta.camposEspecificosRollo
        except AttributeError:  # No se ha creado el objeto todavía. Es None.
            data["c208"] = rollo['productoVenta'].nombre
            data["c209"] = rollo['nrollo']
            cer = rollo['productoVenta'].camposEspecificosRollo
        data["c210"] = "%sm x %dm" % (float2str(cer.ancho, 
                                                autodec = True, 
                                                separador_decimales = "."),
                                      cer.metrosLineales) 
        rectangulo(c, (0.3 * cm, 0.3 * cm),
                      (width - 0.3 * cm, height - 0.3 * cm))
        c.setFont("Helvetica-Bold", 16)
        c.drawString(brand[0], brand[1], escribe(data['brand']))
        c.setFont("Helvetica-Bold", 10)
        c.drawString(column1, lineas[0], escribe(data['c100']))
        c.drawString(column1, lineas[8], escribe(data['c108']))
        c.drawString(column1, lineas[9], escribe(data['c109']))
        c.drawString(column1, lineas[10], escribe(data['c110']))
        c.drawString(column1, lineas[11], escribe(data['c111']))
        c.drawString(column1, lineas[12], escribe(data['c112']))
        c.drawString(column2, lineas[0], escribe(data['c200']))
        c.drawString(column2, lineas[1], escribe(data['c201']))
        c.drawString(column2, lineas[2], escribe(data['c202']))
        c.drawString(column2, lineas[3], escribe(data['c203']))
        c.drawString(column2, lineas[4], escribe(data['c204']))
        c.drawString(column2, lineas[5], escribe(data['c205']))
        c.drawString(column2, lineas[6], escribe(data['c206']))
        c.drawString(column2, lineas[7], escribe(data['c207']))
        c.drawString(column2, lineas[8], escribe(data['c208']))
        c.drawString(column2, lineas[9], escribe(data['c209']))
        c.drawString(column2, lineas[10], escribe(data['c210']))
        c.drawString(column2, lineas[11], escribe(data['c211']))
        c.drawString(column2, lineas[12], escribe(data['c212']))
        c.drawImage(data['logo'], logo[0], logo[1], 
                    2.5 * cm, 2.5 * cm)
        if mostrar_marcado and not rollo['defectuoso']:
            c.drawImage(logo_marcado, 
                        marcado[0] 
                            - ((0.30*cm
                                + c.stringWidth(data['marcado']) ) / 2),
                        marcado[1],
                        width = 0.35 * cm,
                        height = 6)
            c.setFont("Helvetica-Bold", 8)
            c.drawCentredString(marcado[0] + ((0.35*cm) / 2), 
                                marcado[1], 
                                escribe(data["marcado"]))

        #c.setPageRotation(-90)
        #c.rotate(-90)
        c.showPage()
    c.save()
    return nomarchivo
Ejemplo n.º 18
0
def go_from_presupuesto(presupuesto, 
                        incluir_condicionado_general = True,
                        idioma = "es"):
    """
    Construye el PDF a partir de un objeto presupuesto y no de sus datos 
    sueltos.
    """
    try:
        dde = pclases.DatosDeLaEmpresa.select()[0]
        lineas_empresa = [dde.nombre, 
                          dde.direccion, 
                          "%s %s (%s), %s" % (dde.cp, 
                                              dde.ciudad, 
                                              dde.provincia, 
                                              dde.pais), 
                          "Tel.: %s" % (dde.telefono)]
        if dde.fax:
            lineas_empresa.append("Fax: %s" % (dde.fax))
        if dde.email:
            lineas_empresa.append(dde.email)
        elif presupuesto.comercial and presupuesto.comercial.correoe:
            lineas_empresa.append(presupuesto.comercial.correoe)
        if dde.web:
            lineas_empresa.append('<a href=http://%s>%s</a>' % (
                dde.web, dde.web))
        # Son pocos textos. No merece la pena tirar de gettext hasta que
        # no me pidan un tercer idioma.
        if idioma == "en":
            strfiscal = "Corp. data: %s %s %s %s"
        else:
            strfiscal = "Datos fiscales: %s %s %s %s"
        dir_fiscal = strfiscal % (
                dde.nombre, 
                dde.get_dir_facturacion_completa(), 
                dde.str_cif_o_nif(), 
                dde.cif)
    except IndexError:
        lineas_empresa = []
        dir_fiscal = ""
    #lineas_contenido = presupuesto.lineasDePedido + presupuesto.servicios
    lineas_contenido = presupuesto.lineasDePresupuesto 
    lineas_contenido.sort(key = lambda ldp: ldp.id)
    datos_cliente = []
    nombre_cliente = presupuesto.nombrecliente
    datos_cliente.append(nombre_cliente)
    cif = presupuesto.cliente and presupuesto.cliente.cif or presupuesto.cif
    datos_cliente.append(" <small>(%s)</small>" % cif)
    if presupuesto.personaContacto != "":
        if idioma == "en":
            stratt = "Att: %s"
        else:
            stratt = "A la atención de %s"
        datos_cliente.append(stratt % (
            presupuesto.personaContacto))
    datos_cliente.append(presupuesto.direccion)
    listadireccion = [presupuesto.cp, presupuesto.ciudad]
    if presupuesto.ciudad.strip() != presupuesto.provincia.strip():
        if presupuesto.ciudad.strip():
            listadireccion.append("(" + presupuesto.provincia + ")")
        else: 
            listadireccion.append(presupuesto.provincia)
    listadireccion.append(presupuesto.pais)
    segunda_linea_direccion = " ".join([token.strip() 
                                        for token in listadireccion 
                                        if token.strip() != ""])
    datos_cliente.append(segunda_linea_direccion)
    if presupuesto.telefono.strip() != "":
        if idioma == "en":
            strphone = "Phone n.: %s"
        else:
            strphone = "Tlf.: %s"
        datos_cliente.append(strphone % (presupuesto.telefono))
    if presupuesto.fax.strip() != "":
        datos_cliente.append("Fax.: %s" % (presupuesto.fax))
    if presupuesto.obra or presupuesto.nombreobra.strip():
        try:
            ref_obra = presupuesto.obra.obra.get_str_obra()
        except AttributeError:
            ref_obra = presupuesto.nombreobra
        if idioma == "en":
            strobra = "Ref.: <b>%s</b>"
        else:
            strobra = "Ref. obra: <b>%s</b>"
        datos_cliente.append(strobra % ref_obra)
    fecha_entradilla = utils.str_fecha(presupuesto.fecha)
    try:
        iva = presupuesto.cliente.get_iva_norm()
    except AttributeError:
        if (presupuesto.pais and presupuesto.pais.upper() 
                not in ("ESPAÑA", "ESPAñA", "SPAIN")):
            iva = 0
        else:
            iva = 0.21
    if idioma == "en":
        strbimp = "Subtotal"
        striva = "VAT %d%%" % (iva * 100)
        strtot = "TOTAL"
    else:
        strbimp = "Base imponible"
        striva = "IVA %d%%" % (iva * 100)
        strtot = "TOTAL"
    totales = {"orden": [strbimp, 
                         striva, 
                         strtot], 
               strbimp:
                    utils.float2str(presupuesto.calcular_base_imponible())+" €",
               striva: 
                    utils.float2str(presupuesto.calcular_total_iva())+" €", 
               strtot: 
                    utils.float2str(presupuesto.calcular_importe_total())+" €", 
               }
    if presupuesto.descuento:
        if idioma == "en":
            strdto = "Descuento %s %%"
        else:
            strdto = "Discount %s %%"
        fila_descuento = strdto % (
            utils.float2str(presupuesto.descuento*100, autodec = True))
        totales['orden'].insert(0, fila_descuento) 
        totales[fila_descuento] = utils.float2str(
            presupuesto.calcular_subtotal(incluir_descuento = False) 
            * presupuesto.descuento * -1)
        fila_subtotal = "Subtotal"
        totales['orden'].insert(0, fila_subtotal) 
        totales[fila_subtotal] = utils.float2str(
            presupuesto.calcular_subtotal(incluir_descuento = False))
    total_irpf = presupuesto.calcular_total_irpf()
    if total_irpf != 0:
        try:
            dde = pclases.DatosDeLaEmpresa.select()[0]
            irpf = dde.irpf
        except IndexError:
            irpf = None
        texto_irpf = "IRPF"
        if irpf:
            texto_irpf += " (%d%%)" % (irpf*100)
        totales[texto_irpf] = utils.float2str(total_irpf)
        totales["orden"].insert(-2, texto_irpf)
    try:
        dde = pclases.DatosDeLaEmpresa.select()[0]
        logo = dde.get_ruta_completa_logo()
    except IndexError:
        logo = None
    if presupuesto.validez:
        validez = presupuesto.validez
    else:
        validez = None
    if presupuesto.texto:
        condiciones = presupuesto.texto + "\n"
    else:
        condiciones = None
    # Condiciones "blandas" del presupuesto
    # CWT: Se debe imprimir en todos los presupuestos, por si a la hora de 
    # formalizarlo como pedido se ha quedado sin crédito por alguna operación 
    # anterior al pedido y posterior a la oferta.
    #if (not presupuesto.cliente 
    #    or presupuesto.cliente.calcular_credito_disponible(
    #        base = presupuesto.calcular_importe_total(iva = True)) <= 0):
    if True:
        if idioma == "en":
            texto_riesgo = "Operation conditioned by a previous credit "\
                           "approbation by %s." % dde.nombre
        else:
            texto_riesgo = "Esta operación está sujeta a la concesión de "\
                           "crédito por parte de %s." % dde.nombre
    else:
        texto_riesgo = None
    nomarchivo = os.path.join(gettempdir(), 
                              "presupuesto_%s.pdf" % give_me_the_name_baby())
    if presupuesto.texto:
        if idioma == "en":
            condicionado = "Particular conditions:\n" + presupuesto.texto
        else:
            condicionado = "Condiciones particulares:\n" + presupuesto.texto
    else:
        condicionado = None
    try:
        if idioma == "en":
            strpresupuesto = "Offer "
            fdp = "Payment terms: %s" % presupuesto.formaDePago.toString(
                    presupuesto.cliente)
        else:
            strpresupuesto = "Presupuesto"
            fdp = "Forma de pago: %s" % presupuesto.formaDePago.toString(
                    presupuesto.cliente)
    except AttributeError:
        fdp = ""
    if presupuesto.comercial:
        firma_comercial = '<b>%s %s</b>\n<i>%s</i>\n%s\n<u>'\
                          '<a href="mailto:%s">%s</a></u>'\
                          '<b> </b>' % (
                presupuesto.comercial.empleado.nombre
                    and presupuesto.comercial.empleado.nombre or "", 
                presupuesto.comercial.empleado.apellidos 
                    and presupuesto.comercial.empleado.apellidos or "", 
                presupuesto.comercial.cargo
                    and presupuesto.comercial.cargo or "", 
                presupuesto.comercial.telefono 
                    and presupuesto.comercial.telefono or "", 
                presupuesto.comercial.correoe 
                    and presupuesto.comercial.correoe or "", 
                presupuesto.comercial.correoe 
                    and presupuesto.comercial.correoe or "")
    else:
        firma_comercial = ""
    nomarchivo = go(
      "%s %s (%s)" % (strpresupuesto, 
                      presupuesto.nombrecliente, 
                      utils.str_fecha(presupuesto.fecha)), 
       nomarchivo, 
       lineas_empresa, 
       datos_cliente, 
       lineas_contenido, 
       fecha_entradilla, 
       totales, 
       condicionado, 
       presupuesto.despedida, 
       ruta_logo = logo, 
       validez = validez, 
       texto_riesgo = texto_riesgo, 
       #numpresupuesto = presupuesto.numpresupuesto)
       numpresupuesto = presupuesto.id, 
       forma_de_pago = fdp, 
       dir_fiscal = dir_fiscal, 
       firma_comercial = firma_comercial, 
       para_estudio = presupuesto.estudio, 
       idioma = idioma)
    return nomarchivo
Ejemplo n.º 19
0
def go(
    numfactura="", fecha="", nombre_cliente="", direccion="", ciudad="", cif="", ldvs=[], totales=[], solo_texto=False
):
    """
    A partir de los parámetros recibidos construye un PDF con el factura 
    completo.
    ldvs es una lista de cantidad (float), concepto, kgs (float), precio 
    (float) e importe (float).
    Si len(ldvs) > MAXLINEAS genera (len(ldvs)/MAXLINEAS) + 1 páginas, con el 
    número de página entre paréntesis tras el número de factura.
    Si solo_texto es True, no se dibuja la plantulla de la factura, solo los 
    datos.
    Devuelve en nombre del fichero generado.
    """
    # Inicialización y medidas:
    nomarchivo = os.path.join(gettempdir(), "factura_%s.pdf" % (geninformes.give_me_the_name_baby()))
    c = canvas.Canvas(nomarchivo)
    c.setTitle("factura_%s" % numfactura)
    tampag = A4
    c.setPageSize(tampag)
    tm, bm, lm, rm = 1 * cm, 0.6 * cm, 0.6 * cm, 1 * cm
    fuente, tamanno = "Helvetica", 10
    hlin = 0.7 * cm
    MAXLINEAS = 30
    paginas = int((len(ldvs) + len(totales)) / MAXLINEAS) + 1
    medidas = {
        "cliente": (10 * cm, tampag[1] - 1 * cm, 18.6 * cm, tampag[1] - 4.95 * cm),
        # x e y para la esquina sup. izq. e inf. der.
        "logo": (2.2 * cm, tampag[1] - 1.3 * cm, 5.2 * cm, 3.4 * cm),
        # (x,y) de esquina sup. izq. y ancho y alto
        "dde": (tampag[1] / 2, -0.6 * cm),
        # (x,y) sabiendo que va con CenteredString y girado 90º
        "regmercantil": (tampag[0] / 2, 0.6 * cm),
        # (x,y) sabiendo que va centrado.
        "ldvs": (1 * cm, tampag[1] - 6.2 * cm, tampag[0] - rm, 2.7 * cm),
        # (x,y) de esquinas sup. izq. e inf. der.
        "watermark": (9.5 * cm, 13.5 * cm, 9.5 * cm, 10 * cm),
        # esquina sup. izq., ancho y alto
        "numfactura": (1.5 * cm, tampag[1] - 5.8 * cm),
        # (x,y)
        "fecha": (10.5 * cm, tampag[1] - 5.8 * cm),
        # (x,y)
    }
    hcab = 0.5 * cm  # altura cabecera
    medidas_tabla = {
        "xnumalb": 1.0 * cm,
        "xdesc": 1.0 * cm + 2.7 * cm,
        "xfecha": 1.0 * cm + 2.7 * cm + 7.4 * cm,
        "xkgs": 1.0 * cm + 2.7 * cm + 7.4 * cm + 2.6 * cm,
        "xprecio": 1.0 * cm + 2.7 * cm + 7.4 * cm + 2.6 * cm + 1.7 * cm,
        "ximporte": 1.0 * cm + 2.7 * cm + 7.4 * cm + 2.6 * cm + 1.7 * cm + 2 * cm,
        "xfinal": medidas["ldvs"][2],
        "y0": medidas["ldvs"][1] - hcab,
        "yfinal": medidas["ldvs"][3],
        "y1": medidas["ldvs"][1] - hcab - hlin,
        "h": hlin,
        "hcab": hcab,
    }
    # Páginas de la factura
    for pag in range(1, paginas + 1):
        # Parte preimpresa:
        if not solo_texto:
            dibujar_imprenta(c, hlin, tm, bm, lm, rm, tampag, medidas, fuente, tamanno, MAXLINEAS, medidas_tabla)
        # Datos:
        c.setFont(fuente, tamanno)
        if paginas > 1:
            numalb = numfactura + "(%d)" % pag
            if pag == paginas:
                printot = totales
            else:
                printot = []
        else:
            numalb = numfactura
            printot = totales
        rellenar_datos(c, numalb, fecha, nombre_cliente, direccion, ciudad, cif, medidas, fuente, tamanno)
        rellenar_ldvs(c, ldvs[:MAXLINEAS], printot, medidas_tabla, hlin)
        ldvs = ldvs[MAXLINEAS:]
        c.showPage()
    c.save()
    return nomarchivo
Ejemplo n.º 20
0
def go_from_facturaVenta(facturaVenta):
    """
    Construye el PDF a partir de un objeto facturaVenta y no de sus datos
    sueltos.
    """
    cliente = facturaVenta.cliente
    datos_cliente = {"código": cliente.id,
                     "cif": cliente.cif,
                     "razón social": cliente.nombre,
                     "dirección": cliente.direccion,
                     "población": cliente.ciudad,
                     "provincia": cliente.provincia}
    if cliente.cp and cliente.cp.strip():
        datos_cliente["población"] = (cliente.cp + " - "
                                      + datos_cliente["población"])
    datos_factura = {"fecha": utils.str_fecha(facturaVenta.fecha),
                     "número": facturaVenta.numfactura,
                     "codcliente": facturaVenta.cliente
                                    and `facturaVenta.cliente.id`
                                    or ""}
    iva = cliente.iva
    # TODO: ¿Usar el float2str_autoprecision?
    lineas_contenido = [(ldv.producto.codigo,
                         ldv.producto.descripcion,
                         ldv.cantidad,
                         ldv.precio * (1.0 - ldv.descuento) * (1 + iva))
                        for ldv in facturaVenta.lineasDeVenta]
    lineas_contenido += [("",
                          srv.concepto,
                          srv.cantidad,
                          srv.precio * (1.0 - srv.descuento) * (1 + iva))
                         for srv in facturaVenta.servicios]
    totales = [facturaVenta.calcular_base_imponible(),
               iva,
               facturaVenta.calcular_total()]
    try:
        dde = pclases.DatosDeLaEmpresa.select()[0]
        datos_de_la_empresa = [os.path.join("..", "imagenes", dde.logo),
                               dde.nombre +
                                (dde.cif and " (" + dde.str_cif_o_nif() +": " + dde.cif + ")" or ""),
                               dde.direccion,
                               "%s %s (%s), %s" % (dde.cp,
                                                   dde.ciudad,
                                                   dde.provincia,
                                                   dde.pais),
                               ]
        if dde.fax:
            if dde.fax.strip() == dde.telefono.strip():
                datos_de_la_empresa.append("Telf. y fax: %s" % dde.telefono)
            else:
                datos_de_la_empresa.append("Telf.: %s" % (dde.telefono))
                datos_de_la_empresa.append("Fax: %s" % (dde.fax))
        if dde.email:
            datos_de_la_empresa.append(dde.email)
    except IndexError:
        datos_de_la_empresa = [None]
    nomarchivo = os.path.join(gettempdir(),
                              "facturaVenta_%s.pdf" % give_me_the_name_baby())
    vencimientos = []
    forma_de_pago = []
    vtos = facturaVenta.vencimientosCobro[:]
    vtos.sort(lambda v1, v2: (v1.fecha < v2.fecha and 1)
                              or (v1.fecha > v2.fecha and -1)
                              or 0)
    for v in vtos:
        strvto = "%s (%s €)" % (utils.str_fecha(v.fecha),
                                utils.float2str(v.importe))
        vencimientos.append(strvto)
        forma_de_pago.append(v.observaciones)
    observaciones = ["Importa la presente factura:",
                     numerals.numerals(totales[-1],
                                       moneda = "EUROS",
                                       fraccion = "CÉNTIMOS").upper()]
    if facturaVenta.observaciones:
        observaciones.append(facturaVenta.observaciones)
    return go("Factura de venta %s (%s)" % (
                facturaVenta.cliente.nombre,
                utils.str_fecha(facturaVenta.fecha)),
              nomarchivo,
              datos_cliente,
              datos_factura,
              lineas_contenido,
              totales,
              datos_de_la_empresa,
              observaciones,
              vencimientos,
              forma_de_pago)