Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions payments/providers/cpu_ceepos.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,16 @@ def payload_add_products(self, payload, order):

Order lines that contain bought products are retrieved through order"""

def _get_ceepos_product_code(order: Order) -> str:
def _get_ceepos_product_code(order: Order, order_line: OrderLine) -> str:
"""
Get the ceepos cost center code based on the tax percentage as
ceepos has different codes for different tax percentages.
"""
resource = order.reservation.resource
return resource.unit.cost_center_code
unit_cost_center_codes = resource.unit.cost_center_code
tax = str(order_line.tax_percentage)
cost_center_code = unit_cost_center_codes.get(tax)
return cost_center_code

def _get_order_line_description(order: Order) -> str:
resource = order.reservation.resource
Expand Down Expand Up @@ -177,7 +184,7 @@ def _get_ceepos_tax_code(order_line: OrderLine) -> str:
for order_line in order_lines:
items.append(
{
"Code": _get_ceepos_product_code(order),
"Code": _get_ceepos_product_code(order, order_line),
"Amount": order_line.quantity,
"Price": price_as_sub_units(order_line.total_price),
"Description": _get_order_line_description(order),
Expand Down
31 changes: 29 additions & 2 deletions payments/tests/test_cpu_ceepos.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,33 @@ def test_payload_add_products_success(payment_provider, order_with_products):
assert "Price" in product
assert "Description" in product

@pytest.mark.parametrize(
"tax_percentage,ceepos_code",
(
(Decimal('0'), "demo_00"),
(Decimal('10.00'), "demo_10"),
(Decimal('14.00'), "demo_14"),
(Decimal('24.00'), "demo_24"),
(Decimal('25.50'), "demo_255"),
),
)
def test_payload_ceepos_product_code(payment_provider, order_with_products, tax_percentage, ceepos_code):
unit = order_with_products.reservation.resource.unit
unit.cost_center_code = {
"0.00": "demo_00",
"10.00": "demo_10",
"14.00": "demo_14",
"24.00": "demo_24",
"25.50": "demo_255"
}
unit.save()

payload = {}
order_with_products.order_lines.all().update(tax_percentage=tax_percentage)
payment_provider.payload_add_products(payload, order_with_products)

for product in payload["Products"]:
assert product["Code"] == ceepos_code

@pytest.mark.parametrize(
"tax_percentage,tax_code",
Expand All @@ -338,7 +365,7 @@ def test_payload_add_products_success(payment_provider, order_with_products):
def test_tax_code_mapping_in_qa(payment_provider, order_with_products, tax_percentage, tax_code):
"""Test the tax percentage is mapped to a correct code in qa environment"""
payload = {}

order_with_products.order_lines.all().update(tax_percentage=tax_percentage)
payment_provider.payload_add_products(payload, order_with_products)

Expand All @@ -361,7 +388,7 @@ def test_tax_code_mapping_in_production(provider_base_config, order_with_product
provider_base_config["RESPA_PAYMENTS_CEEPOS_API_URL"] = "https://shop.tampere.fi/maksu.html"
payment_provider = CPUCeeposProvider(config=provider_base_config)
payload = {}

order_with_products.order_lines.all().update(tax_percentage=tax_percentage)
payment_provider.payload_add_products(payload, order_with_products)

Expand Down
71 changes: 71 additions & 0 deletions resources/migrations/0131_alter_unit_cost_center_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
from decimal import Decimal
import django.contrib.postgres.fields.jsonb
from django.db import migrations

TAX_PERCENTAGES = [
Decimal(x)
for x in (
"0.00",
"10.00",
"14.00",
"24.00",
"25.50",
)
]

def convert_cost_center_code(apps, schema_editor):
Unit = apps.get_model('resources', 'Unit')
for unit in Unit.objects.all():
original_value = unit.cost_center_code_old
if original_value:
new_value = {str(tax): original_value for tax in TAX_PERCENTAGES}
unit.cost_center_code = new_value
unit.save(update_fields=['cost_center_code'])
print('Converting cost_center_code for unit {} from {} to {}'.format(unit.id, original_value, new_value), flush=True)


def reverse_cost_center_code(apps, schema_editor):
Unit = apps.get_model('resources', 'Unit')
for unit in Unit.objects.all():
json_value = unit.cost_center_code
# Take the first value if available (priority to 0.00%)
if json_value and isinstance(json_value, dict):
# Try to get the 0.00% value first, or fall back to any value
if "0.00" in json_value:
unit.cost_center_code_old = json_value["0.00"]
elif len(json_value) > 0:
unit.cost_center_code_old = next(iter(json_value.values()))
else:
unit.cost_center_code_old = ""
else:
unit.cost_center_code_old = ""
unit.save(update_fields=['cost_center_code_old'])
print('Reverting cost_center_code for unit {} from {} to {}'.format(unit.id, json_value, unit.cost_center_code_old), flush=True)

class Migration(migrations.Migration):

dependencies = [
('resources', '0130_resource_people_capacity_upper'),
]

operations = [
# First add a temporary field or rename existing field
migrations.RenameField(
model_name='unit',
old_name='cost_center_code',
new_name='cost_center_code_old',
),
# Add the new JSONField
migrations.AddField(
model_name='unit',
name='cost_center_code',
field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True, default=dict, verbose_name='CeePos Cost center code'),
),
# Run the data migration with reverse function
migrations.RunPython(convert_cost_center_code, reverse_cost_center_code),
# Remove the old field
migrations.RemoveField(
model_name='unit',
name='cost_center_code_old',
),
]
7 changes: 4 additions & 3 deletions resources/models/unit.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import pytz
from django.conf import settings
from django.contrib.gis.db import models
from django.contrib.postgres.fields import JSONField
from django.core.validators import MinLengthValidator
from django.db.models import Q
from django.utils import timezone
Expand Down Expand Up @@ -98,11 +99,11 @@ class Unit(ModifiableModel, AutoIdentifiedModel):
manager_email = models.EmailField(
verbose_name=_("Manager email"), max_length=100, null=True, blank=True
)
cost_center_code = models.CharField(
cost_center_code = JSONField(
verbose_name=_("CeePos Cost center code"),
max_length=100,
blank=True,
default="",
null=True,
default=dict,
)

sap_cost_center_code = models.CharField(
Expand Down
11 changes: 11 additions & 0 deletions resources/models/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,22 @@ def get_row_data(reservation, *, include_extra_fields, include_accounting_fields

return row

def get_ceepos_cost_center_code_value(unit_cost_center_codes, tax_percentage):
"""
Get CeePos cost center code value based on tax percentage
unit_cost_center_codes: unit.cost_center_code
"""
if not unit_cost_center_codes:
return ""
return unit_cost_center_codes.get(str(tax_percentage), "")


def convert_value(reservation, name):
value = reservation.get(name) or ""
if value and name in RESERVATION_DATETIME_FIELDS:
return localtime(value).replace(tzinfo=None)
if name == "cost_center_code":
return get_ceepos_cost_center_code_value(value, reservation["tax_percentage"])
return value


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ <h4>{% trans "Contact" %}</h4>
</div>
<div class="accounting">
<h4>{% trans "Accounting" %}</h4>
{% include "respa_admin/forms/_input.html" with field=form.cost_center_code %}
{% include "respa_admin/forms/_textarea_input.html" with field=form.cost_center_code %}
{% include "respa_admin/forms/_input.html" with field=form.sap_cost_center_code %}
{% include "respa_admin/forms/_input.html" with field=form.sap_sales_organization %}
{% include "respa_admin/forms/_input.html" with field=form.sap_unit_id %}
Expand Down