How can I query item wise stocks and revenue in django ORM? - python-3.x

class RevenueStockDashboardViewset(ViewSet):
sale = InvSaleDetail.objects.filter(sale_main__sale_type='SALE')
sale_returns = InvSaleDetail.objects.filter(sale_main__sale_type='RETURN')
purchase = InvPurchaseDetail.objects.filter(purchase_main__purchase_type='PURCHASE')
purchase_returns = InvPurchaseDetail.objects.filter(purchase_main__purchase_type='RETURN')
def list(self, request):
total_revenue = (self.sale.annotate(total=Sum('sale_main__grand_total'))
.aggregate(total_revenue=Sum('total'))
.get('total_revenue') or 0) - (self.sale_returns.annotate(total=Sum('sale_main__grand_total'))
.aggregate(total_revenue=Sum('total'))
.get('total_revenue') or 0) - (self.purchase.annotate(total=Sum('purchase_main__grand_total'))
.aggregate(total_revenue=Sum('total'))
.get('total_revenue') or 0) + (self.purchase_returns.annotate(total=Sum('purchase_main__grand_total'))
.aggregate(total_revenue=Sum('total'))
.get('total_revenue') or 0)
total_stocks = (self.purchase.annotate(total=Sum('qty'))
.aggregate(total_stock=Sum('total'))
.get('total_stock') or 0) - (self.purchase_returns.annotate(total=Sum('qty'))
.aggregate(total_stocks=Sum('total'))
.get('total_stock') or 0) - (self.sale.annotate(total=Sum('qty'))
.aggregate(total_stock=Sum('total'))
.get('total_stock') or 0) - (self.sale_returns.annotate(total=Sum('qty'))
.aggregate(total_stock=Sum('total'))
.get('total_stock') or 0)
return Response(
{
'total_revenue': total_revenue,
'total_stocks': total_stocks,
# 'item_wise_stocks': items,
}
)
Item Model:
class InvItem(CreatedInfoModel):
name = models.CharField(
max_length=100,
unique=True,
help_text="Item name should be max. of 100 characters",
)
code = models.CharField(
max_length=10,
unique=True,
blank=True,
help_text="Item code should be max. of 10 characters",
)
sale models:
class InvSaleDetail(CreatedInfoModel):
sale_main = models.ForeignKey(
InvSaleMain, related_name="inv_sale_details", on_delete=models.PROTECT
)
item = models.ForeignKey(InvItem, on_delete=models.PROTECT)
item_category = models.ForeignKey(InvItemCategory, on_delete=models.PROTECT)
cost = models.DecimalField(
max_digits=12,
decimal_places=2,
help_text="cost can have max value upto=9999999999.99 and default=0.0",
)
qty = models.DecimalField(
max_digits=12,
decimal_places=2,
help_text="Purchase quantity can have max value upto=9999999999.99 and min_value=0.0",
)
sale_qty = models.DecimalField(
max_digits=12,
decimal_places=2,
help_text="Sale quantity can be max value upto 9999999999.99",
)
purchase Models:
class InvPurchaseDetail(CreatedInfoModel):
purchase_main = models.ForeignKey(
InvPurchaseMain,
related_name="purchase_details",
on_delete=models.PROTECT,
)
item = models.ForeignKey(InvItem, on_delete=models.PROTECT)
item_category = models.ForeignKey(InvItemCategory, on_delete=models.PROTECT)
purchase_cost = models.DecimalField(
max_digits=12,
decimal_places=2,
default=0.0,
help_text="purchase_cost can be max value upto 9999999999.99 and default=0.0",
)
sale_cost = models.DecimalField(
max_digits=12,
decimal_places=2,
help_text="sale_cost can be max value upto 9999999999.99 and default=0.0",
)
qty = models.DecimalField(
max_digits=12,
decimal_places=2,
help_text="Purchase quantity can be max value upto 9999999999.99",
)
I have Inventory Dashboard where I want to show the item wise revenue and item wise stocks. I have done query for total stocks and revenue but I want item wise. If you need more information. Please let me Know.
There is purchase model and sale model, the sale_main and purchase_main is basically sale and puchase info and detail is detail about items we are adding.
I want basically to fetch item wise, calculate revenue as i did and show item wise.

Related

django returning duplicates even though distinct() is used

I'm using django=4.1, python=3.8 & sqlite. What I want to do filter our the top five player points and unique players in a given month and present it in a template, there shouldn't be any duplicates. This is the PlayerPoint model:
class PlayerPoint(models.Model):
OPERATION_CHOICES = (('ADD', 'ADD'), ('SUB', 'SUBTRACT'), ('RMN', 'REMAIN'))
points = models.IntegerField(null=False, default=0)
operation = models.CharField(
max_length=3,
null=False,
choices=OPERATION_CHOICES,
default=OPERATION_CHOICES[2][0]
)
operation_amount = models.IntegerField(null=False)
operation_reason = models.CharField(null=False, max_length=1500)
player = models.ForeignKey(
settings.AUTH_USER_MODEL,
null=False,
on_delete=models.PROTECT,
to_field="phone_number",
related_name="player_points"
)
points_ts = models.DateTimeField(auto_now_add=True, null=False)
And this is the player model:
class Player(AbstractUser):
phone_number = models.CharField(
max_length=14,
unique=True,
help_text="Please ensure +251 is included"
)
first_name = models.CharField(
max_length=40,
help_text="please ensure that you've spelt it correctly"
)
father_name = models.CharField(
max_length=40,
help_text="please ensure that you've spelt it correctly"
)
grandfather_name = models.CharField(
max_length=40,
help_text="please ensure that you've spelt it correctly"
)
email = models.EmailField(
unique=True,
help_text="please ensure that the email is correct"
)
age = models.CharField(max_length=3)
profile_pic = models.ImageField(upload_to='profile_pix', default='profile_pix/placeholder.jpg')
joined_ts = models.DateTimeField(auto_now_add=True, null=False)
username = None
When I run the below query it gives me the top 5 Player Points but it's not distinct, the player_ids are duplicates. It keeps repeating the same Player.
q = PlayerPoint.objects.filter(points_ts__year=2023, points_ts__month=1, points__gte=2000)
x = q.order_by('-points')
y = x.values_list('player_id', flat=True).distinct()
print(y)
The output is: <QuerySet [('+251703445566',), ('+251703445566',), ('+251703445566',), ('+251703445566',), ('+251703445566',), ('+251703445566',)]>
As you can see it's the same phone numbers meaning the same player.
How do I fix it?
My gratitude before hand for reading and helping.

calculating percentages on a field in Django

I have the model below and I am trying to calculate the percentages of product quantities. Any help would be greatly appreciated. Thanks
model.py
class Stock(models.Model):
date = models.DateField(default=now)
product = models.CharField(max_length=100, null=True, unique=True)
quantity = models.IntegerField(default='0')
view.py
total= Stock.objects.aggregate(total_vote=Sum('quantity'))
per = Stock.objects.values('quantity')
percentage = [
{'quantity': p['quantity'], 'percentage': p['quantity'] * 100 /total}
for p in per
]

how to work with foreign key field in django

Hi Everyone i am working work django framework, where i used to upload excel file in Dailytrip table, current i get car_mumber from car table, but now i need to store car_number from Car_team table also team_id, i am storing car_id and team_id in car_team table also i need to store team_id in dailytrip table automaticlly based on car_id(car_number) i am to much confuse how to i work that, pls help me out
models.py
class Car_team(BaseModel):
team = models.ForeignKey(
Team,
models.CASCADE,
verbose_name='Team',
null=True,
)
car=models.ForeignKey(
Car,
models.CASCADE,
verbose_name='Car',
null=True)
city =models.ForeignKey(
City,
models.CASCADE,
verbose_name='City',
)
start_date=models.DateField(null=True, blank=True)
end_date=models.DateField(null=True, blank=True)
views.py
def add_payout_uber_daily_data(request):
if request.method == 'POST':
form = UberPerformanceDataForm(request.POST, request.FILES, request=request)
if form.is_valid():
date = form.cleaned_data['date']
excel_file = request.FILES['file']
df = pd.read_excel(excel_file)
is_na = pd.isna(df['Date']).sum().sum() + pd.isna(df['Name']).sum().sum() + pd.isna(df['UUID']).sum().sum() + pd.isna(df['Net Fare With Toll']).sum().sum() + pd.isna(df['Trips']).sum().sum() + pd.isna(df['Uber KMs']).sum().sum() + pd.isna(df['CashCollected']).sum().sum() + pd.isna(df['UberToll']).sum().sum() + pd.isna(df['Tips']).sum().sum() + pd.isna(df['Hours Online']).sum().sum() + pd.isna(df['Ratings']).sum().sum() + pd.isna(df['Acceptance Rate']).sum().sum() + pd.isna(df['Cancellation Rate']).sum().sum()
error_list = []
if is_na > 0:
error_list.append('Found #N/A or blank values in the sheet. Please correct and re-upload')
context = {'error_list': error_list, 'menu_payout': 'active','submenu_daily_data': 'active','form': form, }
return render(request, 'add_payout_uber_daily_data.html', context=context)
date_match = True
for d in df['Date']:
if str(d.strftime("%Y-%m-%d")) != str(date):
date_match = False
break
if not date_match:
error_list.append('Some dates are not matching in excel')
if len(error_list) > 0:
context = {'error_list': error_list, 'menu_payout': 'active','submenu_daily_data': 'active','form': form, }
return render(request, 'add_payout_uber_daily_data.html', context=context)
DailyTrip.objects.filter(date=date).update(is_active=0)
for i in df.index:
uuid = df['UUID'][i]
driver_id = None
car_id = None
fleet_id = None
manager_id = None
try:
driver = Driver.objects.get(uber_uuid=uuid)
driver_id = driver.id
except Driver.DoesNotExist:
driver_id = None
#replce car code and store car_number,car_id,team_id via car_team only this logic need to change current get car_number direct car table but we need car_number vai foriegn key
try:
car = Car.objects.get(car_number=df["Car Number"][i])
car_id = car.id
manager_id = car.manager_id
except Car.DoesNotExist:
car_id = None
try:
fleet = Fleet.objects.get(name=df["Fleet Name"][i])
fleet_id = fleet.id
except Fleet.DoesNotExist:
fleet_id = None
name = df['Name'][i]
car_number = df['Car Number'][i]
fare_total = df['Net Fare With Toll'][i]
trips = df['Trips'][i]
pool_trips = 0
hours_online = df['Hours Online'][i]
total_km = df['Uber KMs'][i]
cash_collected = abs(df['CashCollected'][i])
toll = df['UberToll'][i]
tip_amount = df['Tips'][i]
fare_avg = float(fare_total)/int(trips)
fare_per_hour_online = float(fare_total)/float(hours_online)
fare_per_km = fare_total/total_km
trips_per_hour = trips/hours_online
km_per_trip = total_km/trips
rating = df['Ratings'][i]
acceptance_rate_perc = float(df['Acceptance Rate'][i])/100
driver_cancellation_rate = float(df['Cancellation Rate'][i])/100
obj, created = DailyTrip.all_objects.update_or_create(
date=date, uuid=uuid,
defaults={
'car_id': car_id,
'manager_id': manager_id,
'car_number': car_number,
'driver_id': driver_id,
'car_id': car_id,
'fleet_id': fleet_id,
'driver_name': name,
'fare_total': fare_total,
'trips': trips,
'pool_trips': pool_trips,
'hours_online': hours_online,
'total_km': total_km,
'cash_collected': cash_collected,
'toll': toll,
'tip_amount': tip_amount,
'fare_avg': fare_avg,
'fare_per_hour_online':fare_per_hour_online,
'fare_per_km':fare_per_km,
'trips_per_hour': trips_per_hour,
'km_per_trip': km_per_trip,
'rating': rating,
'acceptance_rate_perc': acceptance_rate_perc,
'driver_cancellation_rate': driver_cancellation_rate,
'is_active': 1,
'comments': None}
)
if len(error_list) > 0:
DailyTrip.objects.filter(date=date).update(is_active=0)
context = {'error_list': error_list, 'menu_payout': 'active','submenu_daily_data': 'active','form': form, }
return render(request, 'add_payout_uber_daily_data.html', context=context)
else:
messages.success(request, 'Daily Trips added Successfully...')
return redirect('/fleet/payout/daily_data/add/uber')
else:
form = UberPerformanceDataForm(initial={})
context = {
'menu_payout': 'active',
'submenu_daily_data': 'active',
'form': form,
}
return render(request, 'add_payout_uber_daily_data.html', context=context)
You can try that :
to get car_number from car_team -->
car_team = car_team.objects.objects.all().last() # to get the last car_team for example
car_number = car_team.car.car_number # to get the car number from the car_team
try:
car = Car.objects.get(car_number=df["Car Number"][i])
car_id = car.id
car1=Car_team.objects.filter(car_id=car_id)
if car1:
team_id=car1[0].team_id
else:
team_id=None
except Car.DoesNotExist:
car_id = None
team_id= None

Assign the same value to object keys from lambda in Python (Django)

When trying to assign the same value to starting_bid and price from the Listing model in my Django project the below approach always yields different values. How can I assign the same value while still having the lambda return a random integer whenever the test runs?
tests.py
SEEDER = Seed.seeder() # from django_seed
AMOUNT = 15
MIN = 5
MAX = 84
PRICE = lambda x: random.randint(MIN, MAX)
SEEDER.add_entity(
Listing,
AMOUNT,
{
"starting_bid": PRICE,
"price": PRICE
})
SEEDER.execute()
Result:
{"starting_bid": 80, "price": 45}
Expected:
{"starting_bid": 80, "price": 80}
models.py
class Listing(models.Model):
CATEGORIES = (("LAP", "Laptop"), ("CON", "Console"), ("GAD", "Gadget"), ("GAM", "Game"), ("TEL", "TV"))
user = models.ForeignKey(User, null=True, on_delete=models.CASCADE)
title = models.CharField(max_length=64)
description = models.CharField(max_length=256)
starting_bid = models.PositiveSmallIntegerField()
price = models.PositiveSmallIntegerField()
image_url = models.URLField(max_length=200)
category = models.CharField(max_length=8, choices=CATEGORIES)
active = models.BooleanField(default=True)
_price = []
def PRICE(round = 2):
global _price
if not _price:
_price = random.randint(MIN, MAX)
_price = [_price] * round
return _price.pop()

SQLAlchemy Order joined table by field in another joined table

My project requires that Orders are split into their individual lines which can be displayed in their own views I want these views to order the lines by eta which is a value in the Order table.
I have 3 tables with a 1>1 join on tables 1&2 and a many>many join on tables 2 and 3 defined by table 4 as follows:
class Order(db.Model):
id = db.Column(db.Integer, primary_key=True)
eta = db.Column(db.DateTime())
order_lines = db.relationship('Line', backref='order', order_by=lambda: Line.id)
def __repr__(self):
return '<Order No. {}>'.format(self.increment_id)
class Line(db.Model):
id = db.Column(db.Integer, primary_key=True)
line_name = db.Column(db.String())
order_id = db.Column(db.Integer, db.ForeignKey('order.id'))
product_id = db.Column(db.String, db.ForeignKey('product.product_id'))
def __repr__(self):
return '<Line SKU: {}>'.format(self.line_sku)
class Line_view(db.Model):
id = db.Column(db.Integer, primary_key=True)
view_name = db.Column(db.String())
view_lines = relationship('Line',
secondary='line_view_join',
backref='views',
lazy='dynamic',
order_by= ***???*** ) #ordery by eta on Order table
def __repr__(self):
return '<View: {}>'.format(self.view_name)
class Line_view_join(db.Model):
__tablename__ = 'line_view_join'
id = db.Column(db.Integer(), primary_key=True)
line_id = db.Column(db.Integer(), db.ForeignKey('line.id', ondelete='CASCADE'))
view_id = db.Column(db.Integer(), db.ForeignKey('line_view.id', ondelete='CASCADE'))
I am trying to work out how to query table 3, Line_View and have the joined Lines ordered by the eta of Order table.
Such that when querying:
chosen_view = Line_view.query.filter_by(id = 1).one()
chosen_view.view_lines are ordered by Order.eta
I have Tried
class Line_view(db.Model):
id = db.Column(db.Integer, primary_key=True)
view_name = db.Column(db.String())
view_lines = relationship('Line',
secondary='line_view_join',
backref='views',
lazy='dynamic',
**order_by=lambda: asc(Line.order.eta))**
def __repr__(self):
return '<View: {}>'.format(self.view_name)
But this results in the error:
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Line.order has an attribute 'eta'
Do you need to store the Line_views in the database? If not, you can query the Lines sorted by the eta attribute of the related order. Below, I create two orders with one line each, and then query the lines sorted by the eta attribute of their order:
eta = datetime(2019,10,10)
o = Order(eta = eta)
l = Line(order=o, line_name="sample")
db.session.add(o)
db.session.add(l)
eta = datetime(2019,11,11)
o1 = Order(eta = eta)
l1 = Line(order=o1, line_name="sample1")
db.session.add(o1)
db.session.add(l1)
db.session.commit()
lines = Line.query.join(Order).order_by(Order.eta)

Resources