Skip to content
Snippets Groups Projects
Commit e1ddb689 authored by Neda Moeini's avatar Neda Moeini
Browse files

Add tax summary calculation and display in CSV upload page

parent edd74561
No related branches found
No related tags found
No related merge requests found
......@@ -82,12 +82,13 @@ class CSVUploadForm(forms.Form):
raise forms.ValidationError(error_message)
reader = csv.DictReader(io.StringIO(csv_content))
data_rows = list(reader)
fieldnames = reader.fieldnames or []
self._validate_headers(fieldnames)
self._load_reference_data()
errors = []
for index, row in enumerate(reader, start=1):
for index, row in enumerate(data_rows, start=1):
errors.extend(self._validate_source_and_trader_type(row, index))
errors.extend(self._validate_nominal_analysis_account(row, index))
errors.extend(self._validate_nc_cc_dep_combination_against_meo_sage_account(row, index))
......@@ -97,8 +98,31 @@ class CSVUploadForm(forms.Form):
raise forms.ValidationError(errors)
self.cleaned_data["csv_data"] = csv_content
self.cleaned_data["tax_summary"] = self._calculate_tax_summary(data_rows, fieldnames)
return file
def _calculate_tax_summary(self, rows: list[dict[str, str]], fieldnames: Sequence[str]) -> dict[str, float]:
"""Calculate a summary of tax values from the CSV data."""
tax_summary: dict[str, float] = {}
max_repeat = self._get_max_repeat(fieldnames, "TaxAnalysisTaxRate")
for row in rows:
for i in range(1, max_repeat + 1):
tax_col = f"TaxAnalysisTaxRate/{i}"
value_col = f"TaxAnalysisGoodsValueBeforeDiscount/{i}"
tax_code = row.get(tax_col)
try:
value = float(row.get(value_col, 0) or 0)
except ValueError:
value = 0.0
if tax_code:
tax_summary[tax_code] = tax_summary.get(tax_code, 0.0) + value
return tax_summary
def _load_reference_data(self: Self) -> None:
self.supplier_map = {
s.supplier_account_number: s.supplier_account_name
......
......@@ -38,7 +38,7 @@
<!-- Success Message -->
<div id="successSection"
class="hidden mt-4 mb-8 bg-green-100 border border-green-400 text-green-700 p-4 rounded-lg text-center">
class="hidden mt-4 mb-4 bg-green-100 border border-green-400 text-green-700 p-4 rounded-lg text-center">
<strong class="font-bold text-lg">Success!</strong>
<p id="successMessage" class="block mt-2 text-md"></p>
</div>
......@@ -49,6 +49,14 @@
📥 Download Updated CSV
</a>
</div>
<!-- Tax Summary -->
<div id="taxSummarySection"
class="hidden mt-4 mb-8 bg-gray-100 border border-gray-300 text-gray-800 p-4 rounded-lg text-center">
<strong class="font-bold text-lg">Tax Summary</strong>
<ul id="taxSummaryList"
class="mt-2 list-disc list-inside text-left text-sm md:text-base mx-auto max-w-md"></ul>
</div>
</div>
<script>
......@@ -64,11 +72,15 @@
const successMessage = document.getElementById('successMessage');
const downloadSection = document.getElementById('downloadSection');
const downloadLink = document.getElementById('downloadLink');
const taxSummarySection = document.getElementById('taxSummarySection');
const taxSummaryList = document.getElementById('taxSummaryList');
errorList.innerHTML = '';
successMessage.innerHTML = '';
taxSummaryList.innerHTML = '';
errorSection.classList.add('hidden');
successSection.classList.add('hidden');
taxSummarySection.classList.add('hidden');
downloadSection.classList.add('hidden');
submitBtn.disabled = true;
......@@ -93,6 +105,17 @@
successSection.classList.remove('hidden');
downloadLink.href = result.download_url;
downloadSection.classList.remove('hidden');
// Show tax summary if present
if (result.tax_summary && Object.keys(result.tax_summary).length > 0) {
taxSummaryList.innerHTML = '';
for (const [taxCode, total] of Object.entries(result.tax_summary)) {
const li = document.createElement('li');
li.textContent = `Tax Code ${taxCode}: ${total.toFixed(2)}`;
taxSummaryList.appendChild(li);
}
taxSummarySection.classList.remove('hidden');
}
} else {
errorList.innerHTML = '';
......@@ -126,20 +149,15 @@
submitBtn.disabled = false;
}
});
document.getElementById('fileInput').addEventListener('change', function () {
const errorSection = document.getElementById('errorSection');
const successSection = document.getElementById('successSection');
const downloadSection = document.getElementById('downloadSection');
const errorList = document.getElementById('errorList');
const successMessage = document.getElementById('successMessage');
// Hide previous messages and download button
errorSection.classList.add('hidden');
successSection.classList.add('hidden');
downloadSection.classList.add('hidden');
// Clear contents
errorList.innerHTML = '';
successMessage.innerHTML = '';
document.getElementById('fileInput').addEventListener('change', function () {
document.getElementById('errorSection').classList.add('hidden');
document.getElementById('successSection').classList.add('hidden');
document.getElementById('downloadSection').classList.add('hidden');
document.getElementById('taxSummarySection').classList.add('hidden');
document.getElementById('errorList').innerHTML = '';
document.getElementById('successMessage').innerHTML = '';
document.getElementById('taxSummaryList').innerHTML = '';
});
</script>
{% endblock %}
\ No newline at end of file
......@@ -64,7 +64,8 @@ class CSVUploadAPIView(APIView):
return Response({
"status": "success",
"message": "File successfully uploaded and processed.",
"download_url": reverse_lazy("export-file")
"download_url": reverse_lazy("export-file"),
"tax_summary": form.cleaned_data["tax_summary"],
}, status=status.HTTP_200_OK)
@staticmethod
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment