Files
finanzen/app/Controllers/FormHandler.php
Markus 995e2ec111 redesign for mulituser
change validation concept (client and server)
using entities
2026-10-06 08:55:35 +02:00

196 lines
8.2 KiB
PHP

<?php namespace App\Controllers;
use App\Models\mAccounts;
use function PHPUnit\Framework\logicalXor;
use App\Models\mBills;
class FormHandler extends BaseController {
public function editForm(){
if ($this->request->is('post')) {
log_message('debug','Bills::edit: post data: '.json_encode($this->request->getPost()));
return $this->checkBillForm();
}
else
return $this->viewBill($data);
}
/**
* Prüft ob Kategorie vorhanden wenn ein Betrag eingegeben wurde, ohne Betrag und ohne Kategorie wird die Zeile ignoriert bzw. gelöscht
*/
public function _ruleBookingLineAcc($value, array $data, ?string &$error, string $field){
log_message('debug',"Bills::_ruleBookingLineAcc Typ von übergegeben Wert".gettype($value));
$index = explode('.', $field)[1];
if ($value > 0) return true;
if ($index == 0)
$error = "Kategorie fehlt";
else if ((is_numeric($data['input'][$index]) && (round($data['input'][$index],2) > 0.0)) || (is_numeric($data['output'][$index]) && (round($data['output'][$index]) > 0.0)))
$error = "Kategorie in Zeile " . $index . " fehlt";
return empty($error);
}
/**
* Prüft ob Teilbetrag vorhanden wenn eine Kategorie ausgewählt wurde, ohne Betrag und ohne Kategorie wird die Zeile ignoriert bzw. gelöscht
* auch wird geprüft dass nur Input oder Output einen Wert enthält, soll im Javascript gemacht werden wenn ordentlich läuft
*/
public function _ruleBookingLineAmount(string $value, array $data, ?string &$error, string $field){
log_message('debug',"Bills::_ruleBookingLineAmount Typ von übergegeben Wert ".gettype($value));
$index = explode('.', $field)[1];
if ((is_numeric($data['input'][$index]) && (round($data['input'][$index],2) > 0.0)) xor
(is_numeric($data['output'][$index]) && (round($data['output'][$index],2) > 0.0)))
return true;
if ((is_numeric($data['input'][$index]) && (round($data['input'][$index],2) > 0.0)) && (is_numeric($data['output'][$index]) && (round($data['output'][$index],2) > 0.0)))
$error = "Systemfehler: Nur Input oder Output darf einen Wert haben";
else if (($index == 0) && (count($data['input'])==1))
$error = "Betrag fehlt";
else if (is_numeric($data['account_id'][$index]) && ($data['account_id'][$index] > 0))
$error = "Betrag in Zeile " . $index+1 . " fehlt";
return empty($error);
}
/**
* rechnet nach ob der Virtuelle Gesamtbetrag (berechnet javascript) stimmt
*/
public function _ruleCalcAmount(string $value, array $data, ?string &$error, string $field){
$subamounts = 0.0;
foreach ($data['input'] as $i => $inp){
$subamounts = $subamounts + round(floatval($inp),2) - round(floatval($data['output'][$i]),2);
}
if (round($value,2) == round($subamounts,2))
return true;
else
$error = "Systemfehler: Amount Client ". floatval($value) . " ungleich Server Amount ". floatval($subamounts) ." Kalkulation; Diff = ".floatval($value)-floatval($subamounts);
return empty($error);
}
public function _ruleCalcTotal(string $value, array $data, ?string &$error, string $field){
log_message('debug',"Bills::_ruleCalcTotal In: ".$data['total_in']."; Out: ".$data['total_out']);
if ((is_numeric($data['total_in']) && (round($data['total_in'],2) > 0.0)) && (is_numeric($data['total_out']) && (round($data['total_out'],2) > 0.0))) {
$error = "Systemfehler: Gesamtbetrag darf nur Input oder Output sein";
// } else if ((!is_numeric($data['total_in'])) && (!is_numeric($data['total_out']))) {
// $error = "Systemfehler: Gesamtbetrag muss angegeben sein";
} else {
$total = round(floatval($data['total_in'])-floatval($data['total_out']),2);
if (($total !== round(floatval($data['amount']),2)) && (round(floatval($data['openamount']),2) == 0.0))
$error = "Systemfehler: Gesamtbetrag entspricht nicht Teilbeträgen";
}
log_message('debug',"Bills::_ruleCalcTotal Ergebnis ".$error);
return empty($error);
}
public function checkBillForm(){
$rules = [
'id'=>['required','is_natural'],
'source_id' => ['label'=>'Konto','rules'=>['required','greater_than[0]'],'errors'=>['greater_than'=>'Konto fehlt']],
'datum' => 'required',
'scheduled' => 'required',
'transfer' => 'required',
'sid.*' => ['label'=>'BuchungszeileID','rules'=>['required','is_natural']],
'receiver' => ['label'=>'Empfänger','rules'=>['required','max_length[120]'],'errors'=>['required'=>'Empfänger fehlt']],
'account_id.*' => [[$this,'_ruleBookingLineAcc']],
'input.*' => [[$this,'_ruleBookingLineAmount']],
'comment.*' => ['label'=>'Kommentar','rules'=>['max_length[150]']],
'output.*' => ['permit_empty','numeric'],
'amount' => ['required', 'numeric', [$this,'_ruleCalcAmount']],
'billfile' => ['max_size[billfile,10000]','mime_in[billfile,application/pdf,image/jpg,image/jpeg]'],
'removeBillFile' => ['max_length[50]'],
'validate' => ['required'],
'scheduledNum' =>['required_with[scheduled]','permit_empty','numeric'],
'scheduledType' =>['required_with[scheduled]','permit_empty','in_list[week,month,year]']
];
if ( 1 < count($this->request->getPost('sid')) ) {
$rules['openamount'] = ['rules'=>['numeric','equals[0.00]'], 'errors'=>['equals'=>'Restbetrag muss 0 sein']];
$rules['total_in'] = [[$this,'_ruleCalcTotal']];
$rules['total_out'] = ['required_without[total_in]','permit_empty','numeric'];
}
$data = $this->request->getPost();// filter getPost by array_keys($rules) but indexed rules not working
log_message('debug','Bills::checkBillForm: Form Data: '.json_encode($data));
if (! $this->validateData($data, $rules)){
log_message('debug','Bills::checkBillForm: validation failed: '.json_encode($data));
log_message('debug','Bills::checkBillForm: validation failed: '.json_encode($this->validator->getErrors()));
$eBooking = new \App\Entities\eBooking($data);
return $this->viewBill($eBooking, $this->validator->getErrors());
// return redirect()->back()->withInput()->with('errors', $validation->getErrors());
}
else{
log_message('debug','Bills::checkBillForm: validation success: '.json_encode($this->validator->getValidated()));
$eBooking = new \App\Entities\eBooking($this->validator->getValidated());
if ($data['scheduled'] == "0"){
$file = $this->request->getFile('billfile');
if ($file) {
if (! $file->isValid() && ($file->getError() != UPLOAD_ERR_NO_FILE)) {
throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')');
}
$eBooking->setInvoice($file);
}
}
$result = $eBooking->saveIt();
if (true !== $result) // show error of database
$this->viewBill($eBooking, $result);
$redirectURL = session('redirect_url') ?? site_url('/');
unset($_SESSION['redirect_url']);
return redirect()->to($redirectURL);
}
}
public function viewBill(\App\Entities\eBooking $fdata, $errors = NULL){
helper('form');
log_message('debug','Bills::viewBill: fdata: '.json_encode($fdata->toArray()));
$data['booking'] = $fdata->getFormData();
$data['validation'] = $errors;
return view('newBill', $data);
}
public function viewInvoice(string $filename) {
$filePath= WRITEPATH . '/uploads/'.auth()->user()->preFixDB;
$file = new \CodeIgniter\Files\File($filePath."/".$filename);
log_message('debug',$file->getMimeType());
if ($file->getMimeType() == 'application/pdf')
$this->viewPdf($filename);
else{
$imginfo = getimagesize($filePath."/".$filename);
header("Content-type: {$imginfo['mime']}");
readfile($filePath."/".$filename);
exit;
}
// return view('viewBillImg', ['filename'=>'writable/uploads/'.$filename]);
}
private function viewPdf(string $filename) {
// $view = \Config\Services::renderer();
log_message('debug',$filename);
$filePath= WRITEPATH . '/uploads/'.auth()->user()->preFixDB;
header("Cache-Control: maxage=1");
header("Pragma: public");
header('Content-type:application/pdf');
header('Content-disposition: inline; filename="'.$filename.'"');
header('content-Transfer-Encoding:binary');
header('Content-Length:' .filesize($filePath."/".$filename));
if (($pdf =file_get_contents($filePath."/".$filename)) === false)
print $filePath."/".$filename;
else
print $pdf;
exit;
}
}