Skip to content

Commit 409f41b

Browse files
Merge pull request #111 from theflyingmachine/Release_2023.06
Release 2023.06
2 parents ce5a1d8 + e9f4769 commit 409f41b

File tree

15 files changed

+372
-450
lines changed

15 files changed

+372
-450
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
---
2+
name: Bug report
3+
about: Create a report to help us improve
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
**Describe the bug**
11+
A clear and concise description of what the bug is.
12+
13+
**To Reproduce**
14+
Steps to reproduce the behavior:
15+
1. Go to '...'
16+
2. Click on '....'
17+
3. Scroll down to '....'
18+
4. See error
19+
20+
**Expected behavior**
21+
A clear and concise description of what you expected to happen.
22+
23+
**Screenshots**
24+
If applicable, add screenshots to help explain your problem.
25+
26+
**Desktop (please complete the following information):**
27+
- OS: [e.g. iOS]
28+
- Browser [e.g. chrome, safari]
29+
- Version [e.g. 22]
30+
31+
**Smartphone (please complete the following information):**
32+
- Device: [e.g. iPhone6]
33+
- OS: [e.g. iOS8.1]
34+
- Browser [e.g. stock browser, safari]
35+
- Version [e.g. 22]
36+
37+
**Additional context**
38+
Add any other context about the problem here.

.github/ISSUE_TEMPLATE/custom.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
name: Custom issue template
3+
about: Describe this issue template's purpose here.
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
title: ''
5+
labels: ''
6+
assignees: ''
7+
8+
---
9+
10+
**Is your feature request related to a problem? Please describe.**
11+
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12+
13+
**Describe the solution you'd like**
14+
A clear and concise description of what you want to happen.
15+
16+
**Describe alternatives you've considered**
17+
A clear and concise description of any alternative solutions or features you've considered.
18+
19+
**Additional context**
20+
Add any other context or screenshots about the feature request here.

CONTRIBUTING.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
## MilkBasket Contributing Guidelines
2+
Welcome to the MilkBasket repository! We appreciate your interest in contributing to our project. By following these guidelines, you can help us maintain a collaborative and inclusive environment for all contributors. Please take a moment to review this document before making any contributions.
3+
4+
#### Table of ContentsTable of Contents
5+
- Code of Conduct
6+
- How to Contribute
7+
- Bug Reports
8+
- Feature Requests
9+
- Pull Requests
10+
- Style Guide
11+
- License
12+
13+
14+
#### Code of Conduct
15+
Before getting started, please read and adhere to our Code of Conduct. We expect all contributors to follow the code of conduct throughout their involvement in the project.
16+
17+
#### How to Contribute
18+
Contributions to the project can be made in the form of bug reports, feature requests, and pull requests. We value your input and appreciate the effort you put into making this project better. To contribute, follow the steps below:
19+
1. Fork the repository to your GitHub account.
20+
2. Create a new branch from the master branch. The branch name should be descriptive of the contribution you're making.
21+
3. Make your changes or additions to the codebase.
22+
4. Write unit tests, if applicable, to cover any new functionality or bug fixes.
23+
5. Ensure that your code follows our Style Guide.
24+
6. Commit your changes and provide a clear and concise commit message.
25+
7. Push your branch to your forked repository.
26+
8. Submit a pull request to the master branch of the main repository.
27+
9. Wait for the project maintainers to review your contribution. Be prepared to make necessary changes or address feedback during the review process.
28+
29+
#### Bug Reports
30+
If you encounter a bug or a problem with the project, please submit a bug report. Follow these steps to report a bug:
31+
1. Ensure that the bug hasn't been reported already by searching through the existing issues.
32+
2. If the bug hasn't been reported, open a new issue.
33+
3. Provide a descriptive title and a clear description of the bug, including steps to reproduce it.
34+
4. Include any relevant error messages or screenshots.
35+
5. Label the issue with the appropriate tags, such as "bug" and any relevant priority labels.
36+
6. Engage in the discussion if more information is needed or requested by project maintainers.
37+
38+
#### Feature Requests
39+
If you have an idea for a new feature or an enhancement to the project, you can submit a feature request. Here's how:
40+
1. Search the existing issues to ensure that the feature hasn't been requested before.
41+
2. If the feature hasn't been requested, open a new issue.
42+
3. Provide a descriptive title and a clear description of the feature or enhancement.
43+
4. Explain why the feature would be valuable and how it aligns with the project's goals.
44+
5. Label the issue with the appropriate tags, such as "feature request" and any relevant priority labels.
45+
6. Engage in the discussion if more information is needed or requested by project maintainers.
46+
47+
#### Pull Requests
48+
If you want to contribute code or documentation changes to the project, you can submit a pull request. Follow these steps:
49+
1. Ensure that there is an open issue discussing the changes you want to make. If not, open a new issue and engage in the discussion before proceeding.
50+
2. Fork the repository and create a new branch for your changes.
51+
3. Make your changes in the new branch.
52+
4. Write clear commit messages and ensure that your code follows our Style Guide.
53+
5. Include relevant tests to validate your changes, if applicable.
54+
6. Submit a pull request to the master branch of the main repository.
55+
7. Provide a concise and descriptive title for your pull request.
56+
8. Include a summary of the changes and any relevant context in the pull request description.
57+
9. Be prepared to address any feedback or change requests from project maintainers during the review process.
58+
59+
#### Style Guide
60+
To maintain consistency and readability within the project, we follow a specific coding style. Please ensure that your contributions adhere to the following guidelines:
61+
62+
1. Use consistent indentation (spaces/tabs).
63+
2. Follow the naming conventions used in the project.
64+
3. Keep code lines reasonably short (around 80 characters).
65+
4. Comment your code when necessary to enhance clarity.
66+
5. Write meaningful and descriptive variable and function names.
67+
6. Follow best practices and conventions specific to the programming language or framework used in the project.
68+
69+
#### License
70+
By contributing to the project, you agree that your contributions will be licensed under the same license as the project itself. Make sure to review the project's license before making any contributions.

SECURITY.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Security Policy
2+
3+
## Supported Versions
4+
5+
Use this section to tell people about which versions of your project are
6+
currently being supported with security updates.
7+
8+
| Version | Supported |
9+
| ------- | ------------------ |
10+
| 2023.x | :white_check_mark: |
11+
12+
## Reporting a Vulnerability
13+
14+
Use this section to tell people how to report a vulnerability.
15+
16+
Tell them where to go, how often they can expect to get an update on a
17+
reported vulnerability, what to expect if the vulnerability is accepted or
18+
declined, etc.

register/api_views.py

Lines changed: 155 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import calendar
2+
import json
23
import logging
34
from calendar import monthrange
45
from collections import defaultdict
@@ -11,6 +12,7 @@
1112
from django.db.models.functions import Coalesce
1213
from django.http import JsonResponse
1314
from django.urls import reverse
15+
from django.utils.safestring import mark_safe
1416

1517
from register.models import Customer, Payment, Tenant
1618
from register.models import Expense
@@ -21,7 +23,7 @@
2123
IncomeSerializer, PaidCustomerSerializer, CustomerProfileSerializer, TenantSerializer
2224
from register.utils import get_tenant_perf, is_last_day_of_month, get_milk_current_price, \
2325
is_transaction_revertible, customer_register_last_updated, get_active_month, \
24-
get_customer_balance_amount, get_bill_summary
26+
get_customer_balance_amount, get_bill_summary, get_customer_due_amount_by_month
2527

2628
logger = logging.getLogger()
2729

@@ -298,3 +300,155 @@ def get_profile_api(request, customer_id):
298300
'month_year': date.today().strftime("%B, %Y"),
299301
'print_bill_url': reverse('print_bill', args=[customer.id]),
300302
})
303+
304+
@login_required()
305+
def get_report_data_api(request, poll_id):
306+
"""
307+
This function returns JSON data for the Report page.
308+
"""
309+
chart_data = []
310+
d1 = date.today()
311+
percent = 0
312+
milk_delivered = ['morning-yes', 'evening-yes']
313+
twelve_month_ago = d1.replace(day=1).replace(year=d1.year - 1)
314+
# Fetch all Expenses and Incomes
315+
tenant = Q(tenant_id=request.user.id)
316+
expense_data = Expense.objects.filter(tenant).values('log_date__month',
317+
'log_date__year').annotate(
318+
expense=Sum('cost')).values('log_date__month', 'log_date__year', 'expense')
319+
320+
income_data = Income.objects.filter(tenant).values('log_date__month',
321+
'log_date__year').annotate(
322+
income=Sum('amount')).values('log_date__month', 'log_date__year', 'income')
323+
324+
# Fetch all Registers
325+
register_query = Q(tenant, schedule__in=milk_delivered, log_date__gte=twelve_month_ago)
326+
all_register_entry = Register.objects.filter(register_query)
327+
328+
for i in range(-12, 1):
329+
percent += 3.75
330+
graph_month = d1 + relativedelta(months=i)
331+
month_str = graph_month.strftime("%B-%Y")
332+
month_abbr = graph_month.strftime("%b-%y")
333+
request.session[poll_id] = f'Income and Expense ({graph_month.strftime("%B-%Y")})'
334+
request.session[f'{poll_id}_percent'] = percent
335+
request.session.save()
336+
337+
# Retrieve Expense for the current month
338+
month_expense = next((item['expense'] for item in expense_data if
339+
item['log_date__month'] == graph_month.month and item[
340+
'log_date__year'] == graph_month.year), 0)
341+
342+
# Retrieve Income for the current month
343+
month_extra_income = next((item['income'] for item in income_data if
344+
item['log_date__month'] == graph_month.month and item[
345+
'log_date__year'] == graph_month.year), 0)
346+
347+
month_register_sale = sum(
348+
[entry.quantity * entry.current_price for entry in all_register_entry if
349+
entry.log_date.month == graph_month.month and entry.log_date.year == graph_month.year]) / 1000
350+
351+
month_register_sale += month_extra_income
352+
353+
month_paid = sum(
354+
[entry.quantity * entry.current_price for entry in all_register_entry if
355+
entry.log_date.month == graph_month.month and entry.log_date.year == graph_month.year and entry.paid]) / 1000
356+
357+
month_paid += month_extra_income
358+
month_due = month_register_sale - month_paid
359+
360+
profit = float(
361+
max(month_paid - month_expense, 0)) if month_paid > month_expense else False
362+
loss = float(
363+
max(month_expense - month_paid, 0)) if month_paid <= month_expense else False
364+
365+
current_month = {
366+
"monthName": month_str,
367+
"month": month_abbr,
368+
"income": float(month_register_sale),
369+
"paid": float(month_paid),
370+
"due": float(month_due),
371+
"expense": float(month_expense),
372+
"profit": profit,
373+
"loss": loss,
374+
}
375+
chart_data.append(current_month)
376+
377+
# Get milk production over past 365 days
378+
chart_data_milk = []
379+
all_milk_production = defaultdict(
380+
int) # Using defaultdict to automatically initialize values to 0
381+
for entry in all_register_entry:
382+
all_milk_production[(entry.schedule, entry.log_date.date())] += entry.quantity
383+
384+
for i in range(-365, 1):
385+
percent += 0.123
386+
d1 = date.today()
387+
graph_day = d1 + relativedelta(days=i)
388+
request.session[poll_id] = f'Milk Production ({graph_day.strftime("%d-%B-%Y")})'
389+
request.session[f'{poll_id}_percent'] = percent
390+
request.session.save()
391+
milk_production_morning = all_milk_production[('morning-yes', graph_day)]
392+
milk_production_evening = all_milk_production[('evening-yes', graph_day)]
393+
394+
current_day = {
395+
"dayName": graph_day.strftime('%d-%B-%Y'),
396+
'milkMorning': round(float(milk_production_morning / 1000), 2),
397+
'milkEvening': round(float(milk_production_evening / 1000), 2),
398+
"milkQuantity": round(float(milk_production_morning / 1000), 2) + round(
399+
float(milk_production_evening / 1000), 2),
400+
}
401+
chart_data_milk.append(current_day)
402+
403+
percent += 5
404+
request.session[f'{poll_id}_percent'] = percent
405+
request.session.save()
406+
# Calculate all time Expenses
407+
all_time_expense = \
408+
Expense.objects.filter(tenant_id=request.user.id).aggregate(Sum('cost'))[
409+
'cost__sum'] or 0
410+
411+
# Calculate all time Income
412+
all_time_milk_income = \
413+
Payment.objects.filter(tenant_id=request.user.id).aggregate(Sum('amount'))[
414+
'amount__sum'] or 0
415+
all_time_extra_income = \
416+
Income.objects.filter(tenant_id=request.user.id).aggregate(Sum('amount'))[
417+
'amount__sum'] or 0
418+
all_time_income = all_time_milk_income + all_time_extra_income
419+
420+
# Calculate all time profit or loss
421+
is_profit = True if all_time_expense < all_time_income else False
422+
all_time_profit_or_loss = abs(all_time_income - all_time_expense)
423+
percent += 5
424+
request.session[f'{poll_id}_percent'] = percent
425+
request.session.save()
426+
due_list, due_month = get_customer_due_amount_by_month(request)
427+
context = {
428+
'graph_data': mark_safe(json.dumps(chart_data)),
429+
'table_data': chart_data,
430+
'chart_data_milk': mark_safe(json.dumps(chart_data_milk)),
431+
'all_time_expense': all_time_expense,
432+
'all_time_income': all_time_income,
433+
'is_profit': is_profit,
434+
'all_time_profit_or_loss': all_time_profit_or_loss,
435+
'due_customers': mark_safe(json.dumps(due_list)),
436+
'due_month': mark_safe(json.dumps(due_month)),
437+
}
438+
request.session[poll_id] = 'Done'
439+
request.session.save()
440+
return JsonResponse(context)
441+
442+
@login_required()
443+
def get_report_data_status_api(request, poll_id):
444+
retry = 30
445+
status = None
446+
while retry:
447+
status = {'status': request.session.get(poll_id, None),
448+
'percent': request.session.get(f'{poll_id}_percent')
449+
}
450+
if status:
451+
return JsonResponse(status)
452+
else:
453+
retry -= 1
454+
return JsonResponse(status)

register/templates/register/broadcast.html

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -128,25 +128,25 @@ <h3 className="text-center mt-2 mt-lg-5">Broadcast Bills</h3>
128128

129129
let loading_component = <div className="text-center m-xl-5 p-xl-5">
130130

131-
<div className="spinner-grow text-primary spinner-size-big" role="status">
131+
<div className="spinner-grow text-primary" role="status">
132132
<span className="sr-only">Loading...</span>
133133
</div>
134-
<div className="spinner-grow text-secondary spinner-size-big" role="status">
134+
<div className="spinner-grow text-secondary" role="status">
135135
<span className="sr-only">Loading...</span>
136136
</div>
137-
<div className="spinner-grow text-success spinner-size-big" role="status">
137+
<div className="spinner-grow text-success" role="status">
138138
<span className="sr-only">Loading...</span>
139139
</div>
140-
<div className="spinner-grow text-danger spinner-size-big" role="status">
140+
<div className="spinner-grow text-danger" role="status">
141141
<span className="sr-only">Loading...</span>
142142
</div>
143-
<div className="spinner-grow text-warning spinner-size-big" role="status">
143+
<div className="spinner-grow text-warning" role="status">
144144
<span className="sr-only">Loading...</span>
145145
</div>
146-
<div className="spinner-grow text-info spinner-size-big" role="status">
146+
<div className="spinner-grow text-info" role="status">
147147
<span className="sr-only">Loading...</span>
148148
</div>
149-
<div className="spinner-grow text-dark spinner-size-big" role="status">
149+
<div className="spinner-grow text-dark" role="status">
150150
<span className="sr-only">Loading...</span>
151151
</div>
152152
</div>;

0 commit comments

Comments
 (0)