redesign for mulituser

change validation concept (client and server)
using entities
This commit is contained in:
Markus
2026-10-06 08:55:35 +02:00
parent 14e050e4ba
commit 995e2ec111
41 changed files with 2402 additions and 1223 deletions

View File

@@ -0,0 +1,44 @@
<?php namespace App\Controllers;
use CodeIgniter\Session\Session;
use App\Models\mAccounts;
use Config\App;
class Accounts extends BaseController {
private \App\Models\mAccounts $accounts;
public function __construct() {
$this->accounts = new mAccounts;
}
public function index(){
if ($this->request->is('post')) {
return $this->editAccount();
}
else
return $this->viewAccountsTree();
}
private function viewAccountsTree($data = array()){
helper('form');
$data = array_merge($data,$this->accounts->getTreeData());
$data['ddlist'] = $this->accounts->getDropDownList( 'all', false,true );
return view('accountstree',$data);
}
private function editAccount(){
$rules = [
'description' => 'required',
];
if (! $this->validate($rules)) {
return $this->viewAccountsTree(['errors'=>$this->validator->getErrors()]);
}
$saveDB = array();
if ($this->accounts->saveAccount($this->request->getPost()))
$saveDB = ['mode'=>'alert-success','message'=>'Erfolgreich gespeichert'];
else
$saveDB = ['mode'=>'alert-danger','message'=>'Speichern fehlgeschlagen'];
return $this->viewAccountsTree(['saveDB'=>$saveDB]);
}
};

View File

@@ -1,71 +0,0 @@
<?php
namespace App\Controllers;
use App\Models\mBills;
use CodeIgniter\Session\Session;
class Ajax extends BaseController
{
protected $session;
public function __construct()
{
$this->session = service('session');
}
public function getTabelData(){
if (!$this->request->isAJAX()) return;
$billing = model('App\Models\mBills');
$start = $this->request->getPost('datum_start')??session('datum_start');
$ende = $this->request->getPost('datum_ende')??session('datum_ende');
$src = intval($this->request->getPost('source')) ?? 0;
$_SESSION['datum_start'] = $start;
$_SESSION['datum_ende'] = $ende;
$_SESSION['source'] = $src;
$result = $billing->getEntriesDet($start,$ende,$src);
return json_encode($result);
}
public function getAccountsBalance(){
if (!$this->request->isAJAX()) return;
$billing = model('App\Models\mBills');
return json_encode($billing->getAccountsBalance());
}
public function getScheduledData(){
if (!$this->request->isAJAX()) return;
$scheduled = model('App\Models\mScheduled');
return json_encode($scheduled->getEntries());
}
public function getToDosData(){
if (!$this->request->isAJAX()) return;
$billing = model('App\Models\mBills');
return json_encode($billing->getToDos());
}
public function getOverviewData(){
if (!$this->request->isAJAX()) return;
$billing = model('App\Models\mBills');
$result = $billing->getEntries();
return json_encode($result);
}
public function deleteBill(){
if (!$this->request->isAJAX()) return;
$bills = model('App\Models\mBills');
$bills->deleteEntry($this->request->getPost('id'));
return json_encode(["result"=>"done"]);
}
public function deleteScheduled(){
if (!$this->request->isAJAX()) return;
$scheduled = model('App\Models\mScheduled');
$scheduled->delete($this->request->getPost('id'));
return json_encode(["result"=>"done"]);
}
}
?>

90
app/Controllers/Bills.php Normal file
View File

@@ -0,0 +1,90 @@
<?php namespace App\Controllers;
use App\Models\mAccounts;
use function PHPUnit\Framework\logicalXor;
use App\Models\mBills;
use CodeIgniter\API\ResponseTrait;
include_once (dirname(__FILE__) . "/FormHandler.php");
class Bills extends FormHandler {
use ResponseTrait;
public function __construct() {
}
public function edit(int $id, bool $transfer=false){
if ($id == 0){ // erstellen eines leeren Formular
log_message('debug','Bills::edit: new bill');
$eBooking = new \App\Entities\eBooking();
$eBooking->transfer = $transfer;
$eBooking->scheduled = false;
$data = $eBooking->getNew();
} else {
$billModel = model(mBills::class);
$bill = $billModel->find($id); /* @var \App\Entity\eBooking $bill */
$bill->datum = date( "Y-m-d", strtotime( $bill->datum ));
$data = $bill->fillDetails();
log_message('debug','Bills::edit:ID:'.$id.'; Data: '.json_encode($bill->toArray()));
}
return $this->viewBill($data);
}
public function viewActivities(){
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
$data = array();
$data['source'] = 0;
$data['start'] = session('datum_start') ?? date("Y-m-d", strtotime( "- 2 weeks", strtotime( "now" ) ));
$data['ende'] = session('datum_ende') ?? date("Y-m-d", strtotime( "now" ) );
$data['source'] = session('source') ?? 0;
$data['sourcelist'] = $accounts->getDropDownList( 'all', true );
return view('activities', $data);
}
public function getOverviewData(){
if (!$this->request->isAJAX()) return;
$billing = model('App\Models\mBills');
$result = $billing->getEntries(10);
return json_encode($result);
}
public function getActivitiesData(){
if (!$this->request->isAJAX()) return;
$billing = model('App\Models\mBills');
$start = $this->request->getPost('datum_start')??session('datum_start');
$ende = $this->request->getPost('datum_ende')??session('datum_ende');
$src = intval($this->request->getPost('source'));
$_SESSION['datum_start'] = $start;
$_SESSION['datum_ende'] = $ende;
$_SESSION['source'] = $src;
$result = $billing->getEntriesDet($start,$ende,$src);
return json_encode($result);
}
public function delete(){
if ($this->request->is('post')) {
if (!ctype_digit($this->request->getPost("id"))) return $this->failForbidden("Ungültige ID");
log_message('debug',"delete id: ".$this->request->getPost("id"));
$billModel = model(mBills::class);
$result = $billModel->deleteEntry(intval($this->request->getPost("id")));
if ($result !== true)
return $this->fail("Database error ".$result);
else
return $this->respondDeleted(['url'=>session('redirect_url') ?? site_url('/'),'ID'=>$this->request->getPost("id")]);
}
return $this->failUnauthorized("Schäm Dich");
}
public function getToDosData(){
if (!$this->request->isAJAX()) return;
$billing = model('App\Models\mBills');
return json_encode($billing->getToDos());
}
public function getAccountsBalance(){
if (!$this->request->isAJAX()) return;
$billing = model('App\Models\mBills');
return json_encode($billing->getAccountsBalance());
}
}

View File

@@ -10,26 +10,32 @@ class Charts extends BaseController {
$this->db = \Config\Database::connect();
}
public function getData($id){
public function getData(int $id){
if ($id == 0)
return $this->getAllData();
else
return $this->getDetailData($id);
}
private function getDetailData($id){
private function getDetailData(int $id){
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
$bills = model('App\Models\mBills'); /* @var \App\Models\mBills $bills */
$billDet = model('App\Models\mBillDetails'); /* @var \App\Models\mBills $billDet */
$accTable = $accounts->getTable();
$billTable = $bills->getTable();
$billDetTable = $billDet->getTable();
$jetzt = date('Y-m-01');
$query = <<<EOD
SELECT
SUM(subamount)*(-1) AS Amount,
description,account_id as id
FROM
finanzen.budget_billdetails, finanzen.budget_bills,finanzen.budget_accounts
$billDetTable, $billTable,$accTable
WHERE
datum >= '$jetzt'
AND (datum < '$jetzt'::date + interval '1 month')
AND budget_bills.id = bill_id
AND account_id = finanzen.budget_accounts.id
AND $billTable.id = bill_id
AND account_id = $accTable.id
AND (account_id IN (
WITH RECURSIVE subordinates AS (
SELECT
@@ -37,7 +43,7 @@ class Charts extends BaseController {
parent_id,
description
FROM
finanzen.budget_accounts
$accTable
WHERE
id = $id
UNION
@@ -46,7 +52,7 @@ class Charts extends BaseController {
e.parent_id,
e.description
FROM
finanzen.budget_accounts e
$accTable e
INNER JOIN subordinates s ON s.id = e.parent_id)
SELECT
id
@@ -72,16 +78,24 @@ class Charts extends BaseController {
return view("charts/monthly", $data);
}
private function getAllData(){
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
$bills = model('App\Models\mBills'); /* @var \App\Models\mBills $bills */
$billDet = model('App\Models\mBillDetails'); /* @var \App\Models\mBills $billDet */
$accTable = $accounts->getTable();
$billTable = $bills->getTable();
$billDetTable = $billDet->getTable();
$jetzt = date('Y-m-01');
$query = <<<EOD
SELECT * FROM (
SELECT id, description,sum(amount)as summe FROM (SELECT id,description from finanzen.budget_accounts WHERE parent_id=0 AND type='output' AND LKZ is null) as w,
SELECT id, description,sum(amount)as summe FROM (SELECT id,description from $accTable WHERE parent_id=0 AND account=false AND deleted_at is null) as w,
LATERAL
(SELECT ABS(SUM(subamount)) as amount
FROM finanzen.budget_billdetails, finanzen.budget_bills
FROM $billDetTable, $billTable
WHERE datum >= '$jetzt'
AND budget_bills.id = bill_id
AND (account_id IN
AND $billTable.deleted_at is null
AND $billDetTable.deleted_at is null
AND $billTable.id = $billDetTable.bill_id
AND (account_id IN
(
WITH RECURSIVE subordinates AS (
SELECT
@@ -89,7 +103,7 @@ class Charts extends BaseController {
parent_id,
description
FROM
finanzen.budget_accounts
$accTable
WHERE
id = w.id
UNION
@@ -98,7 +112,7 @@ class Charts extends BaseController {
e.parent_id,
e.description
FROM
finanzen.budget_accounts e
$accTable e
INNER JOIN subordinates s ON s.id = e.parent_id)
SELECT
id
@@ -109,6 +123,7 @@ class Charts extends BaseController {
EOD;
$data = array();
$result = $this->db->query($query);
log_message('debug','Charts::getAllData: '.$this->db->getLastQuery());
foreach ($result->getResult() as $row) {
$werte[] = $row->summe;
$ids[] = $row->id;

View File

@@ -0,0 +1,195 @@
<?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;
}
}

View File

@@ -1,352 +1,28 @@
<?php
namespace App\Controllers;
use App\Models\mBills;
use App\Models\mAccounts;
use App\Models\mBills;
use CodeIgniter\Session\Session;
use CodeIgniter\Files\File;
use CodeIgniter\I18n\Time;
class Home extends BaseController
{
private $accounts;
class Home extends BaseController {
/**
* @var Session
*/
protected $session;
public function __construct()
{
public function __construct() {
$this->session = service('session');
$this->accounts = model('App\Models\mAccounts');
}
public function overview()
{
public function overview() {
$accounts = model('App\Models\mAccounts'); /* @var \App\Models\mAccounts $accounts */
$bills = model('App\Models\mBills'); /* @var \App\Models\mBills $bills */
$billDet = model('App\Models\mBillDetails'); /* @var \App\Models\mBills $billDet */
$scheduled = model('App\Models\mScheduled'); /* @var \App\Models\mScheduled $scheduled */
return view('table');
}
private function checkDDPList(&$arr, $ele){
if (!array_key_exists($ele, $arr)){
$arr[$ele] = $this->accounts->getDropDownEntry($ele);
}
}
private function checkDDSList($arr, $par, $ele){
if (!array_key_exists($par, $arr)){
$ret = array();
if ($ele > 0)
$ret[$ele] = $this->accounts->getDropDownEntry($ele);
else
$ret[0] = '-----';
return $ret;
}
else{
return $arr[$par];
}
}
private function loadFormDefaults(){
$data['id'] = 0;
$data['source'] = 0;
$data['datum'] ='';
$data['renummer'] = false;
$data['multi'] = false;
$data['transfer'] = false;
$data['receiver'] = '';
$data['total_in'] = '';
$data['total_out'] = '';
$data['validate'] = false;
$data['scheduled'] = false;
$data['scheduledNum'] = 0;
$data['scheduledType'] = 0;
for ($i=0;$i<10;$i++){
$data['sid'][$i] = 0;
$data['category_parent'][$i] = 0;
$data['category'][$i] = 0;
$data['input'][$i] = '';
$data['output'][$i] = '';
$data['comment'][$i] = '';
}
return $data;
}
/**
* Legt eine neue Terminbuchung an
* @param bool $transfer ob Terminbuchung vom Typ Transfer ist
* @return char gibt die View zurück
**/
public function newScheduled($transfer = 0){
$data = $this->loadFormDefaults();
$data['transfer'] = (bool)$transfer;
return $this->newBill($data,NULL,true);
}
public function newTransfer(){
$data = $this->loadFormDefaults();
$data['transfer'] = true;
return $this->newBill($data,NULL);
}
public function newBill($data = NULL, $errors = NULL,$scheduled = false){
helper('form');
$data = $data ?? $this->loadFormDefaults();
$data['isScheduled'] = $scheduled;
$data['validation'] = $errors;
$srclist = $this->accounts->getDropDownList( 'Acc', TRUE );
$this->checkDDPList($srclist,$data['source']);
$data['sourcelist'] = $srclist;
$data['scheduled'] = array('NumList' => array('1'=>'1','2'=>'2','3'=>'3','4'=>'4','5'=>'5','6'=>'6'),
'TypeList' => array('week'=>'Woche(n)','month'=>'Monat(e)','year'=>'Jahr(e)'),
'style' => 'class="form-select"');
if ($data['transfer'])
$categories = $this->accounts->getDropDownLists( 'Acc', TRUE );
else
$categories = $this->accounts->getDropDownLists( 'InOut', TRUE );
// $data['catparentlist'] = $categories['parent'];
// if (!array_key_exists('catparent', $data))
// $data['catparent'] = $this->accounts->getParent($data['cat']);
// $this->checkDDPList($data['catparentlist'],$data['catparent']);
// $data['catlist'] = $this->checkDDSList((array)$categories['subs'],$data['catparent'],$data['cat']);
$data['subsparent'] = array();
$data['subscategory'] = array();
for ($i=0;$i<10;$i++){
$data['subsparent'][$i] = $categories['parent'];
$data['category_parent'][$i] = $data['category_parent'][$i] ?? 0;
$this->checkDDPList($data['subsparent'][$i],$data['category_parent'][$i]);
$data['subscategory'][$i] = $this->checkDDSList((array)$categories['subs'],$data['category_parent'][$i],$data['category'][$i]??0);
}
$data['subsdata'] = json_encode($categories['subs']);
return view('newBill', $data);
}
private function customValidation(&$errors){
$result = true;
// if ( "on" == $this->request->getPost('multi') )
// {
for ($i=0;$i<10;$i++){
$inp = $this->request->getPost("input[$i]");
$outp = $this->request->getPost("output[$i]");
$cat = $this->request->getPost("category[$i]");
if ((is_numeric($inp) && $inp > 0.0) || (is_numeric($outp) && $outp > 0.0)){
if ($cat == 0){
$result &= false;
$errors['Kategorie']="Kategorie [$i] fehlt oder ungültig";
}
}
if ($cat > 0){
$errors['log2'] = "cat recognized";
if (!((is_numeric($inp) && ($inp > 0.0)) || (is_numeric($outp) && ($outp > 0.0)))){
$errors['Betrag']="Betrag [$i] fehlt oder ungültig";
$result &= false;
}
}
}
// }
// else{
// if ((is_numeric($this->request->getPost('total_in')) && $this->request->getPost('total_in') > 0.0) || (is_numeric($this->request->getPost('total_out')) && $this->request->getPost('total_out') > 0.0)){
// return true;
// }
// else
// $errors['Betrag']="Betrag fehlt oder ungültig";
// }
return $result;
}
public function viewBill(string $filename) {
$filePath= WRITEPATH . '/uploads';
$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]);
}
public function viewPdf(string $filename) {
$view = \Config\Services::renderer();
log_message('debug',$filename);
$filePath= WRITEPATH . '/uploads';
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;
}
public function attemptNewBilling()
{
helper('form');
$uploading = false;
$rules = [
'source' => 'required|greater_than[0]',
'datum' => 'required',
'category.0' => 'required|greater_than[0]'
// 'totalamount'=>'required|numeric'
];
$errors = [ // Errors
'source' => ['required' => 'Konto fehlt','greater_than' => 'Konto fehlt'],
'datum' => ['required' => 'Datum fehlt']];
// 'totalamount' => ['required' => 'Betrag fehlt','numeric' => 'Betrag muss eine Zahl sein']];
if ( 'on' == $this->request->getPost('multi') ) {
$rules['openamount'] = 'equals[0]';
$errors['openamount'] = ['equals' => 'Betrag muss 0 sein'];
}
$fehler= array();
$valid = $this->customValidation($fehler);
$file = $this->request->getFile('billfile');
if ($file) {
if (! $file->isValid() && ($file->getError() != UPLOAD_ERR_NO_FILE)) {
throw new \RuntimeException($file->getErrorString() . '(' . $file->getError() . ')');
} else if ($file->isValid()) {
$rules['billfile'] = ['uploaded[billfile]','max_size[billfile,10000]','mime_in[billfile,application/pdf,image/jpg,image/jpeg]'];
$errors['billfile'] = ['uploaded'=>'Fehler beim Upload','max_size' => 'Zu Groß', 'mime_in' => "Ungültiger Datentyp"];
$uploading = true;
}
}
if ((! $this->validate($rules,$errors)) || (!$valid)){
return $this->newBill($this->request->getPost(), array_merge($this->validator->getErrors(),$fehler),$this->request->getPost('scheduled'));
// return redirect()->back()->withInput()->with('errors', $validation->getErrors());
}
else{
$data = $this->request->getPost();
log_message('debug',print_r($data,true));
if ($this->request->getPost('scheduled') =="0"){
$bills = model('App\Models\mBills');
if ($this->request->getPost('removeBillFile')){
$bills->deleteBillFile($data['id']);
unlink(WRITEPATH . 'uploads/'.$this->request->getPost('removeBillFile'));
}
$billId = $bills->saveBill($data);
if ($uploading){
$date = Time::parse($data['datum']);
$file->move(WRITEPATH . 'uploads',$date->toLocalizedString('yyyyMMdd')." ".$data['receiver']." ".$billId.".".$file->guessExtension());
log_message('debug', $file->getName());
$bills->storeBillFile($billId, $file->getName());
}
$redirectURL = session('redirect_url') ?? site_url('/');
unset($_SESSION['redirect_url']);
return redirect()->to($redirectURL);
}
else{
$scheduled = model('App\Models\mScheduled');
$scheduled->saveBill($data);
}
$this->response->redirect(site_url('/'));
}
}
public function editBill($id){
$bills = model('App\Models\mBills');
$data = $this->loadFormDefaults();
$result = $bills->getEntry($id, $data, $this->accounts);
return $this->newBill($result);
}
public function editScheduled($id){
$scheduled = model('App\Models\mScheduled');
$entry = $scheduled->getEntry($id);
// $bill = array_merge($this->loadFormDefaults(),(array)json_decode($entry['data']));
// $bill['datum'] = $entry['next_date'];
return $this->newBill($entry,NULL,true);
}
public function deleteScheduled($id){
$scheduled = model('App\Models\mScheduled');
$entry = $scheduled->getEntry($id);
// $bill = array_merge($this->loadFormDefaults(),(array)json_decode($entry['data']));
// $bill['datum'] = $entry['next_date'];
return $this->newBill($entry,NULL,true);
}
public function syncScheduled(){
if (!$this->request->isAJAX()) return;
$scheduled = model('App\Models\mScheduled');
$schedules = $scheduled->findAll();
$result = array();
$line = "";
foreach ( $schedules as $schedule )
{
$cur_date = $schedule['next_date'];
while ( strtotime( $cur_date ) <= strtotime( "now" ) )
{
$line .= " $cur_date - ";
$bill = array_merge($this->loadFormDefaults(),(array)json_decode($schedule['data']));
//echo "Hugo:".$schedule['id'];
$bill['id']=0; // to generate a new booking
$bill['datum'] = $cur_date;
$bill['type'] = $bill['transfer']?'transfer':'multiple';
$line .= $bill['receiver'];
$bills = model('App\Models\mBills');
$bills->saveBill($bill);
$cur_date = $scheduled->calcNextDate( $cur_date, $bill['scheduledNum'], $bill['scheduledType']);
$line .= " - $cur_date <br/>";
//log_message('debug','BudgetScheduled:process data: '.logArray($booking->getData()));
$scheduled->update($schedule['id'], ['next_date'=>$cur_date ]);
}
}
return $line;
//$this->showTableBookings();
}
public function viewAccountsTree(){
helper('form');
$data = $this->accounts->getTreeData();
$data['ddlist'] = $this->accounts->getDropDownList( 'all', false,true );
return view('accountstree',$data);
}
public function attemptEditAccount(){
$rules = [
'description' => 'required',
'type' => 'required',
];
if (! $this->validate($rules))
{
return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
}
$this->accounts->saveAccount($this->request->getPost());
// $this->accounts = model('App\Models\mAccounts', false);
return $this->viewAccountsTree();
}
public function viewAccountActivities(){
helper('form');
$data = array();
$data['source'] = 0;
$data['start'] = session('datum_start') ?? date("d.m.Y", strtotime( "- 2 weeks", strtotime( "now" ) ));
$data['ende'] = session('datum_ende') ?? date("d.m.Y", strtotime( "now" ) );
$data['source'] = session('source') ?? 0;
$data['sourcelist'] = $this->accounts->getDropDownList( 'all', TRUE );
return view('activities', $data);
}
public function viewScheduled(){
helper('form');
return view('scheduled');
}
}

View File

@@ -0,0 +1,83 @@
<?php
namespace App\Controllers;
use App\Models\mScheduled;
use CodeIgniter\Session\Session;
use CodeIgniter\API\ResponseTrait;
include_once (dirname(__FILE__) . "/FormHandler.php");
class Scheduled extends FormHandler {
use ResponseTrait;
/**
* @var Session
*/
protected $session;
public function __construct() {
$this->session = service('session');
}
public function new(bool $transfer=false){
//log_message('debug','Bills::new');
$eBooking = new \App\Entities\eBooking();
$eBooking->transfer = $transfer;
$eBooking->scheduled = true;
$eBooking = $eBooking->getNew();
return $this->viewBill($eBooking);
}
public function edit(int $id){
$scheduled = model('App\Models\mScheduled');
$entry = $scheduled->getEntry($id);
$eBooking = new \App\Entities\eBooking($entry);
return $this->viewBill($eBooking);
}
public function sync(){
if (!$this->request->isAJAX()) return;
$scheduled = model('App\Models\mScheduled');
$schedules = $scheduled->findAll();
$lines = "";
foreach ( $schedules as $schedule ) {
$cur_date = $schedule['next_date'];
while ( strtotime( $cur_date ) <= strtotime( "now" ) ) {
$data = (array)json_decode($schedule['data']);
$data['id'] = 0; // to generate a new booking (overwrite id of scheduled DB)
$data['scheduled'] = false;
$eBooking = new \App\Entities\eBooking($data);
$eBooking->datum = $cur_date;
$lines .= " $cur_date - $eBooking->receiver <br/>";
$eBooking->saveIt();
$cur_date = $scheduled->calcNextDate( $cur_date, $data['scheduledNum'], $data['scheduledType']);
}
$scheduled->update($schedule['id'], ['next_date'=>$cur_date ]);
}
return $lines;
}
public function viewScheduled(){
helper('form');
return view('scheduled');
}
public function delete(){
if ($this->request->is('post')) {
log_message('debug',"delete id: ".$this->request->getPost("id"));
if (!ctype_digit($this->request->getPost("id"))) return $this->failForbidden("Ungültige ID");
$schmodel = model(mScheduled::class);
$result = $schmodel->delete(intval($this->request->getPost("id")));
if ($result !== true)
return $this->fail("Database error ".$result);
else
return $this->respondDeleted(['url'=>session('redirect_url') ?? site_url('/'),'ID'=>$this->request->getPost("id")]);
}
return $this->failUnauthorized("Schäm Dich");
}
public function getTabData(){
if (!$this->request->isAJAX()) return;
$scheduled = model('App\Models\mScheduled');
return json_encode($scheduled->getEntries());
}
}