fix(finance): ignore closed values when editing columns
All checks were successful
Deploy production / deploy (push) Successful in 11m10s

This commit is contained in:
lizerk 2026-09-14 09:42:02 +03:00
parent 7df236a094
commit 1f35009e09
2 changed files with 82 additions and 6 deletions

View File

@ -205,8 +205,10 @@ class PayrollAdminComponentDetailView(PayrollAdminAPIView):
point_base_behavior_changed = current.include_in_point_base != values[
"include_in_point_base"
] or (values["include_in_point_base"] and current.kind != values["kind"])
existing_lines = PayrollInputLine.objects.filter(component_code=code).exclude(
status=ApprovalStatus.VOIDED
existing_lines = (
PayrollInputLine.objects.filter(component_code=code)
.exclude(status=ApprovalStatus.VOIDED)
.exclude(period__status=PayrollPeriodStatus.CLOSED)
)
if scheduled_route_changed and existing_lines.exists():
_conflict(
@ -274,10 +276,16 @@ class PayrollAdminComponentDetailView(PayrollAdminAPIView):
negative_bases = []
if point_base_behavior_changed:
affected_by_period = defaultdict(set)
active_assignments = PayrollInputLine.objects.filter(
component_code=code,
status__in=[ApprovalStatus.DRAFT, ApprovalStatus.APPROVED],
).values_list("period_id", "employee_id")
active_assignments = (
PayrollInputLine.objects.filter(
component_code=code,
status__in=[ApprovalStatus.DRAFT, ApprovalStatus.APPROVED],
)
.exclude(
period__status=PayrollPeriodStatus.CLOSED,
)
.values_list("period_id", "employee_id")
)
for period_id, employee_id in active_assignments:
affected_by_period[period_id].add(employee_id)

View File

@ -1202,6 +1202,74 @@ def test_marker_routing_cannot_change_after_values_are_entered(scheduled_workspa
assert changed.json()["code"] == "COMPONENT_SCHEDULE_HAS_INPUTS"
def test_closed_values_do_not_block_changing_column_to_scheduled_change(
scheduled_workspace,
):
workspace = scheduled_workspace
manager = workspace["manager"]
employee = workspace["employee"]
client = workspace["client"]
closed_period = workspace["periods"][7]
current_period = workspace["periods"][8]
grant(manager, "publish_payroll")
created = client.post(
api_url("admin-component-list"),
{
"name": "Будущий маркер",
"kind": "earning",
"requires_reason": False,
"include_in_point_base": False,
"include_in_carryover": False,
"visible_to_employee": True,
"highlight_color": "",
"period_scope": "all",
},
format="json",
)
assert created.status_code == 201, created.content
component = created.json()
saved = set_cell(
client,
period=closed_period,
employee=employee,
component_code=component["code"],
amount="500.00",
)
assert saved.status_code == 201, saved.content
closed_period.status = "published"
closed_period.save(update_fields=["status", "updated_at"])
closed = client.post(
api_url("admin-period-close", pk=closed_period.pk),
{},
format="json",
)
assert closed.status_code == 200, closed.content
changed = client.patch(
api_url("admin-component-detail", code=component["code"]),
component_payload(
name=component["name"],
source_period=current_period,
),
format="json",
)
assert changed.status_code == 200, changed.content
assert changed.json()["kind"] == SCHEDULED_CHANGE_KIND
closed_component = next(
column
for column in period_table(client, closed_period)["component_columns"]
if column["code"] == component["code"]
)
assert closed_component["kind"] == "earning"
current_component = next(
column
for column in period_table(client, current_period)["component_columns"]
if column["code"] == component["code"]
)
assert current_component["kind"] == SCHEDULED_CHANGE_KIND
def test_closed_target_prevents_retroactive_marker_change_or_clear(
scheduled_workspace,
):