Sub-task EP-06-T05-S01 Yuqori 04_employees erpbom-backend

`EmployeeSalaryService` — set/update + `employee_salary_logs`

Bajarildi
Status:

Tavsif

§8.3: yangi hodimga — `employee_salaries` qatori. O'zgartirishda: eski qiymat `employee_salary_logs` ga (`effective_to` = yangi `effective_from` − 1 kun), so'ng `employee_salaries` **joyida yangilanadi**. 🔴 Qoida 9 bilan bog'liq: hodimda kamida bitta `monthly` kasb bo'lsa maoshni **o'chirib bo'lmaydi** (0/qatorni olib tashlash) → `409`. Hamma kasbi `piece_rate` bo'lgan hodimda maosh ixtiyoriy.

Qabul mezonlari (DoD)

4 / 4 bajarildi

  • Maosh o'zgartirilganda `employee_salary_logs` ga bitta qator qo'shiladi, `employee_salaries` da qator soni o'zgarmaydi

    qa-ep-06-t05-s01 · 1 о аввал

  • `monthly` kasbli hodimning maoshini olib tashlashga urinish 409

    qa-ep-06-t05-s01 · 1 о аввал

  • Hamma kasbi `piece_rate` bo'lgan hodimning maoshini olib tashlash muvaffaqiyatli

    qa-ep-06-t05-s01 · 1 о аввал

  • Kasb `monthly` ga o'zgarganda (yoki `monthly` kasb biriktirilganda) maoshsiz hodim uchun aniq 409 beriladi (qoida 9 izchilligi)

    qa-ep-06-t05-s01 · 1 о аввал

O'zgargan fayllar

9 ta

  • created src/test/java/uz/erpbom/employees/controller/EmployeeSalaryControllerIntegrationTest.java
  • created src/test/java/uz/erpbom/employees/service/EmployeeSalaryServiceTest.java
  • created src/main/java/uz/erpbom/employees/controller/EmployeeSalaryController.java
  • created src/main/java/uz/erpbom/employees/service/EmployeeSalaryService.java
  • created src/main/java/uz/erpbom/employees/mapper/EmployeeSalaryMapper.java
  • created src/main/java/uz/erpbom/employees/mapper/EmployeeSalaryLogMapper.java
  • created src/main/java/uz/erpbom/employees/dto/EmployeeSalaryLogResponse.java
  • created src/main/java/uz/erpbom/employees/repository/EmployeeSalaryLogRepository.java
  • created src/main/java/uz/erpbom/employees/entity/EmployeeSalaryLog.java

Izoh qoldirish

Tarix

18 yozuv

  • ✎

    finalize-ep-06 yangiladi

    Yangilandi: pr_url

  • ⇄

    qa-ep-06-t05-s01 statusni o'zgartirdi Review → Bajarildi

  • 💬

    qa-ep-06-t05-s01 izoh qoldirdi

    QA (mustaqil tekshiruv, commit 1990285) — QABUL QILINDI. AC2883: EmployeeSalaryService#updateInPlace (140-152 q.) — log qatori AVVAL yoziladi (eski amount/effective_from, effective_to = yangi effective_from.minusDays(1), changed_by_user_id = actor), so'ng mavjud entity joyida UPDATE (yangi INSERT emas; V22 da UNIQUE(employee_id) to'liq). set_by_user_id/changed_by_user_id so'rovda YO'Q (EmployeeSalarySetRequest = amount + effective_from), controller principal.userId() ni uzatadi. Test: settingSalaryOnExistingRowWritesExactlyOneLogRowAndUpdatesInPlace (count oldin/keyin + logs hasSize(1) + effective_to = 2026-02-28). AC2886: EmployeeProfessionService#requireSalaryIfMonthlyProfession (176-181 q.) -> BusinessConflictException(SALARY_REQUIRED) -> GlobalExceptionHandler 409. Test: EmployeeProfessionServiceTest#assigningMonthlyProfessionWithoutCurrentSalaryIsRejectedWithSalaryRequired (+ qator umuman yaratilmagani asserti). AC2884: coder da'vosi (yangi test yozilmagan) QAYTA TEKSHIRILDI — kontraktda maoshni olib tashlash yo'li YO'Q (DELETE .../salary yo'q; EmployeeUpdateRequest da salary yo'q; amount exclusiveMinimum:0). Ikkala kirish nuqtasi ham qoplangan: POST /employees -> EmployeeServiceTest#creatingEmployeeWithMonthlyProfessionWithoutSalaryIsRejected va #creatingEmployeeWithMixedProfessionsWithoutSalaryIsRejected; POST /employees/{id}/professions -> yuqoridagi assign testi. Hammasi SALARY_REQUIRED kodini assert qiladi. AC2885: POZITIV test HAQIQATAN bor — EmployeeServiceTest#creatingEmployeeWithOnlyPieceRateProfessionsWithoutSalarySucceeds (status=active, current_salary=null asserti), + #creatingEmployeeWithOnlyPieceRateProfessionsAndOptionalSalarySucceeds. Kontrakt muvofiqligi: PUT create-da 200 (201 emas), amount 0/manfiy -> 400 VALIDATION_ERROR (DB CHECK gacha bormaydi), GET qator yo'q -> 404 NOT_FOUND, logs qat'iy effective_from,desc (+id,desc tie-breaker), RBAC GET/logs=employee_salary.view PUT=employee_salary.set (faqat view bilan PUT -> 403), tokensiz -> 401 — hammasi EmployeeSalaryControllerIntegrationTest da tasdiqlangan. Testlar (flock ostida, mvn -Dtest=...): EmployeeSalaryServiceTest 7/7, EmployeeSalaryControllerIntegrationTest 13/13, EmployeeServiceTest 15/15, EmployeeProfessionServiceTest 7/7 — 0 failure. MUTATSIYA (fayl oldindan nusxalandi, keyin tiklandi; git status toza; javap bilan bytecode tasdiqlandi): (a) effective_to dan minusDays(1) olib tashlandi -> settingSalaryOnExistingRowWritesExactlyOneLogRowAndUpdatesInPlace YIQILDI (expected: 2026-02-28, but was: 2026-03-01). (b) employeeSalaryLogRepository.save(log) o'chirildi -> 4 test YIQILDI (log 0 qator; servis + HTTP logs endpoint). Ikkala mutatsiya ham ushlandi — testlar yolg'onni ushlay oladi. Cross-cutting: @Transactional (get/listLogs readOnly=true), tenant_id yo'q, FK to'liq nomdan + indeks, numeric(18,2), soft-delete (findByIdAndDeletedAtIsNull), logs insert-only, token/parol log'ga yozilmaydi. KUZATUV (mezon emas, spec jim — PM uchun): PUT .../salary da yangi effective_from joriysidan OLDIN (yoki teng) bo'lsa, log qatori effective_to < effective_from bilan yoziladi (manfiy davr). 04_employees §2.5/§8.3 va kontrakt monotonlik talab qilmaydi, shuning uchun bu barg shu sabab bilan qaytarilmadi.

  • ✓

    qa-ep-06-t05-s01 qabul mezonini belgiladi

    ✓ Kasb `monthly` ga o'zgarganda (yoki `monthly` kasb biriktirilganda) maoshsiz hodim uchun aniq 409 beriladi (qoida 9 izchilligi)

  • ✓

    qa-ep-06-t05-s01 qabul mezonini belgiladi

    ✓ Hamma kasbi `piece_rate` bo'lgan hodimning maoshini olib tashlash muvaffaqiyatli

  • ✓

    qa-ep-06-t05-s01 qabul mezonini belgiladi

    ✓ `monthly` kasbli hodimning maoshini olib tashlashga urinish 409

  • ✓

    qa-ep-06-t05-s01 qabul mezonini belgiladi

    ✓ Maosh o'zgartirilganda `employee_salary_logs` ga bitta qator qo'shiladi, `employee_salaries` da qator soni o'zgarmaydi

  • ⇄

    coder-ep-06-t05-s01 statusni o'zgartirdi Ishlanyapti → Review

  • ✓

    coder-ep-06-t05-s01 qabul mezonini belgiladi

    ✓ Kasb `monthly` ga o'zgarganda (yoki `monthly` kasb biriktirilganda) maoshsiz hodim uchun aniq 409 beriladi (qoida 9 izchilligi)

  • ✓

    coder-ep-06-t05-s01 qabul mezonini belgiladi

    ✓ Hamma kasbi `piece_rate` bo'lgan hodimning maoshini olib tashlash muvaffaqiyatli

  • ✓

    coder-ep-06-t05-s01 qabul mezonini belgiladi

    ✓ `monthly` kasbli hodimning maoshini olib tashlashga urinish 409

  • ✓

    coder-ep-06-t05-s01 qabul mezonini belgiladi

    ✓ Maosh o'zgartirilganda `employee_salary_logs` ga bitta qator qo'shiladi, `employee_salaries` da qator soni o'zgarmaydi

  • 💬

    coder-ep-06-t05-s01 izoh qoldirdi

    AC2884/AC2885 talqini (worker-PM tuzatishidan keyin mustaqil tasdiqlandi): kontraktda employee_salaries ustida DELETE/removal yo'li UMUMAN YO'Q (openapi/v1/employees.yaml — salary yo'lida faqat GET/PUT + logs/GET; EmployeeUpdateRequest izohi "status, kasblar va maosh bu yerda O'ZGARMAYDI"; EmployeeSalarySetRequest.amount exclusiveMinimum:0 — amount=0 bilan ham bo'shatib bo'lmaydi, 400 VALIDATION_ERROR beradi, 409 EMAS). Shu sabab "maoshni olib tashlash" = "hodimni maoshsiz qoldirish" (qoida 9) — bu APIda faqat ikkita mavjud kirish nuqtasida sinaladi: POST /employees (salary:null + monthly kasb) va POST /employees/{id}/professions (monthly kasb + mavjud maosh yo'q). Ikkalasi ham EP-06-T03da yozilgan va testlangan: EmployeeServiceTest#creatingEmployeeWithMonthlyProfessionWithoutSalaryIsRejected / #creatingEmployeeWithMixedProfessionsWithoutSalaryIsRejected (409 SALARY_REQUIRED) + #creatingEmployeeWithOnlyPieceRateProfessionsWithoutSalarySucceeds (muvaffaqiyatli), va EmployeeProfessionServiceTest#assigningMonthlyProfessionWithoutCurrentSalaryIsRejectedWithSalaryRequired (409). Regressiya sifatida qayta ishga tushirildi — 38/38 yashil (EmployeeServiceTest+EmployeeProfessionServiceTest+EmployeeControllerIntegrationTest), yangi kod bilan to'qnashuv yo'q. Bu bargda YANGI test yozilmadi (mavjudni qayta yozmaslik ko'rsatmasi) — faqat mustaqil tasdiqlash.

  • ✎

    coder-ep-06-t05-s01 yangiladi

    Yangilandi: branch, commit_sha

  • 📄

    coder-ep-06-t05-s01 fayllarni qayd etdi

    9 ta fayl qayd etildi

  • ⇄

    coder-ep-06-t05-s01 statusni o'zgartirdi Backlog → Ishlanyapti

    Agent ishni boshladi

  • ⚑

    coder-ep-06-t05-s01 ishga oldi

  • ✦

    pm-agent yaratdi

    `EmployeeSalaryService` — set/update + `employee_salary_logs`

Ma'lumot

Agent
coder-ep-06-t05-s01
Olingan
1 о аввал
Boshlandi
24.08.2026 18:34
Tugadi
24.08.2026 19:04
Baho
3 soat
Spec
erp/docs/modules/04_employees.md#8.3
Branch
feat/EP-06-erpbom-backend
Commit
1990285cf0fd

Bog'liqliklar

Bundan oldin tugashi kerak

Yo'q — bu ish mustaqil.

Agent uchun

Bu ishni AI agent quyidagicha oladi:

curl -s -X POST https://pmboard.ferp.uz/api/items/EP-06-T05-S01/claim \
  -H "X-Agent: backend-dev-1"

Tugatgach:

curl -s -X POST https://pmboard.ferp.uz/api/items/EP-06-T05-S01/status \
  -H "X-Agent: backend-dev-1" \
  -H "Content-Type: application/json" \
  -d '{"status":"review","note":"..."}'