{"id":353313,"date":"2026-08-24T12:30:13","date_gmt":"2026-08-24T12:30:13","guid":{"rendered":"https:\/\/fr.wordpress.org\/plugins\/sprint-dotations\/"},"modified":"2026-08-24T14:46:40","modified_gmt":"2026-08-24T14:46:40","slug":"sprint-dotations","status":"publish","type":"plugin","link":"https:\/\/gax.wordpress.org\/plugins\/sprint-dotations\/","author":23539978,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.0.0","stable_tag":"1.0.0","tested":"7.1","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Sprint Dotations","header_author":"Sprint Plugins","header_description":"Manage equipment allocations, loans, returns, deposits, inventory, and member requests.","assets_banners_color":"bdc7cd","last_updated":"2026-08-24 14:46:40","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/sprintplugins.fr\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":107,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.0.0":{"tag":"1.0.0","author":"sprintplugins","date":"2026-08-24 14:46:40","revision":3663698}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3663556,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3663556,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3663556,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3663556,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{"blueprint.json":{"filename":"blueprint.json","revision":3669030,"resolution":false,"location":"assets","locale":"","contents":"{\"$schema\":\"https:\\\/\\\/playground.wordpress.net\\\/blueprint-schema.json\",\"landingPage\":\"\\\/wp-admin\\\/admin.php?page=sprint-dotations\",\"preferredVersions\":{\"php\":\"8.3\",\"wp\":\"latest\"},\"features\":{\"networking\":true},\"steps\":[{\"step\":\"setSiteOptions\",\"options\":{\"blogname\":\"Sprint Dotations Demo\",\"blogdescription\":\"Virtual and anonymized equipment management demo\",\"permalink_structure\":\"\\\/%postname%\\\/\"}},{\"step\":\"installPlugin\",\"pluginData\":{\"resource\":\"wordpress.org\\\/plugins\",\"slug\":\"sprint-dotations\"},\"options\":{\"activate\":true}},{\"step\":\"runPHP\",\"code\":\"<?php\\nrequire_once '\\\/wordpress\\\/wp-load.php';\\nif ( ! class_exists( 'Sprint_Dotations_DB' ) ) { return; }\\n\\nif ( get_option( 'sprint_dotations_demo_seed_v1' ) ) {\\n    return;\\n}\\n\\nglobal $wpdb;\\n\\n$now       = current_time( 'mysql' );\\n$today_ts  = current_time( 'timestamp' );\\n$today     = date( 'Y-m-d', $today_ts );\\n$plus_14   = date( 'Y-m-d', strtotime( '+14 days', $today_ts ) );\\n$plus_30   = date( 'Y-m-d', strtotime( '+30 days', $today_ts ) );\\n$minus_10  = date( 'Y-m-d', strtotime( '-10 days', $today_ts ) );\\n$minus_30  = date( 'Y-m-d', strtotime( '-30 days', $today_ts ) );\\n$minus_40  = date( 'Y-m-d', strtotime( '-40 days', $today_ts ) );\\n$minus_60  = date( 'Y-m-d', strtotime( '-60 days', $today_ts ) );\\n\\nupdate_option( 'blogname', 'Sprint Dotations Demo', false );\\nupdate_option( 'blogdescription', 'Virtual and anonymized equipment management demo', false );\\nupdate_option( 'permalink_structure', '\\\/%postname%\\\/', false );\\n\\n$admin = get_user_by( 'login', 'admin' );\\n$admin_id = $admin ? (int) $admin->ID : 1;\\nif ( $admin_id ) {\\n    wp_update_user(\\n        array(\\n            'ID'           => $admin_id,\\n            'display_name' => 'Demo Admin',\\n            'nickname'     => 'Demo Admin',\\n            'user_email'   => 'admin@example.com',\\n        )\\n    );\\n}\\n\\n$create_user = static function( $login, $email, $display_name, $role, $first_name = '', $last_name = '' ) {\\n    $user = get_user_by( 'login', $login );\\n    if ( ! $user ) {\\n        $user_id = wp_create_user( $login, 'password', $email );\\n        if ( is_wp_error( $user_id ) ) {\\n            return 0;\\n        }\\n        $user = get_user_by( 'id', $user_id );\\n    }\\n    if ( ! $user ) {\\n        return 0;\\n    }\\n    wp_update_user(\\n        array(\\n            'ID'           => $user->ID,\\n            'display_name' => $display_name,\\n            'nickname'     => $display_name,\\n            'role'         => $role,\\n            'user_email'   => $email,\\n        )\\n    );\\n    if ( '' !== $first_name ) {\\n        update_user_meta( $user->ID, 'first_name', $first_name );\\n    }\\n    if ( '' !== $last_name ) {\\n        update_user_meta( $user->ID, 'last_name', $last_name );\\n    }\\n    return (int) $user->ID;\\n};\\n\\n$manager_id = $create_user( 'equipment-manager', 'equipment.manager@example.com', 'Equipment Manager', 'editor', 'Equipment', 'Manager' );\\n$alex_id    = $create_user( 'alex.carter', 'alex.carter@example.com', 'Alex Carter', 'subscriber', 'Alex', 'Carter' );\\n$chloe_id   = $create_user( 'chloe.nguyen', 'chloe.nguyen@example.com', 'Chlo\\u00e9 Nguyen', 'subscriber', 'Chlo\\u00e9', 'Nguyen' );\\n$sam_id     = $create_user( 'sam.lee', 'sam.lee@example.com', 'Sam Lee', 'subscriber', 'Sam', 'Lee' );\\n$jamie_id   = $create_user( 'jamie.martin', 'jamie.martin@example.com', 'Jamie Martin', 'subscriber', 'Jamie', 'Martin' );\\n$taylor_id  = $create_user( 'taylor.ross', 'taylor.ross@example.com', 'Taylor Ross', 'subscriber', 'Taylor', 'Ross' );\\n\\n$settings = array(\\n    'allowed_roles'             => array( 'editor' ),\\n    'role_can_delete_history'   => 1,\\n    'stock_management_enabled'  => 1,\\n    'member_requests_enabled'   => 1,\\n    'default_deposit_amount'    => 75,\\n    'default_deposit_type'      => 'Check',\\n    'document_mode'             => 'builtin',\\n    'gravity_form_id'           => 0,\\n    'gravity_form_url'          => '',\\n);\\nupdate_option( 'sprint_dotations_settings', $settings, false );\\nif ( class_exists( 'Sprint_Dotations_Settings' ) ) {\\n    Sprint_Dotations_Settings::apply_role_capabilities( $settings );\\n}\\nif ( class_exists( 'Sprint_Dotations_Display_Modes' ) ) {\\n    Sprint_Dotations_Display_Modes::update_site_default( Sprint_Dotations_Display_Modes::COMPLETE );\\n    foreach ( array( $admin_id, $manager_id ) as $user_id ) {\\n        if ( $user_id ) {\\n            Sprint_Dotations_Display_Modes::update_user_preference( Sprint_Dotations_Display_Modes::COMPLETE, $user_id );\\n        }\\n    }\\n}\\nif ( class_exists( 'Sprint_Dotations_Pages' ) ) {\\n    Sprint_Dotations_Pages::ensure_pages( true );\\n}\\n\\n$seasons_table = Sprint_Dotations_DB::seasons_table();\\n$items_table   = Sprint_Dotations_DB::items_table();\\n$loans_table   = Sprint_Dotations_DB::loans_table();\\n$logs_table    = Sprint_Dotations_DB::logs_table();\\n$templates_table = Sprint_Dotations_DB::templates_table();\\n$template_items_table = Sprint_Dotations_DB::template_items_table();\\n$requests_table = Sprint_Dotations_DB::requests_table();\\n$inventory_sessions_table = Sprint_Dotations_DB::inventory_sessions_table();\\n$inventory_lines_table = Sprint_Dotations_DB::inventory_lines_table();\\n$email_log_table = Sprint_Dotations_DB::email_log_table();\\n\\n$season_id = Sprint_Dotations_DB::default_season_id();\\nif ( ! $season_id ) {\\n    $wpdb->insert(\\n        $seasons_table,\\n        array(\\n            'name'       => 'Demo Season 2026\\u20132027',\\n            'start_date' => '2026-07-01',\\n            'end_date'   => '2027-06-30',\\n            'status'     => 'active',\\n            'is_default' => 1,\\n            'created_at' => $now,\\n            'updated_at' => $now,\\n        )\\n    );\\n    $season_id = (int) $wpdb->insert_id;\\n} else {\\n    $wpdb->update(\\n        $seasons_table,\\n        array(\\n            'name'       => 'Demo Season 2026\\u20132027',\\n            'start_date' => '2026-07-01',\\n            'end_date'   => '2027-06-30',\\n            'status'     => 'active',\\n            'is_default' => 1,\\n            'updated_at' => $now,\\n        ),\\n        array( 'id' => $season_id )\\n    );\\n}\\n\\n$items = array(\\n    array( 'Jersey \\u2013 Home',        'Apparel',     'JER-HOME', 'M', 18, 'good', 'available',      'Demo stock for adult home jerseys.' ),\\n    array( 'Jersey \\u2013 Away',        'Apparel',     'JER-AWAY', 'L', 12, 'good', 'available',      'Demo stock for adult away jerseys.' ),\\n    array( 'Training bib',         'Training',    'BIB-001',  '',  30, 'good', 'available',      'Lightweight mesh bibs.' ),\\n    array( 'Goalkeeper gloves',    'Apparel',     'GKG-002',  '9', 4,  'good', 'allocated',      'Competition gloves.' ),\\n    array( 'Travel jacket',        'Apparel',     'JKT-004',  'L', 8,  'good', 'available',      'Club travel outerwear.' ),\\n    array( 'First-aid kit',        'Medical',     'MED-003',  '',  2,  'good', 'available',      'Portable pitch-side medical kit.' ),\\n    array( 'Ball pump',            'Accessories', 'PMP-005',  '',  3,  'damaged', 'maintenance', 'One unit reported with a faulty valve.' ),\\n    array( 'Portable speaker',     'Events',      'AUD-006',  '',  1,  'good', 'allocated',      'Used for announcements during tournaments.' ),\\n    array( 'Cones set',            'Training',    'CON-007',  '',  6,  'good', 'available',      'Sets of 20 training cones.' ),\\n);\\n$item_ids = array();\\nforeach ( $items as $item ) {\\n    $wpdb->insert(\\n        $items_table,\\n        array(\\n            'name'             => $item[0],\\n            'category'         => $item[1],\\n            'reference'        => $item[2],\\n            'size'             => $item[3],\\n            'stock_quantity'   => $item[4],\\n            'condition_status' => $item[5],\\n            'availability'     => $item[6],\\n            'notes'            => $item[7],\\n            'created_at'       => $now,\\n            'updated_at'       => $now,\\n        )\\n    );\\n    $item_ids[ $item[2] ] = (int) $wpdb->insert_id;\\n}\\n\\n$insert_loan = static function( $data ) use ( $wpdb, $loans_table, $now ) {\\n    $wpdb->insert(\\n        $loans_table,\\n        array(\\n            'item_id'                  => (int) $data['item_id'],\\n            'user_id'                  => (int) $data['user_id'],\\n            'group_code'               => (string) $data['group_code'],\\n            'season_id'                => (int) $data['season_id'],\\n            'loaned_at'                => (string) $data['loaned_at'],\\n            'expected_return_at'       => $data['expected_return_at'],\\n            'initial_condition'        => $data['initial_condition'],\\n            'returned_at'              => $data['returned_at'],\\n            'return_condition'         => $data['return_condition'],\\n            'return_outcome'           => $data['return_outcome'],\\n            'status'                   => $data['status'],\\n            'notes'                    => $data['notes'],\\n            'return_notes'             => $data['return_notes'],\\n            'deposit_amount'           => (float) $data['deposit_amount'],\\n            'deposit_type'             => $data['deposit_type'],\\n            'deposit_status'           => $data['deposit_status'],\\n            'deposit_returned_amount'  => (float) $data['deposit_returned_amount'],\\n            'deposit_notes'            => $data['deposit_notes'],\\n            'created_by'               => (int) $data['created_by'],\\n            'returned_by'              => (int) $data['returned_by'],\\n            'created_at'               => $now,\\n            'updated_at'               => $now,\\n        )\\n    );\\n    return (int) $wpdb->insert_id;\\n};\\n\\n$loan_1 = $insert_loan(\\n    array(\\n        'item_id'                 => $item_ids['JER-HOME'],\\n        'user_id'                 => $alex_id,\\n        'group_code'              => 'KIT-2026-001',\\n        'season_id'               => $season_id,\\n        'loaned_at'               => $minus_30,\\n        'expected_return_at'      => $plus_30,\\n        'initial_condition'       => 'good',\\n        'returned_at'             => null,\\n        'return_condition'        => null,\\n        'return_outcome'          => '',\\n        'status'                  => 'active',\\n        'notes'                   => 'Starter kit issued for league matches.',\\n        'return_notes'            => '',\\n        'deposit_amount'          => 75,\\n        'deposit_type'            => 'Check',\\n        'deposit_status'          => 'received',\\n        'deposit_returned_amount' => 0,\\n        'deposit_notes'           => 'Security deposit recorded.',\\n        'created_by'              => $manager_id,\\n        'returned_by'             => 0,\\n    )\\n);\\n$loan_2 = $insert_loan(\\n    array(\\n        'item_id'                 => $item_ids['JKT-004'],\\n        'user_id'                 => $alex_id,\\n        'group_code'              => 'KIT-2026-001',\\n        'season_id'               => $season_id,\\n        'loaned_at'               => $minus_30,\\n        'expected_return_at'      => $plus_30,\\n        'initial_condition'       => 'good',\\n        'returned_at'             => null,\\n        'return_condition'        => null,\\n        'return_outcome'          => '',\\n        'status'                  => 'active',\\n        'notes'                   => 'Travel jacket included in starter kit.',\\n        'return_notes'            => '',\\n        'deposit_amount'          => 75,\\n        'deposit_type'            => 'Check',\\n        'deposit_status'          => 'received',\\n        'deposit_returned_amount' => 0,\\n        'deposit_notes'           => 'Covered by the group deposit.',\\n        'created_by'              => $manager_id,\\n        'returned_by'             => 0,\\n    )\\n);\\n$loan_3 = $insert_loan(\\n    array(\\n        'item_id'                 => $item_ids['GKG-002'],\\n        'user_id'                 => $sam_id,\\n        'group_code'              => 'KIT-2026-002',\\n        'season_id'               => $season_id,\\n        'loaned_at'               => $minus_40,\\n        'expected_return_at'      => $plus_14,\\n        'initial_condition'       => 'good',\\n        'returned_at'             => null,\\n        'return_condition'        => null,\\n        'return_outcome'          => '',\\n        'status'                  => 'active',\\n        'notes'                   => 'Goalkeeper equipment allocation.',\\n        'return_notes'            => '',\\n        'deposit_amount'          => 40,\\n        'deposit_type'            => 'Cash',\\n        'deposit_status'          => 'due',\\n        'deposit_returned_amount' => 0,\\n        'deposit_notes'           => 'Deposit still to be collected.',\\n        'created_by'              => $manager_id,\\n        'returned_by'             => 0,\\n    )\\n);\\n$loan_4 = $insert_loan(\\n    array(\\n        'item_id'                 => $item_ids['AUD-006'],\\n        'user_id'                 => $jamie_id,\\n        'group_code'              => 'EVT-2026-001',\\n        'season_id'               => $season_id,\\n        'loaned_at'               => $minus_10,\\n        'expected_return_at'      => $plus_14,\\n        'initial_condition'       => 'good',\\n        'returned_at'             => null,\\n        'return_condition'        => null,\\n        'return_outcome'          => '',\\n        'status'                  => 'active',\\n        'notes'                   => 'Borrowed for the summer tournament.',\\n        'return_notes'            => '',\\n        'deposit_amount'          => 0,\\n        'deposit_type'            => '',\\n        'deposit_status'          => 'none',\\n        'deposit_returned_amount' => 0,\\n        'deposit_notes'           => '',\\n        'created_by'              => $manager_id,\\n        'returned_by'             => 0,\\n    )\\n);\\n$loan_5 = $insert_loan(\\n    array(\\n        'item_id'                 => $item_ids['MED-003'],\\n        'user_id'                 => $chloe_id,\\n        'group_code'              => 'KIT-2026-003',\\n        'season_id'               => $season_id,\\n        'loaned_at'               => $minus_60,\\n        'expected_return_at'      => $minus_30,\\n        'initial_condition'       => 'good',\\n        'returned_at'             => $minus_10,\\n        'return_condition'        => 'good',\\n        'return_outcome'          => 'returned',\\n        'status'                  => 'returned',\\n        'notes'                   => 'Medical kit used during away fixtures.',\\n        'return_notes'            => 'Returned complete after inspection.',\\n        'deposit_amount'          => 20,\\n        'deposit_type'            => 'Check',\\n        'deposit_status'          => 'returned',\\n        'deposit_returned_amount' => 20,\\n        'deposit_notes'           => 'Returned in full.',\\n        'created_by'              => $manager_id,\\n        'returned_by'             => $manager_id,\\n    )\\n);\\n$loan_6 = $insert_loan(\\n    array(\\n        'item_id'                 => $item_ids['PMP-005'],\\n        'user_id'                 => $taylor_id,\\n        'group_code'              => 'KIT-2026-004',\\n        'season_id'               => $season_id,\\n        'loaned_at'               => $minus_30,\\n        'expected_return_at'      => $minus_10,\\n        'initial_condition'       => 'good',\\n        'returned_at'             => $today,\\n        'return_condition'        => 'damaged',\\n        'return_outcome'          => 'damaged',\\n        'status'                  => 'returned',\\n        'notes'                   => 'Borrowed for away training sessions.',\\n        'return_notes'            => 'Returned with a damaged valve. Follow-up required.',\\n        'deposit_amount'          => 15,\\n        'deposit_type'            => 'Cash',\\n        'deposit_status'          => 'partial',\\n        'deposit_returned_amount' => 5,\\n        'deposit_notes'           => 'Partially retained due to damage.',\\n        'created_by'              => $manager_id,\\n        'returned_by'             => $manager_id,\\n    )\\n);\\n\\n$templates = array(\\n    'Player starter kit' => array( 'JER-HOME' => 1, 'JKT-004' => 1, 'BIB-001' => 1 ),\\n    'Event field kit'    => array( 'MED-003' => 1, 'PMP-005' => 1, 'CON-007' => 1, 'AUD-006' => 1 ),\\n);\\nforeach ( $templates as $template_name => $refs ) {\\n    $wpdb->insert(\\n        $templates_table,\\n        array(\\n            'name'        => $template_name,\\n            'description' => 'An anonymized demo template for illustrating grouped allocations.',\\n            'created_by'  => $manager_id,\\n            'created_at'  => $now,\\n            'updated_at'  => $now,\\n        )\\n    );\\n    $template_id = (int) $wpdb->insert_id;\\n    foreach ( $refs as $ref => $qty ) {\\n        if ( empty( $item_ids[ $ref ] ) ) {\\n            continue;\\n        }\\n        $wpdb->insert(\\n            $template_items_table,\\n            array(\\n                'template_id' => $template_id,\\n                'item_id'     => (int) $item_ids[ $ref ],\\n                'quantity'    => (int) $qty,\\n            )\\n        );\\n    }\\n}\\n\\n$requests = array(\\n    array(\\n        'request_type'     => 'equipment_request',\\n        'status'           => 'pending',\\n        'item_id'          => $item_ids['JER-AWAY'],\\n        'loan_id'          => 0,\\n        'user_id'          => $jamie_id,\\n        'actor_user_id'    => $jamie_id,\\n        'quantity'         => 1,\\n        'message'          => 'Could I receive an away jersey in size L for the next tournament?',\\n        'metadata'         => wp_json_encode( array( 'preferred_size' => 'L' ) ),\\n        'resolution_notes' => '',\\n        'resolved_by'      => 0,\\n        'created_at'       => $now,\\n        'updated_at'       => $now,\\n        'resolved_at'      => null,\\n    ),\\n    array(\\n        'request_type'     => 'return_request',\\n        'status'           => 'approved',\\n        'item_id'          => 0,\\n        'loan_id'          => $loan_3,\\n        'user_id'          => $sam_id,\\n        'actor_user_id'    => $sam_id,\\n        'quantity'         => 1,\\n        'message'          => 'I am available next Tuesday evening to return the gloves.',\\n        'metadata'         => wp_json_encode( array( 'preferred_slot' => 'Tuesday 18:00' ) ),\\n        'resolution_notes' => 'Pickup appointment scheduled with the equipment manager.',\\n        'resolved_by'      => $manager_id,\\n        'created_at'       => $now,\\n        'updated_at'       => $now,\\n        'resolved_at'      => null,\\n    ),\\n    array(\\n        'request_type'     => 'issue_report',\\n        'status'           => 'completed',\\n        'item_id'          => 0,\\n        'loan_id'          => $loan_6,\\n        'user_id'          => $taylor_id,\\n        'actor_user_id'    => $taylor_id,\\n        'quantity'         => 1,\\n        'message'          => 'The pump lost pressure and may need repair or replacement.',\\n        'metadata'         => wp_json_encode( array( 'severity' => 'medium' ) ),\\n        'resolution_notes' => 'Item marked as damaged and partial deposit retained.',\\n        'resolved_by'      => $manager_id,\\n        'created_at'       => $now,\\n        'updated_at'       => $now,\\n        'resolved_at'      => $now,\\n    ),\\n);\\nforeach ( $requests as $request ) {\\n    $wpdb->insert( $requests_table, $request );\\n}\\n\\n$wpdb->insert(\\n    $inventory_sessions_table,\\n    array(\\n        'name'        => 'Quarterly inventory review',\\n        'inventory_date' => $today,\\n        'status'      => 'closed',\\n        'notes'       => 'Demo inventory session with anonymized counts.',\\n        'created_by'  => $manager_id,\\n        'closed_by'   => $manager_id,\\n        'created_at'  => $now,\\n        'updated_at'  => $now,\\n        'closed_at'   => $now,\\n    )\\n);\\n$inventory_id = (int) $wpdb->insert_id;\\n$inventory_lines = array(\\n    array( 'JER-HOME', 18, 1, 17, 17, 0, 0, 'ok', '' ),\\n    array( 'GKG-002', 4, 1, 3, 3, 0, 0, 'ok', '' ),\\n    array( 'PMP-005', 3, 0, 3, 2, -1, 1, 'investigate', 'One unit needs maintenance.' ),\\n);\\nforeach ( $inventory_lines as $line ) {\\n    $wpdb->insert(\\n        $inventory_lines_table,\\n        array(\\n            'inventory_id'          => $inventory_id,\\n            'item_id'               => (int) $item_ids[ $line[0] ],\\n            'theoretical_quantity'  => (int) $line[1],\\n            'active_loans'          => (int) $line[2],\\n            'expected_on_site'      => (int) $line[3],\\n            'counted_quantity'      => (int) $line[4],\\n            'difference_quantity'   => (int) $line[5],\\n            'adjust_stock'          => (int) $line[6],\\n            'resolution'            => (string) $line[7],\\n            'notes'                 => (string) $line[8],\\n            'created_at'            => $now,\\n            'updated_at'            => $now,\\n        )\\n    );\\n}\\n\\n$email_logs = array(\\n    array( 'campaign_key' => 'demo-reminder-1', 'season_id' => $season_id, 'user_id' => $alex_id,  'recipient' => 'alex.carter@example.com',  'send_type' => 'manual', 'status' => 'sent', 'subject' => 'Equipment reminder \\u2013 Demo Season 2026\\u20132027', 'error_message' => '', 'sent_at' => $now ),\\n    array( 'campaign_key' => 'demo-reminder-2', 'season_id' => $season_id, 'user_id' => $sam_id,   'recipient' => 'sam.lee@example.com',      'send_type' => 'manual', 'status' => 'sent', 'subject' => 'Deposit follow-up \\u2013 Demo Season 2026\\u20132027', 'error_message' => '', 'sent_at' => $now ),\\n    array( 'campaign_key' => 'demo-reminder-3', 'season_id' => $season_id, 'user_id' => $taylor_id,'recipient' => 'taylor.ross@example.com',  'send_type' => 'manual', 'status' => 'sent', 'subject' => 'Return incident follow-up', 'error_message' => '', 'sent_at' => $now ),\\n);\\nforeach ( $email_logs as $email_log ) {\\n    $wpdb->insert( $email_log_table, $email_log );\\n}\\n\\nif ( class_exists( 'Sprint_Dotations_DB' ) ) {\\n    Sprint_Dotations_DB::log( 'demo_seed_created', array( 'actor_user_id' => $admin_id, 'details' => array( 'note' => 'Blueprint demo content generated.' ), 'created_at' => $now ) );\\n    Sprint_Dotations_DB::log( 'loan_created', array( 'loan_id' => $loan_1, 'item_id' => $item_ids['JER-HOME'], 'user_id' => $alex_id, 'actor_user_id' => $manager_id, 'details' => array( 'group_code' => 'KIT-2026-001' ), 'created_at' => $now ) );\\n    Sprint_Dotations_DB::log( 'loan_returned', array( 'loan_id' => $loan_6, 'item_id' => $item_ids['PMP-005'], 'user_id' => $taylor_id, 'actor_user_id' => $manager_id, 'details' => array( 'outcome' => 'damaged' ), 'created_at' => $now ) );\\n}\\n\\nupdate_option(\\n    'sprint_dotations_demo_overview',\\n    array(\\n        'note' => 'This site contains virtual and anonymized demonstration content only.',\\n        'manager_page' => class_exists( 'Sprint_Dotations_Pages' ) ? Sprint_Dotations_Pages::get_page_url( 'manager' ) : '',\\n        'user_page'    => class_exists( 'Sprint_Dotations_Pages' ) ? Sprint_Dotations_Pages::get_page_url( 'user' ) : '',\\n    ),\\n    false\\n);\\n\\nupdate_option( 'sprint_dotations_demo_seed_v1', gmdate( 'c' ) );\\nflush_rewrite_rules( false );\\n\"},{\"step\":\"login\",\"username\":\"admin\",\"password\":\"password\"}]}"}},"all_blocks":[],"tagged_versions":["1.0.0"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3663556,"resolution":"1","location":"assets","locale":"","width":1586,"height":992},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3663556,"resolution":"2","location":"assets","locale":"","width":1586,"height":992},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3663556,"resolution":"3","location":"assets","locale":"","width":1586,"height":992},"screenshot-4.png":{"filename":"screenshot-4.png","revision":3663556,"resolution":"4","location":"assets","locale":"","width":1586,"height":992},"screenshot-5.png":{"filename":"screenshot-5.png","revision":3663556,"resolution":"5","location":"assets","locale":"","width":1586,"height":992}},"screenshots":{"1":"Dashboard with the main equipment, return, reminder, and allocation indicators.","2":"Equipment catalogue with availability, stock level, category, size, and condition.","3":"Allocation tracking with return deadlines, overdue items, deposits, and quick actions.","4":"Reminder campaigns and delivery monitoring.","5":"Settings, notifications, Sprint Club integration, and display modes."}},"plugin_section":[],"plugin_tags":[141027,11615,277218,6601,25730],"plugin_category":[45],"plugin_contributors":[274079],"plugin_business_model":[],"class_list":["post-353313","plugin","type-plugin","status-publish","hentry","plugin_tags-associations","plugin_tags-clubs","plugin_tags-equipment","plugin_tags-inventory","plugin_tags-loans","plugin_category-ecommerce","plugin_contributors-sprintplugins","plugin_committers-sprintplugins"],"banners":{"banner":"https:\/\/ps.w.org\/sprint-dotations\/assets\/banner-772x250.png?rev=3663556","banner_2x":"https:\/\/ps.w.org\/sprint-dotations\/assets\/banner-1544x500.png?rev=3663556","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/sprint-dotations\/assets\/icon-128x128.png?rev=3663556","icon_2x":"https:\/\/ps.w.org\/sprint-dotations\/assets\/icon-256x256.png?rev=3663556","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/sprint-dotations\/assets\/screenshot-1.png?rev=3663556","caption":"Dashboard with the main equipment, return, reminder, and allocation indicators."},{"src":"https:\/\/ps.w.org\/sprint-dotations\/assets\/screenshot-2.png?rev=3663556","caption":"Equipment catalogue with availability, stock level, category, size, and condition."},{"src":"https:\/\/ps.w.org\/sprint-dotations\/assets\/screenshot-3.png?rev=3663556","caption":"Allocation tracking with return deadlines, overdue items, deposits, and quick actions."},{"src":"https:\/\/ps.w.org\/sprint-dotations\/assets\/screenshot-4.png?rev=3663556","caption":"Reminder campaigns and delivery monitoring."},{"src":"https:\/\/ps.w.org\/sprint-dotations\/assets\/screenshot-5.png?rev=3663556","caption":"Settings, notifications, Sprint Club integration, and display modes."}],"raw_content":"<!--section=description-->\n<p>Sprint Dotations helps clubs, associations, and other organizations track equipment allocated or loaned to their members from WordPress.<\/p>\n\n<p>The plugin provides an equipment catalogue, movement history, inventory tools, and two front-end areas: a member area and an authorized manager area. It works independently and can also be grouped with other Sprint Plugins screens inside the free Sprint Club portal.<\/p>\n\n<h4>Equipment management<\/h4>\n\n<ul>\n<li>Catalog with reference, category, size, condition, availability, and stock quantity.<\/li>\n<li>Individual and bulk allocations.<\/li>\n<li>Loans, returns, losses, damage, and decommissioning.<\/li>\n<li>Reusable allocation templates.<\/li>\n<li>Optional deposit tracking.<\/li>\n<li>Seasons and expected return dates.<\/li>\n<li>Inventory sessions with stock reconciliation.<\/li>\n<li>Complete movement history and audit log.<\/li>\n<\/ul>\n\n<h4>User areas<\/h4>\n\n<ul>\n<li>Front-end equipment summary for each user.<\/li>\n<li>Front-end management area for authorized managers.<\/li>\n<li>Equipment, return, and issue requests from the member area.<\/li>\n<li>Printable equipment handover form.<\/li>\n<li>Optional integration with an existing Gravity Forms form.<\/li>\n<\/ul>\n\n<h4>Communication and administration<\/h4>\n\n<ul>\n<li>Email notifications and reminders with a delivery log.<\/li>\n<li>CSV, XLSX, and JSON exports.<\/li>\n<li>CSV and XLSX imports, plus JSON backup restoration.<\/li>\n<li>XLSX import\/export requires the PHP ZipArchive extension; CSV and JSON remain available without it.<\/li>\n<li>Diagnostic tools and Site Health integration.<\/li>\n<li>Essential, Complete, and Expert display modes.<\/li>\n<li>Compatibility with the central display mode provided by Sprint Club.<\/li>\n<\/ul>\n\n<h4>Personal data<\/h4>\n\n<p>Sprint Dotations stores relationships between WordPress user accounts and their loans, requests, emails, and equipment operations. The plugin integrates with the WordPress personal-data export and erasure tools.<\/p>\n\n<p>Active loans and unresolved requests may be retained during an erasure request so the organization can recover its equipment and complete ongoing operations. Other information is anonymized whenever possible.<\/p>\n\n<p>The plugin does not transmit data to an external service.<\/p>\n\n<h4>Data retention on uninstall<\/h4>\n\n<p>Data is retained by default to prevent accidental loss. To request complete removal, add the following constant to <code>wp-config.php<\/code> before uninstalling the plugin:<\/p>\n\n<pre><code>define( 'SPRINT_DOTATIONS_REMOVE_DATA_ON_UNINSTALL', true );\n<\/code><\/pre>\n\n<!--section=installation-->\n<ol>\n<li>Install and activate Sprint Dotations.<\/li>\n<li>Open the \u201cSprint Dotations\u201d menu in the WordPress administration area.<\/li>\n<li>Configure the current season, permissions, and stock options.<\/li>\n<li>Add equipment manually or use an import file.<\/li>\n<li>Review the front-end pages created automatically during activation.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"is%20sprint%20club%20required%3F\"><h3>Is Sprint Club required?<\/h3><\/dt>\n<dd><p>No. Sprint Dotations works independently. Sprint Club can group its screens with other plugins from the Sprint Plugins suite.<\/p><\/dd>\n<dt id=\"is%20gravity%20forms%20required%3F\"><h3>Is Gravity Forms required?<\/h3><\/dt>\n<dd><p>No. The built-in handover form works without Gravity Forms. The optional integration only lets the site use a form that already exists.<\/p><\/dd>\n<dt id=\"can%20members%20request%20equipment%3F\"><h3>Can members request equipment?<\/h3><\/dt>\n<dd><p>Yes, when this feature is enabled in the settings. It can be disabled globally.<\/p><\/dd>\n<dt id=\"what%20happens%20to%20data%20when%20the%20plugin%20is%20uninstalled%3F\"><h3>What happens to data when the plugin is uninstalled?<\/h3><\/dt>\n<dd><p>Data is retained by default. Complete removal must be explicitly enabled with the constant documented in the \u201cData retention on uninstall\u201d section.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20communicate%20with%20an%20external%20service%3F\"><h3>Does the plugin communicate with an external service?<\/h3><\/dt>\n<dd><p>No. Data remains inside the WordPress installation, apart from email messages sent through the mail system configured for the site.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial public release.<\/li>\n<\/ul>","raw_excerpt":"Manage equipment allocations, loans, returns, deposits, inventory, and member requests for a club or association.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/353313","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=353313"}],"author":[{"embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/sprintplugins"}],"wp:attachment":[{"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=353313"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=353313"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=353313"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=353313"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=353313"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/gax.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=353313"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}