Django aggregation--find time differences in days - python

Now I can find each employee's total commissions but I want to sort them in days.
model.py
class Sale(models.Model):
date=models.DateTimeField(auto_now_add=True,blank=True,null=True)
commission=models.DecimalField(max_digits=7,decimal_places=2,blank=True,null=True)
ouremployee=models.ForeignKey(Employee,blank=True,null=True)
My sale object already recorded commission associated with each sale and each employee but now I want to find each employee's total commission with 7 days.
views.py
Sale = Sale.objects.all()
total_commission=0
TotalCommission = Sale.annotate(total_commission=Sum('ouremployee'))
My views.py doesn't work.
Here is my query:
Employee.objects.filter(str(datetime.datetime.now())-'sale__date') > str(datetime.timedelta(days=30))).annotate(total_commission=Sum('sale__commission'))

Related

Why am I getting an incorrect payment total via Stripe in Python?

I'm trying to make a payment through the ecommerce website I created. The payment successfully went through but the total amount charged is different than what I wanted to charge. For example, I want to charge $29.19 but I get charged $2,918.90. I know it has something to do with the decimal places, but I seem to have it correct; 2 decimal places.
I tried adding decimal to the subtotal, tax, and shipping to get a decimal total, though it came, I still had a wrong total amount.
My cart.py:
def get_total(self):
subtotal = sum(Decimal(item['price']) * int(item['quantity']) for item in self.cart.values())
tax = Decimal('0.10')
tax_price = sum(Decimal(item['price']) * int(item['quantity']) for item in self.cart.values()) * Decimal(tax)
shipping_cost = 5
total = Decimal(subtotal) + Decimal(tax_price) + Decimal(shipping_cost)
return total
My Payment views.py:
#login_required
def CartView(request):
cart = Cart(request)
total = str(cart.get_total())
total = total.replace('.', '')
stripe.api_key = ''
intent = stripe.PaymentIntent.create(
amount=total,
currency='usd',
metadata={'userid': request.user.id}
)
Order class:
total_paid = models.DecimalField(max_digits=5, decimal_places=2)
OrderItem class:
price = models.DecimalField(max_digits=5, decimal_places=2)
If you look at the PaymentIntent object in the Stripe documentation you can see that the amount parameter accepts the price in the smallest currency unit.
Amount intended to be collected by this PaymentIntent. A positive
integer representing how much to charge in the smallest currency unit
(e.g., 100 cents to charge $1.00 or 100 to charge ¥100, a zero-decimal
currency).
If you want to charge $1.00 the amount you pass to the PaymentIntent should be 100. If you want to charge $29.19 the amount you pass should be 2919.
Instead of total = total.replace('.', '') try making a int amount and multiply it by a 100 (or store the prices in the cents beforehand).

How to get auto end date based on selection of start date and no. of days of travel

I am new with Django and coding. After doing Local Library and Polls tutorial on MDN and Django respectively.
I am now working on travel itinerary app. Where I want that my model should be able to take start date as enter by user and based on number of nights selected by user should auto fill the end date.
Example:
Start Date: 09-July-21
No. of Nights: 05
End Date: 14-July-21
Code for models.py is as follows, I will be using Postgresql DB for this project
class Packages(models.Model):
title_package = models.CharField(max_length=300)
no_of_nights = models.SmallIntegerField()
summary = models.TextField(max_length=3000)
start_date = models.DateField(help_text='should not allow client to book in past')
end_date = models.DateField(help_text='based on start date selection and no. of nights client is staying.')
You can count end date on view form_valid as follows:
def form_valid(self, form):
instance = form.save(commit=False)
start_date = form.cleaned_data.get('start_date')
no_of_nights = form.cleaned_data.get('no_of_nights')
instance.end_date = start_date + timedelta(days=no_of_nights)
instance.save()

Django: How to access the previous model class instances while creating new instance of the same class?

I have a model in my django app like below:
models.py
class Profit(models.Model):
client = models.ForeignKey(Client, null=True, on_delete=models.CASCADE)
month = models.CharField(max_length=100)
amount = models.IntegerField()
total_profit = models.IntegerField()
Now, what I want to do is that whenever a new instance/object is created for this class, the user puts the month and the amount of profit for that month, But I want that it also calculates the total profit the user got up till the current profit, by adding all the profits that was being added in the past.
For example.
if the user is adding the profit for month April, then it add all the values in the amount field of previously added objects of (March, February, January and so on..) and put it in the field total_profit. So that the user can see how much total_profit he got at each new entry.
My views.py where I am printing the list of profits is given below:
views.py
class ProfitListView(ListView):
model = Profit
template_name = 'client_management_system/profit_detail.html'
context_object_name = 'profits'
# pk=self.kwargs['pk'] is to get the client id/pk from URL
def get_queryset(self):
user = get_object_or_404(Client, pk=self.kwargs['pk'])
return Profit.objects.filter(client=user)
Client is the another model in my models.py to which the Profit class is connected via ForeignKey
I also don't exactly know how to use window functions inside this view.
As stated in the comments one should generally not store things in the database that can be calculated from other data. Since that leads to duplication and then makes it difficult to update data. Although if your data might not change and this is some financial data one might store it anyway for record keeping purposes.
Firstly month as a CharField is not a very suitable field of yours for your schema. As firstly they are not easily ordered, secondly it would be better for you to work with a DateTimeField instead:
class Profit(models.Model):
month = models.CharField(max_length=100) # Remove this
made_on = models.DateTimeField() # A `DateTimeField` is better suited
amount = models.IntegerField()
total_profit = models.IntegerField()
Next since you want to print all the Profit instances along with the total amount you should use a Window function [Django docs] which will be ordered by made_on and we will also use a frame just in case that the made_on is same for two entries:
from django.db.models import F, RowRange, Sum, Window
queryset = Profit.objects.annotate(
total_amount=Window(
expression=Sum('amount'),
order_by=F('made_on').asc(),
frame=RowRange(end=0)
)
)
for profit in queryset:
print(f"Date: {profit.made_on}, Amount: {profit.amount}, Total amount: {profit.total_amount}")

Get objects in which today date lies between two dates in table

I have a django model like this
class AthleteSubscription(models.Model):
user = models.ForeignKey(User, related_name="user_subscription", default='')
subscription_start = models.DateField(default=datetime.date.today)
subscription_end = models.DateField(default=datetime.date.today() + timedelta(30))
Where subscription_start is start date of subscription and subscription_end is the end date of subscription. Subscription is of 30 days. I want to get those records in which current date (date today) lies between subscription_start and subscription_end. How can I do this with django ORM.
qv = AthleteSubscription.objects.filter(subscription_start__gte=some_date, subscription_end__lte=some_date)

Is there a 'good' way to build and organize Django models?

I am trying to build a Django App which lets small Stock Clubs easily manage and view data about their club. The issue I have run into is building elegant and logical models. I have not found any literature about a 'good' way to build models, or even a 'good' way to go about starting to plan models, so I thought I would post my models.py here and see what you think.
Do I have them built logically? Is there a better way? I'm not as concerned with the style of the code itself (it will eventually be PEP-8 compliant) as I am with the logic and elegance of the design.
To get a better idea of what the purpose is, here is a very plain-looking example of what the data contained by the models will be generating: http://www.bierfeldt.com/takestock/clubs/1/
Here is a flowchart design of what the models look like currently:
Thank you.
models.py
from django.db import models
####### Stock Models #######
class Stock(models.Model):
'''A stock whose current_price is updated every minute by a cronned script
running on the server. The current_price updating script gets all Stock objects
and runs Google Finance queries on each Stock
Stock has no relation to a particular owner, for that, see StockInstance model below'''
ticker = models.CharField(max_length=200)
current_price = models.DecimalField(max_digits=20, decimal_places=2)
def __unicode__(self):
return str(self.ticker + ">" + str(self.current_price))
class StockInstance(models.Model):
'''A middle-man model which links a Stock model to an owner (see Club model below.)
A single owner may possess multiple instances of a single stock purchased at different times
ex. December 9, 2012 - Owner buys 20 shares of AAPL at $500
December 13, 2012 - Owner buys 15 shares of AAPL at $482'''
owner = models.ForeignKey('Club')
stock = models.ForeignKey(Stock)
def current_price(self):
#Current Price of relevant stock
return self.stock.current_price
shares = models.IntegerField()
purchase_date = models.DateTimeField()
purchase_price = models.DecimalField(max_digits=20, decimal_places=2)
#if is_open is False, the instance is considered a closed position
is_open = models.BooleanField(default=True)
sell_date = models.DateTimeField(blank=True, null=True)
sell_price = models.DecimalField(max_digits=20, decimal_places=2, blank=True, null=True)
def current_value(self):
#Current value of this stock instance
#ex. $200 Current Price * 10 shares = $2000
return (self.current_price() * self.shares)
def purchase_value(self):
#Purchase value of this stock instance
#ex. $195 Purchase Price * 10 shares = $1950
return (self.purchase_price * self.shares)
def percent_gl(self):
#Percent Gained/Lost
#ex. ($2000 Current Value - $1950 Purchase Value) / ($1950 Purchase Value) = .03 (03%) Gained
return ((self.current_value() - self.purchase_value()) / (self.purchase_value()))
def amount_gl(self):
#Dollar Value Gained/Lost
#ex. $2000 Current Value - $1950 Purchase Value = $50 Gained
return (self.current_value() - self.purchase_value())
def total_percentage(self):
#Percent of Club Value (all club assets including cash) which this stock instance comprises
#ex. $2000 Current Value / $10000 Club Total Assests = .20 (20%)
return (self.current_value() / self.owner.current_value())
def __unicode__(self):
return str(str(self.shares) + str(" of ")+ str(self.stock.ticker))
####### Member Models #######
class Member(models.Model):
'''Members may belong to multiple clubs. The Member model has no relation to a club
See MemberInstance model below'''
name = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
def __unicode__(self):
return self.name
class MemberInstance(models.Model):
'''A middle-man model which links a Member model to an owner (see Club model below.)
A single member may belong to multiple clubs at the same time
ex. John has 5 shares of "Sandstone Investment Club"
John has 15 shares of "Blackwell Investment Firm"'''
owner = models.ForeignKey('Club')
member = models.ForeignKey(Member)
shares = models.DecimalField(max_digits=20, decimal_places=2)
def total_share_value(self):
#Total Dollar value of all of particular member's shares of a club
#ex. Sandstone Investment Club's Share Price is $20 and John has 5 shares
#ex. cont. $20 * 5 shares = $100 value of John's shares in Sandstone Investment Club
return (self.shares * self.owner.current_price())
def total_share_percentage(self):
#Percent of a club that a particular member owns
#ex. John has $100 of Sandstone Investment, Sandstone Investment is worth $1000
#ex. cont. $100 / $1000 = .10 (10%) John owns 10% of Sandstone Investment's Value
return (float(self.total_share_value()) / float(self.owner.current_value()))
####### Club Models #######
class Club(models.Model):
'''A Stock Club
A club has members (MemberInstance) and buys Stocks (StockInstance).
A note on the real-life purpose of stock clubs: Small-tim individual investors often do not have the
buying power to make powerful stock purchases. A single individual may not be able to buy 50 shares
of a stock priced at $500 each. This individual joins a stock club, possibly with friends, family, or co-workers.
The stock club has a number of shares that each member owns some of. The stock CLUB may own shares of many different
STOCKS, but the club only has ONE stock price--its own.'''
name = models.CharField(max_length=200)
created_at = models.DateTimeField(auto_now_add = True)
updated_at = models.DateTimeField(auto_now = True)
cash = models.DecimalField(max_digits=20, decimal_places=2)
def total_shares(self):
#The number of shares of the club that exist
#ex. John has 6 shares of the club; Bob has 4 shares of the club
#ex. cont. The club has (6+4=9) 10 total shares among its members.
shares = 0
for member in self.memberinstance_set.select_related():
shares = shares + member.shares
return shares
def current_value(self):
#The current value of the club
#The current value of each stock instance plus the club's uninvested cash
#ex. $200 from AAPL StockInstance + $400 from GOOG Instance + $20 cash = $620
value = 0
for stock in self.stockinstance_set.select_related():
if stock.is_open == True:
value = value + stock.current_value()
else:
pass
return (self.cash + value)
def current_price(self):
#The club's current share price
#The current value of the club divided by the total number of shares of the club
#ex. $620 Club Current Value / 10 Total Shares = $62 per share
return (self.current_value() / self.total_shares())
def cash_total_percentage(self):
#Percent of club's current value that is uninvested cash
return ((self.cash) / (self.current_value()))
def __unicode__(self):
return self.name
A cursory glance at your models suggests that you've got a mostly good design. A few mentions though.
MemberInstance (and other 'middle-man models') are usually named ClubMember, a name describing both sides of the relationship.
Your 'middle-man models' are examples of ManyToMany Models. You should define ManyToManyField on your models, such as members = ManyToManyField(Member, through='ClubMember') on your Club model.
I'll leave PEP-8 style comments alone as that doesn't seem to be the point of your question, however you should consider doc-strings in your methods instead of multiple single line comments to improve command line docs and introspection.
Also note that select_related should take in the fields that you want django to follow the relations on (as of django 1.5).
I'd also move your Club model higher up in the file so you don't need to reference it via 'Club' and can instead just pass the class name.
Have you read the coding styles section in the django docs?
https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/#model-style

Categories

Resources