Is it possible to have a model field set to subtract sum of values from many table - python

I'm creating a crypto-currency app. I have a table called Transaction, which can have 0 or many sales stored on Sale Table. Is it possible to set up a field on the Transaction model "coins_remaining" that will be equal to (amount - sum(amount_sold) from sale table).
Transaction model below
class Transaction(models.Model):
currency = models.CharField(max_length=20)
amount = models.IntegerField()
total_price = models.DecimalField(max_digits=8, decimal_places=2)
date_purchased = models.DateTimeField()
note = models.TextField(default="")
owner = models.ForeignKey(User, on_delete=models.CASCADE)
amount_per_coin = models.DecimalField(max_digits=8, decimal_places=2, editable=False)
def save(self, *args, **kwargs):
self.amount_per_coin = self.total_price / self.amount
super(Transaction, self).save(*args, **kwargs)
Sale table below
class Sale(models.Model):
amount_sold = models.IntegerField()
total_price_sold = models.DecimalField(max_digits=8, decimal_places=2)
date_sold = models.DateTimeField(default=timezone.now)
note = models.TextField(default="")
transaction = models.ForeignKey(Transaction, on_delete=models.CASCADE)
amount_per_coin_sold = models.DecimalField(max_digits=8, decimal_places=2, editable=False)
def save(self, *args, **kwargs):
self.amount_per_coin_sold = self.total_price_sold / self.amount_sold
super(Sale, self).save(*args, **kwargs)

You could define a property on transaction that does it:
#property
def coins_remaining(self):
return self.amount - sum(self.sales.all().values_list('amount_sold', flat=True))

you can create the transaction table as a DataFrame, take the sum of the "amount_sold" column then substract it from the amount
t = Transaction()
s = Sale()
s.transactions = pd.DataFrame({'id': [1,2,3,4,5], 'amount_sold': [10, 20, 30, 40, 50]})
coins_remaining = t.amount - s.transactions['amount_sold'].sum()

Related

Django models, referencing and storing model id

I have a model by name Order, I want to create and invoice_number field on this same model and store order id and some other generated text to make up order invoice_number and I can't figure it out, I think there is a short and neat way to achieve this and I will appreciate any help Thanks.
This code throws and error that self is not defined
here is my code
import datetime
YEAR = datetime.datetime.today().year
class Order(models.Model):
customer_contact = models.IntegerField()
paid = models.BooleanField(default=False)
date = models.DateTimeField(auto_now=True)
salesman = models.CharField(db_index=True, max_length=20)
discount = models.IntegerField(default=0)
price = models.IntegerField(default=0)
customer_name = models.CharField(db_index=True, max_length=20)
apartment_name = models.CharField(db_index=True, max_length=20)
flat_number = models.IntegerField()
invoice_number = models.CharField(max_length=20,
default=f'{YEAR}/INV/000{self.pk}')
First of all, remove the default argument from the invoice_number field and then override the save() method of the model
import datetime
YEAR = datetime.datetime.today().year
class Order(models.Model):
customer_contact = models.IntegerField()
paid = models.BooleanField(default=False)
date = models.DateTimeField(auto_now=True)
salesman = models.CharField(db_index=True, max_length=20)
discount = models.IntegerField(default=0)
price = models.IntegerField(default=0)
customer_name = models.CharField(db_index=True, max_length=20)
apartment_name = models.CharField(db_index=True, max_length=20)
flat_number = models.IntegerField()
invoice_number = models.CharField(max_length=20) # changed here
def save(self, **kwargs):
created = not self.pk
super().save(**kwargs)
if created:
self.invoice_number = f'{YEAR}/INV/000{self.pk}'
self.save()

How to change the data of a table field from another?

Good evening.
The goal is that when creating the Transfer model, the sum field was subtracted from whom_from and added to whom_to Bill's model. As I understand it, this needs to be done through save (), but apparently, I did not set it up correctly. What could be the problem?
models.py
class Bill(models.Model):
title = models.CharField(max_length=100)
amount = models.DecimalField(max_digits=19, decimal_places=2,
validators=[MinValueValidator(0)], default=0)
def __str__(self):
return self.title
class Transfer(models.Model):
whom_from = models.ForeignKey(Bill, on_delete=models.CASCADE, related_name='whom_from')
whom_to = models.ForeignKey(Bill, on_delete=models.CASCADE, related_name='whom_to')
sum = models.DecimalField(max_digits=19, decimal_places=2, validators=[MinValueValidator(0)], default=0)
def save(self, *args, **kwargs):
self.whom_to.amount = self.whom_to.amount + self.sum
self.whom_from.amount = self.whom_from.amount - self.sum
super(Transfer, self).save(*args, **kwargs)

Django - Copying model field to another field

I did a lot of search but couldn't find a proper way to do it.
I want to copy some model object data to another model object data.
I've added my codes below. I got 3 models. as you can see I got a FK ,
the Receipt model related with receipt field. when I want to add Receiptitem object I wanna copy amount , vat and total_amount exactly.
I didn't understad save method.
the user will add product and receipt. then When user will try to select ReceiptItem receipt and product droplists he will choose object he wants and the other stuff will get auto. I wanted to do this.
class Receipt(models.Model):
amount = models.DecimalField(max_digits=5, decimal_places=2)
vat = models.DecimalField(max_digits=5, decimal_places=2)
total_amount = models.DecimalField(max_digits=5, decimal_places=2)
def __str__(self):
return str(self.total_amount)
class ReceiptItem(models.Model):
receipt = models.ForeignKey('Receipt', on_delete=models.CASCADE )
product = models.ForeignKey('Product', on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=5, decimal_places=2)
vat = models.DecimalField(max_digits=5, decimal_places=2)
vat_rate = models.DecimalField(max_digits=5, decimal_places=2)
sub_total = models.DecimalField(max_digits=5, decimal_places=2)
name = models.CharField(max_length=200)
class Product(models.Model):
name = models.CharField(max_length=200)
vat_rate = models.DecimalField(max_digits=5, decimal_places=2)
amount = models.DecimalField(max_digits=5, decimal_places=2)
def __str__(self):
return self.name
If you want data to be copied over upon saving your ReceiptItem you can overload the save function of the model like this:
class ReceiptItem(models.Model):
# your fields here
def save(self, *args, **kwargs):
self.vat = self.receipt.vat
# copy the other data you need here
# the line below calls Model.save() which commits
# your changes to the database
super(ReceiptItem, self).save(*args, **kwargs)
Another option can be to set the values in ReceiptItem.__init__() if you need the values before the object is saved to database.

Django - UNIQUE constraint failed

I could'nt solve my problem even if I looked other people who had this problem.
How to create an id with foreign key? And how can I use the id?
This is my code:
class Receipt(models.Model):
amount = models.DecimalField(max_digits=5, decimal_places=2, primary_key=True)
vat = models.DecimalField(max_digits=5, decimal_places=2)
total_amount = models.IntegerField(default=0)
class ReceiptItem(models.Model):
receipt_id = models.ForeignKey('Receipt', on_delete=models.CASCADE)
product_id = models.ForeignKey('Product', on_delete=models.CASCADE)
amount = models.DecimalField(max_digits=5, decimal_places=2)
vat = models.DecimalField(max_digits=5, decimal_places=2)
vat_rate = models.DecimalField(max_digits=5, decimal_places=2)
sub_total = models.IntegerField(default=0)
name = models.CharField(max_length=200)
class Product(models.Model):
name = models.CharField(max_length=5)
vat_rate = models.DecimalField(max_digits=5, decimal_places=2)
amount = models.IntegerField(default=0, primary_key=True)
This is the error I'm getting:
django.db.utils.IntegrityError: UNIQUE constraint failed: migros_product.amount
class Product(models.Model):
name = models.CharField(max_length=5)
vat_rate = models.DecimalField(max_digits=5, decimal_places=2)
amount = models.IntegerField(default=0, primary_key=True)
Amount is set as primary key, which means that the database will only allow 1 record per value of amount.
BUT, you've also set a default value of 0, so your DB can only create 1 record with amount = 0, whenever the amount value is not provided.
You must decide what you want. If the amount uniqueness matters, then remove default=0 and put null=True, blank=True, for example.

Getting the total of unit price * quantity

Here's an excerpt from my models:
class Order(models.Model):
...
content_type = models.ForeignKey(ContentType)
user = models.ForeignKey('auth.User')
class OrderItem(models.Model):
...
unit_price = models.DecimalField(max_digits=7, decimal_places=2, blank=True)
quantity = models.SmallIntegerField()
order = models.ForeignKey(Order)
I have a dashboard where I want to display the total of sold items. I am struggling with how I can multiply the unit_price by the quantity.
You could do this with an extra() query:
OrderItem.objects.extra(select={'total': 'unit_price * quantity'})
You could add a property total to OrderItem:
class OrderItem(models.Model):
...
unit_price = models.DecimalField(max_digits=7, decimal_places=2, blank=True)
quantity = models.SmallIntegerField()
#property
def total(self):
return unit_price * quantity
# you can then access it like any other field (but you cannot filter on it)
print OrderItem.objects.get(pk=1).total

Resources