Noob in need of help!!!

Hi there, I’m trying to implement a quite “simple” project for University… there will be a list of items with price (done), some labor data - position and salary (done), with which will be used to calculate the “per unit cost”

for example: If I have to price how much cost to install one light switch on the wall. I 'll use the material prices (cover plate, modules, electric tape), a performance value - already stored to the DB (done), and add the to the value some percentage such as “profit”, “Admin fees” and “taxes” (all variables stored). and calculate the per unit price.

So let’s say I have total of materials: $10, an electrician 8h pay of $165 (calculated from salary) which can install 40 units/day (performance rate), meaning only one will cost $4.13 on labor. Therefore, my total would be ($10+$4.13)*Variables

Than I’ll be adding, with a client name, per unit prices and quantities adding up to a total proposal.

My problem is where and how to do the calculations? Is there an example that could be flowed?
I’m stuck with the calculations… because it involves more than two tables, I can’t find info to get it done. Please help!!!

Calcs like this you put in your view or the model.

As you have a few models then probably calculate in the view.

Just create your function that does the calc in the view somewhere as a separate function. Then pass the variables to to it.

def calculate_price(materials, worker_hours, worker_dollars_per_hour, etc):
    return materials + (worker_hours * worker_dollars_per_hour) # etc...

Then in your view where you are calling the template you would get the variables from the db and pass to the calculate function.

If I was getting really picky - the calculation should be in its own file separate to the views - but that is probably beyond the scope of this task.

Thanks for the fast reply!
I’ll be trying to implement that!
Cheers!

Hi there, I’ve managed to do all calculations and working well, Thanks for the suggestion!
Now I would like to show a sort of summary for all data from the DB into a home page, but using:
Entry.objects.count() or Entry.objects.all().count() or Entry.objects.filter().count()… etc nothing works what am I doing wrong?
Thanks!
my list:

<ul>

        <li><strong>Cotizaciones Creadas: </strong>{{ct}}</li>

        <li><strong>Número de Clientes: </strong>{{cl}}</li>

        <li><strong>Total de Items el la Base de Datos: </strong>{{m}}</li>

        <li><strong>Número de Mano de Obra: </strong>{{mo}}</li>

        <li><strong>Rendimientos Calculados: </strong>{{rd}}</li>

        <li><strong>Precios Unitarios: </strong>{{pu}}</li>

    </ul>

the home view:

class Home(TemplateView):

    template_name = 'cotizacion/index.html'

    ct = Cotizaciones.objects.all().count()

    cl = Clientes.objects.all().count()

    m = Materiales.objects.all().count()

    mo = ManoObra.objects.all().count()

    rd = Rendimientos.objects.all().count()

    pu = PreciosUnitarios.objects.all().count()

You have to pass your data to the template through the context. If you’re not familiar with the context, see Rendering a context.

See the docs and example for TemplateView.

Great… did work! Thanks a lot!

Is there any example on how to show in detail view data from more than one many to many relations?
Thanks!

In principle, it’s no different than showing the detail from one many-to-many relationship, you’re doing effectively the same thing multiple times.

I just can’t get it to work… do you have any example in the docs that I could guide myself?

There’s really not enough information here to even know how to guide you.
Please post your view, template, and models.

(When posting code here, copy/paste the code, don’t post images, and post the code between lines of three backtick - ` characters. This means you’ll have a line of ```, then your code, then another line of ```.)

"’
class Cotizaciones(models.Model):
cliente_id = models.ForeignKey(Clientes, on_delete=models.CASCADE)
pu_id = models.ManyToManyField(PreciosUnitarios, through=‘ItemCotiza’)
valor_mo = models.FloatField(blank=True, null=True)
valor_materiales = models.FloatField(blank=True, null=True)
creado_en = models.DateTimeField(default=timezone.now)

class Meta():
    ordering = ['creado_en']

def get_absolute_url(self):
    return reverse('cotizacion_detail', kwargs={'pk': self.pk})

def __str__(self) -> str:
    return "Cotización #: " + str(self.id) + " - Cliente: " + self.cliente_id.nombre

def save(self, *args, **kwargs):
    if self.id:
        ic = ItemCotiza.objects.filter(cotizacion_id=self.id)
        tm = ic.aggregate(Sum('valor_material'))['valor_material__sum']
        tmo = ic.aggregate(Sum('valor_mo'))['valor_mo__sum']
        self.valor_materiales = tm
        self.valor_mo = tmo
        super().save(*args, **kwargs)
    else:
        super().save(*args, **kwargs)

class ItemCotiza(models.Model):
pu_id = models.ForeignKey(
PreciosUnitarios, on_delete=models.CASCADE)
cotizacion_id = models.ForeignKey(Cotizaciones, on_delete=models.CASCADE)
cantidad = models.PositiveIntegerField(default=1)
valor_material = models.FloatField(
validators=[validate_decimals], blank=True, null=True)
valor_mo = models.FloatField(
validators=[validate_decimals], blank=True, null=True)

class Meta():
    unique_together = [['cotizacion_id', 'pu_id']]

def __str__(self):
    return str(self.cotizacion_id)+self.pu_id.redimiento.nombre

def save(self, *args, **kwargs):
    self.valor_material = self.pu_id.valor_material * self.cantidad
    self.valor_mo = self.pu_id.valor_mo * self.cantidad
    super().save(*args, **kwargs)

"’
The view:
‘’’
class CotizacionDetailView(DetailView):
model = Cotizaciones
‘’’
the Detail:
‘’’ {% block content %}

Detalle de la Cotización:


{{cotizaciones}}


<ul>
    {% for ic in cotizacines_detail.itemcotiza.all %}
    <li><strong>{{ic}} </strong></li><br>
    <li><strong>Unidades por Jornal: </strong></li><br>
    {%endfor%}
</ul>

{% endblock %} ‘’’

(Side note: something is translating your backticks to “smart quotes” which is messing up your formatting)

Ok, so what is it that you’re trying to do here?

I want to show the details for the quotation… which items are involved… before hand I do calculate for each item the per unit price.
I can verify it does work in the DB but can’t bring it to the frontend side!

I’m sorry, I’m trying to ask the question in terms of the models you’ve posted here. What is the output that you’re trying to create?
Or even better, what have you tried that isn’t working?

1 Like

A list of items, quantity and subtotals
A labor total, material total and a final total
Like:
Quotation #1:
cable awg 12 - 12 m - $6
electric tape - 1 piece - $2
total labor: $1.8
total Items: $7.2
total $8

I do have the List view of the Quotations I’ve generated directly within the DB, but when select the record to show the detail… nothing

Unfortunately, I don’t understand what you’re trying to tell me here relative to what you started with.

You wrote:

What models are you trying to display? What relationships are you trying follow? Please phrase your answers using the class and field names of the entities that you’ve posted above.
Also, you mentioned that you couldn’t get it to work - what did you try?

(And please go back and fix your post to replace the quotes with the backticks.)

from django.core.exceptions import ValidationError
from django.db import models
from django.db.models import Sum
from django.utils import timezone
from django.urls import reverse
from pandas.core.aggregation import aggregate


def validate_decimals(value):
    try:
        return round(float(value), 2)
    except:
        raise ValidationError(
            ('%(value)s is not an integer or a float  number'),
            params={'value': value},
        )


class Materiales (models.Model):
    UNIDADES_CHOICES = [
        ('PZA', 'PIEZA'),
        ('UND', 'UNIDAD'),
        ('M', 'METRO LINEAR'),
        ('KG', 'KILOGRAMO'),
    ]
    material_nombre = models.CharField(max_length=120)
    marca = models.CharField(max_length=120)
    descripcion = models.CharField(max_length=300)
    precio = models.FloatField()
    unidad = models.CharField(
        max_length=3, choices=UNIDADES_CHOICES, default='PZA')

    class Meta:
        ordering = ['material_nombre']

    def __str__(self):
        return self.material_nombre+' ' + self.marca

    def get_absolute_url(self):
        return reverse('material_detail', kwargs={'pk': self.pk})


class Clientes(models.Model):
    nombre = models.CharField(max_length=200)

    class Meta:
        ordering = ['nombre']

    def __str__(self):
        return self.nombre

    def get_absolute_url(self):
        return reverse('cliente_detail', kwargs={'pk': self.pk})


class ManoObra(models.Model):
    cargo = models.CharField(max_length=150, unique=True)
    salario = models.FloatField(validators=[validate_decimals])

    class Meta:
        ordering = ['cargo']

    def __str__(self):
        return self.cargo

    def get_absolute_url(self):
        return reverse('mo_detail', kwargs={'pk': self.pk})


# Posibilidad de desarrollo --> análisis de rendimientos


class Rendimientos(models.Model):
    nombre = models.CharField(max_length=120, unique=True)
    descripcion = models.CharField(max_length=200)
    unidades_jornal = models.FloatField()

    class Meta():
        ordering = ['nombre']

    def __str__(self):
        return self.nombre + " - " + self.descripcion

    def get_absolute_url(self):
        return reverse('rendimiento_detail', kwargs={'pk': self.pk})


class Variables(models.Model):
    utilidad = models.FloatField(default=0.15)
    iva = models.FloatField(default=1.1494)
    gastos_admin = models.FloatField(default=0.10)
    herramientas = models.FloatField(default=0.02)
    seguridad = models.FloatField(default=0.04)

    def __str__(self):
        return ("Utilidad: "+str(self.utilidad)+", IVA: "+str(self.iva)
                + ", generales & Administrativos: "+str(self.gastos_admin))


# implementación futura - discriminar los materiales


class PreciosUnitarios(models.Model):
    redimiento = models.ForeignKey(Rendimientos, on_delete=models.CASCADE)
    mano_obra = models.ManyToManyField(ManoObra, through='PuManoObra')
    material_id = models.ManyToManyField(Materiales, through='Pu_Material')
    valor_mo = models.FloatField(
        validators=[validate_decimals], blank=True, null=True)
    valor_material = models.FloatField(
        validators=[validate_decimals], blank=True, null=True)

    def __str__(self) -> str:
        return self.redimiento.nombre

    def get_absolute_url(self):
        return reverse('pu_detail', kwargs={'pk': self.pk})

    def save(self, *args, **kwargs):
        if self.id:
            pk = self.id
            v = Variables.objects.get(pk=2)
            rm = self.redimiento.unidades_jornal
            jc = ManoObra.objects.get(cargo='Jefe de Cuadrilla')
            pu_m = Pu_Material.objects.filter(pu_id=pk)
            pu_mo = PuManoObra.objects.filter(pu_id=pk)
            tm = pu_m.aggregate(Sum('subtotal'))['subtotal__sum']
            tmo = pu_mo.aggregate(Sum('mo_subtotal'))['mo_subtotal__sum']
            tmo = (tmo + (((jc.salario*8)/208) * 0.10))/rm
            total_herramientas = tmo * v.herramientas
            total_seguridad = tmo * v.seguridad
            subtotal = tm+tmo+total_herramientas+total_seguridad
            total = subtotal / (1 - v.gastos_admin)
            total = total/(1-v.utilidad)
            total = total*v.iva
            self.valor_mo = total * \
                (tmo/(subtotal))
            self.valor_material = total * \
                (tm/(subtotal))

            super().save(*args, **kwargs)
        else:
            super().save(*args, **kwargs)


class PuManoObra(models.Model):
    manoObra_id = models.ForeignKey(ManoObra, on_delete=models.CASCADE)
    pu_id = models.ForeignKey(PreciosUnitarios, on_delete=models.CASCADE)
    valor_jornal = models.FloatField(
        validators=[validate_decimals], null=True, blank=True)
    mo_subtotal = models.FloatField(
        validators=[validate_decimals], null=True, blank=True)
    ctd = models.PositiveIntegerField(default=1)

    def __str__(self) -> str:
        return self.pu_id.redimiento.nombre + ", "+self.manoObra_id.cargo

    def save(self, *args, **kwargs):
        vj = self.manoObra_id.salario/26
        self.valor_jornal = vj
        self.mo_subtotal = self.ctd*vj
        super().save(*args, **kwargs)


class Pu_Material(models.Model):
    material_id = models.ForeignKey(Materiales, on_delete=models.CASCADE)
    pu_id = models.ForeignKey(PreciosUnitarios, on_delete=models.CASCADE)
    cantidad = models.PositiveIntegerField(default=1)
    subtotal = models.FloatField(
        validators=[validate_decimals], null=True, blank=True)

    class Meta():
        unique_together = [['material_id', 'pu_id']]

    def __str__(self) -> str:
        return self.pu_id.redimiento.nombre + ", Material: "+self.material_id.material_nombre

    def save(self, *args, **kwargs):
        self.subtotal = self.material_id.precio*self.cantidad
        super().save(*args, **kwargs)


class Cotizaciones(models.Model):
    cliente_id = models.ForeignKey(Clientes, on_delete=models.CASCADE)
    pu_id = models.ManyToManyField(PreciosUnitarios, through='ItemCotiza')
    valor_mo = models.FloatField(blank=True, null=True)
    valor_materiales = models.FloatField(blank=True, null=True)
    creado_en = models.DateTimeField(default=timezone.now)

    class Meta():
        ordering = ['creado_en']

    def get_absolute_url(self):
        return reverse('cotizacion_detail', kwargs={'pk': self.pk})

    def __str__(self) -> str:
        return "Cotización #: " + str(self.id) + " - Cliente: " + self.cliente_id.nombre

    def save(self, *args, **kwargs):
        if self.id:
            ic = ItemCotiza.objects.filter(cotizacion_id=self.id)
            tm = ic.aggregate(Sum('valor_material'))['valor_material__sum']
            tmo = ic.aggregate(Sum('valor_mo'))['valor_mo__sum']
            self.valor_materiales = tm
            self.valor_mo = tmo
            super().save(*args, **kwargs)
        else:
            super().save(*args, **kwargs)


class ItemCotiza(models.Model):
    pu_id = models.ForeignKey(
        PreciosUnitarios, on_delete=models.CASCADE)
    cotizacion_id = models.ForeignKey(Cotizaciones, on_delete=models.CASCADE)
    cantidad = models.PositiveIntegerField(default=1)
    valor_material = models.FloatField(
        validators=[validate_decimals], blank=True, null=True)
    valor_mo = models.FloatField(
        validators=[validate_decimals], blank=True, null=True)

    class Meta():
        unique_together = [['cotizacion_id', 'pu_id']]

    def __str__(self):
        return str(self.cotizacion_id)+self.pu_id.redimiento.nombre

    def save(self, *args, **kwargs):
        self.valor_material = self.pu_id.valor_material * self.cantidad
        self.valor_mo = self.pu_id.valor_mo * self.cantidad
        super().save(*args, **kwargs)

I want to show the details from Cotizaciones and ItemCotiza

Let me see if I’m with you so far:

You want to create a view, where you query the Cotizaciones and ItemCotiza table, and you want to display both those items in the same view, along with some currently-unidentified data.

Is this where we’re starting from?

the data within both tables are connected… so for each Cotización there are one or more items (pu_id in the ItemCotiza as for the items)
I don’t know how to show a detail of one cotizacion with all the items that belong to it.

My experience with Django so far it’s nothing but frustrations! I’ve chosen it to make my final project at Uni and after all the logic done - with loads of suffering, I can’t get it to display at screen! The documentation really awkward and complicated for beginners… I do appreciated the help, but oh boy I regret the day I’ve listen to someone who convinced me to use it!

Sorry to bother, but is it possible to have multiple forms in the same view or sort of subforms? I want to make a view to collect the data to be saved into the models is it possible?