Skip to content

Loan extension: overdue-status recompute, localized date picker, bulk extend (#281)#284

Open
fabiodalez-dev wants to merge 3 commits into
mainfrom
feat/loan-extension-281
Open

Loan extension: overdue-status recompute, localized date picker, bulk extend (#281)#284
fabiodalez-dev wants to merge 3 commits into
mainfrom
feat/loan-extension-281

Conversation

@fabiodalez-dev

Copy link
Copy Markdown
Owner

Closes #281 (HansUwe52's loan-management report). Three parts.

1. 🐛 Overdue status stays "Overdue" after extending the due date

prestiti.stato is a stored enum. The maintenance/integrity jobs move a loan in_corso → in_ritardo one-way (nothing ever reverts it), and the Edit-Loan save (LoanRepository::update) deliberately never touches lifecycle columns — so extending an overdue loan's due date updated the date but left stato='in_ritardo', and every view renders that stored value verbatim. Hence the loan kept showing Overdue.

PrestitiController::update() now recomputes stato against the new due date (in_ritardo if past, else in_corso), scoped to the physically-out states so prenotato/da_ritirare are untouched, using DateHelper::today() (app timezone, same clock as MaintenanceService). When a loan returns to in_corso the reminder flags reset so the new window notifies afresh.

2. 🐛 Date picker always Italian for non-English UI languages

Uwe: "If a language other than English is used, the calendar is displayed in Italian." flatpickr-init.js detectAppLocale() only recognized it/en and fell through to Italian for everything else. Now vendor.js bundles the de/fr/da flatpickr l10n and registers them, detectAppLocale() maps every shipped UI language and defaults to the neutral English, and the date display is day-first for the European languages. The create-loan inline picker got the same fix. vendor.bundle.js rebuilt.

3. ✨ Bulk loan extension

Uwe: "select multiple loans or all loans and extend the loan period." New PrestitiController::bulkExtend() + POST /admin/loans/bulk-extend: extend the due date of several selected active out-loans by N days at once, recomputing stato per part 1. It deliberately mirrors the manual Edit-Loan semantics — not renew(), which refuses overdue loans and enforces the renewal limit — because the whole point is extending loans that are already overdue. The loans list gains a per-row selection checkbox (only for extendable loans), select-all, and a bulk action bar; selection persists across DataTables page draws.

Verified

  • tests/loan-extension-281.unit.php12/12 (single + bulk recompute, state scoping, reminder reset, symmetric past/future transitions).
  • A real browser bulk-extend against the running app: an active loan extended +7 days, data_scadenza advanced, stato recomputed, success flash shown.
  • PHPStan clean; new i18n keys added to all four locales (en↔de key parity + placeholder parity hold).

Note: the Danish (da_DK) calendar localization here also depends on #283 shipping the da_DK language; on an it/en/de/fr install parts 1–3 are fully self-contained.

…e picker, bulk extend

Addresses HansUwe52's loan-management report (#281) in three parts.

1. Overdue status not cleared after extending the due date.
   prestiti.stato is a stored enum, transitioned in_corso -> in_ritardo one-way
   by the maintenance/integrity jobs and never reverted, while the Edit-Loan
   save (LoanRepository::update) deliberately never touches lifecycle columns.
   So extending an overdue loan's due date left stato='in_ritardo' and it kept
   showing "Overdue". PrestitiController::update() now recomputes stato against
   the new due date (in_ritardo if past, else in_corso), scoped to the
   physically-out states so prenotato/da_ritirare are untouched, using the app
   timezone (DateHelper::today, same clock as MaintenanceService). Returning to
   in_corso also resets the reminder flags so the new window notifies afresh.

2. Date picker always Italian for non-English UI languages.
   flatpickr-init.js detectAppLocale() only recognized it/en and fell through to
   Italian, so German/French/Danish installs got an Italian calendar. vendor.js
   now bundles the de/fr/da flatpickr l10n and registers them; detectAppLocale()
   maps every shipped UI language and defaults to neutral English; date display
   is day-first for the European languages. The create-loan inline picker got
   the same fix. vendor.bundle.js rebuilt.

3. Bulk loan extension.
   New PrestitiController::bulkExtend() + POST /admin/loans/bulk-extend: extend
   the due date of several selected active out-loans by N days at once,
   recomputing stato per (1). Deliberately mirrors the manual Edit-Loan
   semantics (not renew(), which refuses overdue loans) since the point is
   extending overdue loans. The loans list gains a per-row checkbox (only for
   extendable loans), select-all, and a bulk bar; selection persists across
   DataTables page draws.

New i18n keys added to all four locales. Verified: loan-extension-281.unit.php
(12/12 — single + bulk recompute, scoping, reminder reset), a real browser
bulk-extend against the running app (loan extended +7 days, status recomputed,
success flash), PHPStan clean.
@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@fabiodalez-dev, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 35 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 63cf9eec-38f3-4f33-998a-d5be28468fad

📥 Commits

Reviewing files that changed from the base of the PR and between aae6353 and 650b286.

📒 Files selected for processing (17)
  • app/Controllers/PrestitiController.php
  • app/Routes/web.php
  • app/Views/prestiti/crea_prestito.php
  • app/Views/prestiti/index.php
  • frontend/js/flatpickr-init.js
  • frontend/js/vendor.js
  • locale/de_DE.json
  • locale/en_US.json
  • locale/fr_FR.json
  • locale/it_IT.json
  • public/assets/661.bundle.js
  • public/assets/flatpickr-init.js
  • public/assets/main.css
  • public/assets/vendor.bundle.js
  • tests/code-quality.spec.js
  • tests/loan-bulk-extension-capacity.unit.php
  • tests/loan-extension-281.unit.php
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/loan-extension-281

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…ion strings

CodeRabbit flagged %n (a dangerous C sprintf specifier PHP rejects) in the
bulk loan-extension count strings. They are only ever expanded via JS
String.replace, so no crash occurs today, but %n is a footgun if ever passed
to PHP sprintf/vsprintf. Switched to the standard %s (count) + %d (days), which
sprintf accepts and the placeholder-parity check recognizes. Keeps all shared
locales byte-identical across the open PRs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Loan Management

1 participant