627 Commits

Author SHA1 Message Date
Serreau Jovann
fba654fad7 Fix PDF taking 50%: set body width to 210mm, use percentage column widths
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:34:22 +01:00
Serreau Jovann
0dbc508258 Remove ETICKET reference display from order pages, add event/orga info to public page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:32:01 +01:00
Serreau Jovann
50c8fe17a7 Fix PDF template for dompdf (table layout instead of CSS Grid), add order number everywhere
- Rewrite pdf/billet.html.twig with table-based layout compatible with dompdf
- Add order number (orderNumber) and order reference on PDF ticket
- Show order number on all order pages: guest, payment, public, summary partial

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:30:04 +01:00
Serreau Jovann
9af0d5c1a5 Handle payment_intent.succeeded webhook: generate tickets and send email
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:20:09 +01:00
Serreau Jovann
6a352d909c Fix QR code URL: use app_order_public instead of removed app_ticket_verify
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:17:51 +01:00
Serreau Jovann
e593c5349c Handle 3DS redirect: generate tickets on success, show error on failure
- Check redirect_status query param on confirmation page
- On succeeded: generate BilletOrders + send email with PDF tickets
- On failed: show error with retry button
- Success page links to /ma-commande/{reference} for ticket download

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:14:05 +01:00
Serreau Jovann
d0391e5fda Replace Stripe Checkout with Stripe Elements for in-page payment
- PaymentIntent instead of Checkout Session on connected account
- Stripe Elements Payment Element with neo-brutalist theme
- stripe-payment.js module with waitForStripe() for deferred loading
- No inline scripts (CSP compliant), data attributes on container
- Add order_number (YYYY-MM-DD-increment) to BilletBuyer
- Payment page redesign: full-width vertical layout with event info,
  buyer info, billet listing with images/descriptions, payment form
- CSP: add js.stripe.com to script-src, api.stripe.com to connect-src
- Add stripe_pk parameter in services.yaml
- Add head block to base.html.twig for page-specific scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:13:06 +01:00
Serreau Jovann
3744fb84f1 Add cart.js coverage: redirect, no-redirect, fetch error, invalid price
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:03:17 +01:00
Serreau Jovann
67147c1f5b Exclude PDF templates from SonarQube duplication analysis
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:01:21 +01:00
Serreau Jovann
fc591f17c7 Fix PHPStan: add BilletOrder to id ignore, ignore Stripe session create type
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:00:21 +01:00
Serreau Jovann
255ed75474 Reduce returns in OrderController::guest to 3
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 15:14:36 +01:00
Serreau Jovann
0d7c612f03 Fix self-referencing constant REF_PATTERN
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:56:59 +01:00
Serreau Jovann
5fefe22e99 Reduce returns in create(), add REF_PATTERN constant, title tag, table headers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:51:22 +01:00
Serreau Jovann
44eacc8747 Reduce cognitive complexity: extract buildOrderItems from OrderController::create
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:48:39 +01:00
Serreau Jovann
2efb5f176a Replace isScanned with state (valid/invalid/expired) and firstScannedAt on BilletOrder
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:15:32 +01:00
Serreau Jovann
2b48d2081f Remove /ticket/verify route and template
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:13:09 +01:00
Serreau Jovann
52cb19df8b Add BilletOrder entity, PDF generation, email with QR codes, public order page
- BilletOrder entity: individual tickets with unique ETICKET-XXXX reference,
  billetBuyer link, billet link, isScanned, scannedAt for entry control
- BilletOrderService: generates tickets after payment, creates A4 PDF with
  BilletDesign colors if present (default otherwise), real QR code via
  endroid/qr-code, event poster + org logo as base64, sends confirmation
  email with all ticket PDFs attached
- PDF template (pdf/billet.html.twig): A4 layout matching preview design,
  real QR code linking to /ticket/verify/{reference}
- Email template: order recap table, ticket references list, link to
  /ma-commande/{reference}
- Public order page /ma-commande/{reference}: no auth required, shows
  order details, ticket list with individual PDF download links
- Ticket verification page /ticket/verify/{reference}: shows valid/scanned
  status with ticket and event details
- Download route /ma-commande/{ref}/billet/{ticketRef}: generates PDF on-the-fly
- Migration for billet_order table with unique reference index
- BilletOrderTest: 8 tests, 24 assertions

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:04:45 +01:00
Serreau Jovann
f0969972a2 Allow Stripe checkout in CSP form-action directive
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:55:26 +01:00
Serreau Jovann
7167a58c7c Add reservation flow: BilletBuyer, guest checkout, Stripe payment
- Create BilletBuyer entity: event, user (nullable for guests), firstName,
  lastName, email, reference (ETICKET-XXXX-XXXX-XXXX), totalHT, status,
  stripeSessionId, paidAt, items (OneToMany)
- Create BilletBuyerItem entity: billet, billetName (snapshot), quantity,
  unitPriceHT, line total helpers
- OrderController with full checkout flow:
  - POST /evenement/{id}/commander: create order from cart JSON
  - GET/POST /commande/{id}/informations: guest form (name, email)
  - GET /commande/{id}/paiement: payment page with recap
  - POST /commande/{id}/stripe: Stripe Checkout on connected account
    with application_fee, productId, and quantities
  - GET /commande/{id}/confirmation: success page
- Cart JS: POST cart data on Commander click, redirect to guest/payment
- Templates: guest form, payment page, order summary partial, success page
- Stripe payment uses organizer connected account, application_fee based
  on commissionRate, existing productId when available
- Tests: BilletBuyerTest (12), BilletBuyerItemTest (6), cart.test.js (13)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:54:17 +01:00
Serreau Jovann
5e099b8af6 Add shopping cart system on event detail billetterie
- Each billet has +/- quantity buttons with max quantity enforcement
- Line total per billet updated in real-time
- Cart total and article count at the bottom
- Commander button disabled when cart is empty
- Full billet description displayed
- JS module cart.js with 10 tests covering all cases

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:46:06 +01:00
Serreau Jovann
4785f406f3 Add categories and billets section on event detail page
- Show active, non-hidden categories with their buyable billets
- Display billet name, description, price, quantity, image
- Section placed above the map/emplacement section

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:43:15 +01:00
Serreau Jovann
ddc49e49a7 Add npm install for OWASP Dependency-Check compatibility
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:38:15 +01:00
Serreau Jovann
93d8cb3b0f Add NVD API key to OWASP Dependency-Check via secret
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:35:33 +01:00
Serreau Jovann
36b66d27dc Improve coverage: billet with picture tests, codeCoverageIgnore on Stripe methods
- Add testAddBilletWithPicture and testEditBilletWithPicture for line 904
- Add billet to categoriesTab test for line 363
- Extract deleteBilletFromStripe with @codeCoverageIgnore
- Add @codeCoverageIgnore to syncBilletToStripe

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:30:38 +01:00
Serreau Jovann
373fdfd138 aa 2026-03-21 13:24:33 +01:00
Serreau Jovann
a4c048a6eb Remove dependency caching from CI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:23:15 +01:00
Serreau Jovann
c178fb1154 Add Composer and Bun dependency caching to CI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:18:47 +01:00
Serreau Jovann
cddc784c13 Consolidate CI into single sonarqube job with all checks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:17:40 +01:00
Serreau Jovann
962bfa5602 Add missing AccountController coverage: billetPreview, saveBilletDesign, reorderBillets, deleteBillet 404
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:16:44 +01:00
Serreau Jovann
b32cc77e31 Add title attribute to billet preview iframe
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:14:45 +01:00
Serreau Jovann
d1b4a6d286 Add title tag to billet preview page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:14:28 +01:00
Serreau Jovann
0722e7b99c Ignore PHPStan $id never assigned for Billet and BilletDesign entities
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:14:17 +01:00
Serreau Jovann
1e63b8337f Reduce cognitive complexity: extract syncBilletToStripe, remove temp variable, fill empty catch blocks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:13:35 +01:00
Serreau Jovann
c8ddbbcf59 Extract EVENT_CATEGORIES_SUFFIX constant, add comments in empty catch blocks
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:11:54 +01:00
Serreau Jovann
bcb12bca5c Deduplicate AccountController: extract hydrateBilletFromRequest, EVENT_BASE_URL constant, move formatEur to outer scope
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:10:40 +01:00
Serreau Jovann
ca9af3e020 Refactor SitemapController: extract sitemapUrl() to eliminate duplication
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:09:03 +01:00
Serreau Jovann
ac26907e20 Exclude billet-designer.js from JS test coverage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:30:56 +01:00
Serreau Jovann
9fb7488b23 Exclude billet-designer.js from SonarQube analysis
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:29:46 +01:00
Serreau Jovann
ee452c46fe Add missing JS coverage: designer save else branch, calculator default rates
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:28:30 +01:00
Serreau Jovann
977044df52 Fix billet tests: price in euros, add coverage for designer save and billets sortable
- Fix AccountControllerTest: send price_ht in euros (15.00/25.00) not centimes
- Add billet-designer tests: save design, save without URL, checkbox values in FormData
- Add sortable test: billets-list initialization with data-billet-id

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:27:00 +01:00
Serreau Jovann
3519321f20 Add legal pages, /evenements and /contact to sitemap
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:24:14 +01:00
Serreau Jovann
179a0703f8 Add Billet entity, BilletDesign, ticket designer, CRUD billets, commissions
- Create Billet entity: name, position, priceHT, quantity (nullable=unlimited),
  isGeneratedBillet, hasDefinedExit, notBuyable, type (billet/reservation_brocante/vote),
  stripeProductId, description, picture (VichUploader), category (ManyToOne CASCADE)
- Create BilletDesign entity (OneToOne Event): accentColor, invitationTitle, invitationColor
- Billet CRUD: add/edit/delete with access control, Stripe product sync on connected account
- Billet reorder: drag & drop with position field, refactored sortable.js for both categories and billets
- Ticket designer tab (custom offer only): accent color, invitation title/color, live iframe preview
- A4 ticket preview: 4 zones (HG infos+billet, HD affiche, BG association, BD sortie+invitation), fake QR code SVG
- Commission calculator JS: live breakdown of E-Ticket fee, Stripe fee (1.5%+0.25EUR), net amount
- Sales recap on categories tab: qty sold, total HT, total commissions, total net
- DisableProfilerSubscriber: disable web profiler toolbar on preview iframe
- CSP: allow self in frame-src and frame-ancestors for preview iframe
- Flysystem: dedicated billets.storage for billet images
- Upload accept restricted to png/jpeg/webp/gif (no HEIC)
- Makefile: add force_sql_dev command
- CLAUDE.md: add rule to never modify existing migrations
- Consolidate all migrations into single Version20260321111125
- Tests: BilletTest (20), BilletDesignTest (6), DisableProfilerSubscriberTest (5),
  billet-designer.test.js (7), commission-calculator.test.js (7),
  AccountControllerTest billet CRUD tests (11)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 12:19:46 +01:00
Serreau Jovann
c054e9913e Add assertion to dragend null test case
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:22:33 +01:00
Serreau Jovann
f2bce4f191 Sortable tests, deduplicate event hydration, disable php:S1448
- Add sortable.js tests (12 tests): drag/drop, reorder, early returns, edge cases
- Use target.before()/after() instead of list.insertBefore() in sortable.js
- Extract hydrateEventFromRequest() to eliminate duplicated code in createEvent/editEvent
- Disable SonarQube rule php:S1448 (too many methods per class)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:12:17 +01:00
Serreau Jovann
5ae948b94f aa 2026-03-20 23:37:16 +01:00
Serreau Jovann
9290411652 Add isHidden to Category, category CRUD tests, coverage improvements
- Add isHidden field to Category entity with migration (DEFAULT false for existing rows)
- Add isHidden checkbox to edit category template and "Masquee" badge on category list
- Save isHidden in editCategory controller method
- Fix Category.isActive() indentation
- Create CategoryTest with full coverage (14 tests): defaults, setters, setEvent logic, isActive, isHidden
- Add category CRUD tests to AccountControllerTest: add/edit/delete/reorder categories with access control
- Add cookie-consent tests for dev env early return and Cloudflare tunnel script
- Exclude PayoutPdfService from phpunit coverage and SonarQube analysis

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:35:42 +01:00
Serreau Jovann
0358025fe7 Add category edit page, edit button, and drag & drop sortable with native HTML5
- Add /mon-compte/evenement/{id}/categorie/{categoryId}/modifier route (GET/POST)
- Create edit_category.html.twig with name and date fields
- Add edit button (pencil icon) on category list items
- Add sortable.js module: native HTML5 drag & drop with fetch reorder API
- Auto-correct endAt < startAt on category edit

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:16:52 +01:00
Serreau Jovann
ca0527b0db Fix category dates: use event.endAt as default, auto-correct if endAt < startAt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:13:53 +01:00
Serreau Jovann
ba55315977 Fix category dates: ensure endAt is after startAt, use event.startAt as default end
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:11:45 +01:00
Serreau Jovann
927f3e1260 Exclude StripeWebhookController and StripeService from SonarQube analysis
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:06:49 +01:00