I have a question. I recently noticed that the statuses aren't updating correctly from "new" to "active" and from "deleted" to "not visible anymore."
For example, the program should show the "new" status in January and switch to "active" in February, but instead, it's showing "new" for both January and February, and only switching to "active" in March.
The same issue is happening with the "deleted" status. It should show as "deleted" in January and change to "not visible anymore" in February. However, it's showing as "deleted" in January, February, and March, and then disappears entirely in April.
What could be causing this issue? I assume it is the wrong timestamps that were set up, but I am not sure how to redefine them.
The main issue is in production, not in development although the codes are the same.
class ReportView(View):
template_name = "reports/report.html"
def get(self, request):
context = {
'menu': get_service_menu_data(),
}
return render(request, self.template_name, context)
def post(self, request):
logger.info(f"Request: {request.method} {request.path}?{str(request.body)[str(request.body).index('&') + 1:-1]}")
form = csv_form(request.POST)
if form.is_valid():
company = form.cleaned_data.get('company')
month = form.cleaned_data.get('month')
year = form.cleaned_data.get('year')
date_from = datetime.date(int(year), int(month), 1)
date_to = datetime.date(int(year), int(month), calendar.monthrange(int(year), int(month))[1]) + datetime.timedelta(days=1)
prev_month = date_from - relativedelta(months=1)
next_month = date_to + relativedelta(months=1)
current_numbers = PhoneNumberHolder.objects.filter(
billing_group__billing_group=company,
purchased__lte=date_to
).exclude(
terminated__lt=date_from
)
prev_numbers = PhoneNumberHolder.objects.filter(
billing_group__billing_group=company,
purchased__lte=prev_month + relativedelta(months=1) - relativedelta(days=1)
).exclude(
terminated__lt=prev_month
)
next_numbers = PhoneNumberHolder.objects.filter(
billing_group__billing_group=company,
purchased__lte=next_month,
terminated__isnull=True
) | PhoneNumberHolder.objects.filter(
billing_group__billing_group=company,
purchased__lte=next_month,
terminated__gte=next_month
)
status_data = {
'new': [],
'active': [],
'deleted': [],
'port_pending': [],
}
for number in current_numbers:
was_present = prev_numbers.filter(phone_number=number.phone_number).exists()
will_be_present = next_numbers.filter(phone_number=number.phone_number).exists()
price_info = {
'country_code': number.phone_number.country_code,
'phone_number': number.phone_number.number,
'telnyx_price': None,
'our_price': number.individual_price or number.phone_number.price.price,
'status': None,
'terminated_date': number.terminated.strftime('%Y-%m-%d') if number.terminated else None
}
if number.status == number.STATUS_PORT_PENDING:
price_info['status'] = 'port_pending'
status_data['port_pending'].append(price_info)
elif not will_be_present or (number.terminated and number.terminated < next_month):
price_info['status'] = 'deleted'
status_data['deleted'].append(price_info)
else:
price_info['status'] = 'active'
status_data['active'].append(price_info)
for number in prev_numbers:
if not current_numbers.filter(phone_number=number.phone_number).exists():
price_info = {
'country_code': number.phone_number.country_code,
'phone_number': number.phone_number.number,
'telnyx_price': None,
'our_price': number.individual_price or number.phone_number.price.price,
'status': 'deleted',
'terminated_date': number.terminated.strftime('%Y-%m-%d') if number.terminated else None
}
status_data['deleted'].append(price_info)
new_numbers = next_numbers.exclude(phone_number__in=current_numbers.values_list('phone_number', flat=True))
for number in new_numbers:
price_info = {
'country_code': number.phone_number.country_code,
'phone_number': number.phone_number.number,
'telnyx_price': None,
'our_price': number.individual_price or number.phone_number.price.price,
'status': 'new',
'terminated_date': None
}
status_data['new'].append(price_info)
data = Telnyx_raw_data.objects.filter(billing_group=company,
call_start_date__range=[date_from, date_to]
).order_by('call_start_date', 'direction').values()
prices = calculate_cost(data)
all_data = zip(data, prices['final'], prices['minute'], prices['is_new'], prices['loss'])
number_prices, numbers_total = format_number_bill(company, date_to)
csv_data = {
'billing_group': company,
'date_from': str(date_from),
'date_to': str(date_to),
}
report_date = [item for item in csv_form().months if item[0] == month][0]
context = {
'menu': get_service_menu_data(),
'date': f"{year}, {report_date[1]}",
'status_data': status_data,
'data': all_data,
'call_bill_total': round(prices['total'], 5),
'csv': csv_data,
'number_bill': {
'prices': number_prices,
'total': numbers_total
},
'telnyx_prices': get_telnyx_number_prices(),
}
logger.info(f"Response: Report data collected: {csv_data['billing_group']}, {report_date[2]}")
return render(request, self.template_name, context)
Also report.html which is the html that is shown:
{% extends "Base.html" %}
{% block title %} {{ billing_group }} Ataskaita {% endblock %}
{% block content %}
<div class="container py-5 mt-5">
<div class="h1 fw-bold text-center">Ataskaita</div>
<div class="h3 fw-bold text-center">{{ csv.billing_group }}</div>
<div class="h5 fw-bold text-center">{{ date }}</div>
<div class="d-flex justify-content-between mb-3">
<a class="btn btn-outline-secondary border-0 rounded-pill px-3 back-button" href="{% url 'reports' %}">Atgal</a>
<a href="{% url 'report-csv' %}?company={{ csv.billing_group }}&date_from={{ csv.date_from }}&date_to={{ csv.date_to }}"
class="btn btn-outline-success border-0 rounded-pill px-3">
<i class="bi bi-file-earmark-spreadsheet pe-2"></i>Export to CSV
</a>
</div>
<div class="row d-flex justify-content-center">
<ul class="nav nav-tabs tabs-table-content" id="myTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="call-tab" data-bs-toggle="tab" data-bs-target="#call"
type="button" role="tab" aria-controls="call" aria-selected="true">
Skambučių ataskaita
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="number-tab" data-bs-toggle="tab" data-bs-target="#number"
type="button" role="tab" aria-controls="number" aria-selected="false">
Numerių ataskaita
</button>
</li>
</ul>
<div class="tab-content px-0" id="myTabContent">
<div class="tab-pane fade show active" id="call" role="tabpanel" aria-labelledby="call-tab">
<div class="table-responsive">
<table class="table table-sm table-striped">
<thead class="table-custom">
<tr>
<th scope="col" rowspan="2" class="align-middle text-center">Data</th>
<th scope="col" rowspan="2" class="align-middle text-center">Iš - Į</th>
<th scope="col" rowspan="2" class="align-middle text-center">Skambinta iš</th>
<th scope="col" rowspan="2" class="align-middle text-center">Tipas</th>
<th scope="col" rowspan="2" class="align-middle text-center">Skambinta į</th>
<th scope="col" rowspan="2" class="align-middle text-center">Trukmė <br> (min)</th>
<th scope="col" colspan="2" class="align-middle text-center">Min. kaina</th>
<th scope="col" colspan="2" class="align-middle text-center">Suma</th>
</tr>
<tr>
<th scope="col" class="align-middle text-center">Telnyx</th>
<th scope="col" class="align-middle text-center">Siūloma</th>
<th scope="col" class="align-middle text-center">Telnyx</th>
<th scope="col" class="align-middle text-center">Siūloma</th>
</tr>
</thead>
<tbody>
{% for call_record, final_cost, minute_cost, is_new, loss in data %}
<tr class="{% if loss %}table-custom{% endif %}">
<td class="align-middle text-center">{{ call_record.call_start_date|date:'Y-m-d H:i' }}</td>
<td class="align-middle">
<div class="d-flex align-items-center justify-content-center">
{{ call_record.originating_country }} - {{ call_record.destination_country }}
{% if is_new %}
<div class="badge bg-success rounded-circle p-1 ms-1"
data-bs-toggle="tooltip" data-bs-placement="bottom"
title="Naujas sujungimas">
<span class="visually-hidden">.</span>
</div>
{% endif %}
</div>
</td>
<td class="align-middle text-center">{{ call_record.originating_number}}</td>
{% if call_record.direction == "inbound" %}
<td class="align-middle text-center">{{ call_record.direction }}</td>
{% else %}
<td class="align-middle text-center">{{ call_record.destination_line_type }}</td>
{% endif %}
<td class="align-middle text-center">{{ call_record.destination_number }}</td>
<td class="align-middle text-center">{{ call_record.billable_time_in_minute }}</td>
<td class="align-middle text-center {% if loss %}text-danger{% endif %}">{{ call_record.cost_for_minute }}</td>
<td class="align-middle text-center">{{ minute_cost }}</td>
<td class="align-middle text-center">{{ call_record.our_cost }}</td>
<td class="align-middle text-center">{{ final_cost }}</td>
{% endfor %}
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="9"></td>
<td class="text-center fw-bold py-3 bill-total">{{ call_bill_total }}</td>
</tr>
</tfoot>
</table>
</div>
</div>
<div class="tab-pane fade" id="number" role="tabpanel" aria-labelledby="number-tab">
<div class="table-responsive">
<table class="table table-sm table-striped">
<thead class="table-custom">
<tr>
<th rowspan="2" scope="col" class="align-middle text-center">Šalis</th>
<th colspan="2" scope="col" class="align-middle text-center border-0">Kaina (vnt.)</th>
<th rowspan="2" scope="col" class="align-middle text-center">Kiekis</th>
<th rowspan="2" scope="col" class="align-middle text-center">Bendra suma</th>
</tr>
<tr>
<th scope="col" class="align-middle text-center">Telnyx</th>
<th scope="col" class="align-middle text-center">Siūloma</th>
</tr>
</thead>
<tbody>
{% for number in number_bill.prices %}
<tr>
<td class="align-middle text-center">{{ number.country_code }}</td>
<td class="align-middle text-center">
{% for price in telnyx_prices %}
{% if price.country_code == number.country_code %}
{{ price.monthly_cost }}
{% endif %}
{% endfor %}
</td>
<td class="align-middle text-center">{{ number.rate }}</td>
<td class="align-middle text-center">{{ number.quantity }}</td>
<td class="align-middle text-center">{{ number.total }}</td>
{% endfor %}
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4"></td>
<td class="text-center fw-bold py-3 bill-total">{{ number_bill.total }}</td>
</tr>
</tfoot>
</table>
<div class="mt-4">
<h5 class="fw-bold mb-3">Numerių būsenos</h5>
<div class="table-responsive">
<table class="table table-sm table-striped">
<thead class="table-custom">
<tr>
<th scope="col" rowspan="2" class="align-middle text-center">Būsena</th>
<th scope="col" rowspan="2" class="align-middle text-center">Šalis</th>
<th scope="col" rowspan="2" class="align-middle text-center">Numeriai</th>
<th scope="col" colspan="2" class="align-middle text-center border-0">Kaina (vnt.)</th>
</tr>
<tr>
<th scope="col" class="align-middle text-center">Telnyx</th>
<th scope="col" class="align-middle text-center">Siūloma</th>
</tr>
</thead>
<tbody>
{% for status, numbers in status_data.items %}
{% for number in numbers %}
<tr>
<td class="align-middle text-center">
<span class="badge {% if number.status == 'new' %}bg-success{% elif number.status == 'active' %}bg-secondary{% elif number.status == 'port_pending' %}bg-warning{% else %}bg-danger{% endif %}">
{% if number.status == 'new' %}Naujas
{% elif number.status == 'active' %}Aktyvus
{% elif number.status == 'port_pending' %}Laukiamas sujungimas
{% else %}Ištrintas{% endif %}
</span>
</td>
<td class="align-middle text-center">{{ number.country_code }}</td>
<td class="align-middle text-center">{{ number.phone_number }}</td>
<td class="align-middle text-center">
{% for price in telnyx_prices %}
{% if price.country_code == number.country_code %}
{{ price.monthly_cost }}
{% endif %}
{% endfor %}
</td>
<td class="align-middle text-center">{{ number.our_price }}</td>
</tr>
{% endfor %}
{% endfor %}
{% if not status_data.new and not status_data.active and not status_data.deleted %}
<tr>
<td colspan="4" class="text-center py-3">
<span class="text-muted text-center fst-italic">Nėra duomenų</span>
</td>
</tr>
{% endif %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}