Added Order Form and File

This commit is contained in:
Frank Schubert
2021-07-30 18:24:51 +02:00
parent 1ae970564f
commit ec0abff225
18 changed files with 1078 additions and 101 deletions
+15 -1
View File
@@ -25,7 +25,7 @@ class AddressModel {
foreach($data as $field => $value) {
if(property_exists(get_called_class(), $field)) {
$model ->$field = $value;
$model->$field = $value;
}
}
@@ -39,6 +39,10 @@ class AddressModel {
$model->edit_by = $me->id;
}
if(!array_key_exists("note", $data)) {
$model->note = "";
}
return $model;
}
@@ -77,6 +81,7 @@ class AddressModel {
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
$have = [];
$sql = "SELECT Address.* FROM Address, Addresstype
WHERE Addresstype.address_id = Address.id
AND $where
@@ -86,8 +91,17 @@ class AddressModel {
if($db->num_rows($res)) {
while($data = $db->fetch_object($res)) {
$items[] = new Address($data);
$have[] = $data->id;
}
}
$res = $db->select("Address", "*", "$where AND id NOT IN (".implode(",", $have).")");
if($db->num_rows()) {
while($data = $db->fetch_object($res)) {
$items[] = new Address($data);
}
}
return $items;
}
+26
View File
@@ -2,4 +2,30 @@
class File extends mfBaseModel {
public function delete() {
if($this->id) {
$id = $this->id;
// delete file in store
$path = MFUPLOAD_FILE_SAVE_PATH."/documents/".$this->store_filename;
if(!unlink($path)) {
$this->log->warn(__CLASS__."::delete(): Error unlinking file ($path)");
}
$where = "id=$id";
if($this->fieldprefix && !strstr($field,"_")) {
$where = $this->fieldprefix."_id=$id";
}
if($this->db->delete($this->table,$where)) {
if(method_exists($this, "afterDelete")) {
$this->afterDelete();
}
$this->data = new stdClass();
$this->id = "";
return true;
}
}
return false;
}
}
+56
View File
@@ -13,4 +13,60 @@ class FileController extends mfBaseController {
$this->redirect("Dashboard");
}*/
}
protected function downloadAction() {
$id = $this->request->id;
if(!is_numeric($id) || $id < 1) {
return true;
}
$file = new File($id);
if(!$file) {
throw new Exception("File not found", 404);
}
$filename = $file->store_filename;
$path = MFUPLOAD_FILE_SAVE_PATH."/documents/$filename";
//var_dump($path);exit;
if(!file_exists($path)) {
throw new Exception("File not found", 4041);
}
if(preg_match('/\.([^.]+)/',$filename,$m)) {
$ext .= $m[1];
} else {
throw new Exception("File not found", 4042);
}
$outname = ($file->filename) ? $file->filename : $file->orig_filename;
if(!$this->sendfile($path, $outname)) {
throw new Exception("File not found", 4043);
}
exit;
}
private function sendfile($file,$name) {
$this->log->debug("sendfile: $file $name");
if (!$fh = fopen($file, 'r')) {
return false;
}
set_time_limit(36000);
header('Content-Type: application/octet-stream');
header('Content-disposition: attachment; filename="' . $name . '"');
$size = exec('stat -c %s '.escapeshellarg($file));
if($size < (pow(2,31))-1) {
header('Content-Length: ' . $size);
}
while (!feof($fh)) {
$data = fread($fh, 8192);
echo $data;
}
return true;
}
}
+1
View File
@@ -4,6 +4,7 @@ class FileModel {
public $name;
public $description;
public $filename;
public $store_filename;
public $orig_filename;
public $subfolder;
+37 -31
View File
@@ -3,55 +3,61 @@
class Order extends mfBaseModel {
private $owner;
private $billingaddress;
private $products;
private $files;
private $creator;
private $editor;
public function getNewPos() {
if(!$this->id) {
return 0;
}
$p = end($this->getProperty("products"));
return ++$p->pos;
}
public function getProperty($name) {
if($this->$name == null) {
if(!$this->id) {
return null;
}
if($name == "owner") {
if($this->id) {
$this->owner = new Address($this->owner_id);
return $this->owner;
} else {
return null;
}
$this->owner = new Address($this->owner_id);
return $this->owner;
}
if($name == "contact") {
if($this->id) {
$this->contact = new Address($this->contact_id);
return $this->contact;
} else {
return null;
}
$this->contact = new Address($this->contact_id);
return $this->contact;
}
if($name == "billingaddress") {
if($this->id) {
$this->billingaddress = new Address($this->billingaddress_id);
return $this->billingaddress;
} else {
return null;
}
$this->billingaddress = new Address($this->billingaddress_id);
return $this->billingaddress;
}
if($name == "products") {
$this->products = OrderProductModel::search(["order_id" => $this->id]);
return $this->products;
}
if($name == "files") {
$this->files = OrderFileModel::search(['order_id' => $this->id]);
return $this->files;
}
if($name == "creator") {
if($this->id) {
$this->creator = new User($this->create_by);
return $this->creator;
} else {
return null;
}
$this->creator = new User($this->create_by);
return $this->creator;
}
if($name == "editor") {
if($this->id) {
$this->editor = new User($this->edit_by);
return $this->editor;
} else {
return null;
}
$this->editor = new User($this->edit_by);
return $this->editor;
}
$classname = ucfirst($name);
+307
View File
@@ -23,5 +23,312 @@ class OrderController extends mfBaseController {
protected function addAction() {
$this->layout()->setTemplate("Order/Form");
$this->layout()->set("addresses", AddressModel::search(['parents_only' => 1]));
$this->layout()->set("products", ProductModel::getAll());
}
protected function editAction() {
$order_id = $this->request->id;
$order = new Order($order_id);
if(!$order->id) {
$this->layout()->setFlash("Bestellung nicht gefunden.", "error");
$this->redirect("Order");
}
$this->layout()->set("order", $order);
return $this->addAction();
}
protected function saveAction() {
$r = $this->request;
//var_dump($r->products);
//var_dump($r);
//exit;
$id = $r->id;
if(is_numeric($id) && $id > 0) {
$mode = "edit";
$order = new Order($id);
if(!$order->id) {
$this->layout()->setFlash("Bestellung nicht gefunden", "error");
$this->redirect("Order");
}
} else {
$id = false;
$mode = "add";
}
// validate owner
$owner = false;
if(!$r->owner_id) {
$this->layout()->setFlash("Bitte Vertragsinhaber auswählen oder eintragen.", "error");
$this->layout()->set("order", $r);
return $this->add();
}
if(is_numeric($r->owner_id)) {
$owner = new Address($r->owner_id);
if(!$owner->id) {
$this->layout()->setFlash("Ungültiger Vertragsinhaber.", "error");
$this->layout()->set("order", $r);
return $this->add();
}
} elseif($r->owner_id == "new") {
if(!$r->owner_company && !($r->owner_firstname && $r->owner_lastname)) {
$this->layout()->setFlash("Fehler in Vertragsinhaber: Firmenname oder Vor- und Nachname benötigt.");
$this->layout()->set("order", $r);
return $this->add();
}
foreach(["street", "zip", "city", "phone", "email"] as $required) {
if(!$r->{"owner_$required"}) {
$this->layout()->setFlash("Fehler in Vertragsinhaber: Bitte alle benötigten Felder ausfüllen.");
$this->layout()->set("order", $r);
return $this->add();
}
}
} else {
$this->layout()->setFlash("Ungültiger Vertragsinhaber.");
$this->layout()->set("order", $r);
return $this->add();
}
// validate billindaddress
$billingaddress = false;
if($r->billingaddress_id) {
// billingaddress can be empty
if(is_numeric($r->billingaddress_id)) {
$billingaddress = new Address($r->billingaddress_id);
if(!$billingaddress->id) {
$this->layout()->setFlash("Ungültiger Rechnungsempfänger.", "error");
$this->layout()->set("order", $r);
return $this->add();
}
} elseif($r->billingaddress_id == "new") {
if(!$r->billing_company && !($r->billingr_firstname && $r->billing_lastname)) {
$this->layout()->setFlash("Fehler in Rechnungsqmpfänger: Firmenname oder Vor- und Nachname benötigt.");
$this->layout()->set("order", $r);
return $this->add();
}
foreach(["street", "zip", "city", "phone", "email"] as $required) {
if(!$r->{"owner_$required"}) {
$this->layout()->setFlash("Fehler in Rechnungsempfänger: Bitte alle benötigten Felder ausfüllen.");
$this->layout()->set("order", $r);
return $this->add();
}
}
} else {
$this->layout()->setFlash("Ungültiger Rechnungsempfänger.");
$this->layout()->set("order", $r);
return $this->add();
}
}
// validate sepa
if(!$r->billing_type) {
$this->layout()->setFlash("Ungültige Verrechnungsart.");
$this->layout()->set("order", $r);
return $this->add();
}
if($r->billing_type == "sepa") {
foreach(['bank', 'owner', 'iban', 'bic'] as $required) {
if(!$r->{"bank_account_$required"}) {
$this->layout()->setFlash("Bitte Bankdaten für SEPA ausfüllen.");
$this->layout()->set("order", $r);
return $this->add();
}
}
}
// create objects for saving (if new) but don't save yet
$owner_data = [];
$billing_data = [];
$request = $r->get();
foreach($request as $field => $value) {
$m = [];
if(preg_match('/([a-z0-9]+)_(.+)/i', $field, $m)) {
if($m[1] == "owner" && !$owner) {
$owner_data[$m[2]] = $value;
}
if($m[1] == "billing" && !$billingaddress) {
$billing_data[$m[2]] = $value;
}
}
}
if(!$owner) {
$owner = AddressModel::create($owner_data);
}
if(!$billingaddress) {
$billingaddress = AddressModel::create($billing_data);
}
// create or save Order object
$order_data = [];
if(is_numeric($r->owner_id)) {
$order_data['owner_id'] = $r->owner_id;
}
if(is_numeric($r->billingaddress_id)) {
$order_data['billingaddress_id'] = $r->billingaddress_id;
}
$order_data['billing_type'] = $r->billing_type;
$order_data['bank_account_bank'] = $r->bank_account_bank;
$order_data['bank_account_owner'] = $r->bank_account_owner;
$order_data['bank_account_iban'] = $r->bank_account_iban;
$order_data['bank_account_bic'] = $r->bank_account_bic;
$order_data['allow_contact'] = ($r->allow_contact) ? 1 : 0;
$order_data['allow_spin'] = ($r->allow_spin) ? 1 : 0;
$order_data['note'] = $r->note;
$order_date = $r->order_date;
if(!preg_match('/^(\d\d)\.(\d\d)\.(\d\d\d\d)$/',$order_date, $m)) {
$errors[] = "Ungültiges Bestelldateum";
} else {
$day = intval($m[1]);
$month = intval($m[2]);
$year = intval($m[3]);
if($day > 31 || $day < 1
|| $month > 12 || $month < 1
|| $year > date('Y')+1 || $year < date('Y'))
{
$this->layout()->setFlash("Ungültiges Bestelldatum");
$this->layout()->set("Order", $r);
return $this->add();
}
$order_date_ts = mktime(0,0,0,$month,$day,$year);
$order_data['order_date'] = $order_date_ts;
}
$order_data['edit_by'] = $this->me->id;
if($mode == "add") {
$order = OrderModel::create($order_data);
} else {
$order->update($order_data);
}
/*
var_dump($order);
var_dump($owner);
var_dump($billingaddress);
exit;*/
if(!$owner || !$billingaddress) {
$this->layout()->setFlash("Fehler beim Speichern", "error");
$this->layout()->set("order", $order);
return $this->add();
}
$new_id = $order->save();
if(!$new_id) {
$this->layout()->setFlash("Fehler beim Speichern", "error");
$this->layout()->set("order", $order);
return $this->add();
}
// save owner and billingaddress if new
if($r->owner_id == "new") {
$owner_id = $owner->save();
if(!$owner_id) {
$this->layout()->setFlash("Fehler beim Speichern des Inhabers", "error");
$this->redirect("Order", "edit", ['id' => $new_id]);
}
$order->owner_id = $owner_id;
$order->save();
}
if($r->billingaddress_id == "new") {
$billingaddress_id = $billingaddress->save();
if(!$billingaddress_id) {
$this->layout()->setFlash("Fehler beim Speichern des Rechnungsempfängers", "error");
$this->redirect("Order", "edit", ['id' => $new_id]);
}
$owner->billingaddress_id = $billingaddress_id;
$order->save();
}
//var_dump($r->products);exit;
// validate and add products
if(is_array($r->products) && count($r->products)) {
foreach($r->products as $product_id => $p) {
//var_dump($p);
if(!$product_id || !$p["product_id"]) {
continue;
}
$product_data = [];
$product_data["order_id"] = $new_id;
$product_data["product_id"] = $p["product_id"];
$product_data['amount'] = (!empty($p['amount'])) ? $p['amount'] : 1;
$product_data["pos"] = ($p["pos"]) ? $p['pos'] : $order->getNewPos();
$product_data["description"] = $p["description"];
$product_data["price"] = Layout::commaToDot($p["price"]);
$product_data["price_setup"] = Layout::commaToDot($p["price_setup"]);
$product_data["billing_delay"] = 0;
$product_data["billing_period"] = $p["billing_period"];
if($product_id == "new") {
$product = OrderProductModel::create($product_data);
} else {
$product = new OrderProduct($product_id);
$product->update($product_data);
}
if(!$product->save()) {
$this->log->warn("Unable to save OrderProduct:".print_r($product, true));
}
}
}
//var_dump($_FILES['OrderFileUpload']);exit;
// handle file upload
if(array_key_exists("OrderFileUpload", $_FILES) && !$_FILES['OrderFileUpload']['error']) {
//var_dump($_FILES);exit;
$upload = new mfUpload("OrderFileUpload");
$upload->setSavepath(MFUPLOAD_FILE_SAVE_PATH."/documents");
$upload->save();
$file_data = [];
$file_data['name'] = ($r->file_name) ? $r->file_name : $upload->getOriginalFilename();
$file_data['filename'] = ($r->file_filename) ? $r->file_filename : $upload->getOriginalFilename();
$file_data['store_filename'] = $upload->getFilename();
$file_data['orig_filename'] = $upload->getOriginalFilename();
$file = FileModel::create($file_data);
$file_id = $file->save();
if(!$file_id) {
$this->layout()->setFlash("Dateiupload fehlgeschlagen", "warn");
unlink($upload->getSavepath()."/".$upload->getFilename());
} else {
$of = [];
$of['order_id'] = $new_id;
$of['file_id'] = $file_id;
$of['name'] = $file->name;
$of['description'] = $file->description;
$orderfile = OrderFileModel::create($of);
if(!$orderfile->save()) {
$file->delete();
unlink($upload->getSavepath()."/".$upload->getFilename());
$this->layout()->setFlash("Dateiupload fehlgeschlagen", "warn");
}
}
}
$this->layout()->setFlash("Bestellung erfolgreich gespeichert.", "success");
$this->redirect("Order", "edit", ["id" => $new_id]);
}
}
+2 -2
View File
@@ -62,7 +62,7 @@ class OrderModel {
$db = FronkDB::singleton();
$res = $db->select("Order", "*", "1=1 ORDER BY name, filename");
$res = $db->select("Order", "*", "1=1 ORDER BY order_date, owner_id");
if($db->num_rows($res)) {
while($data = $db->fetch_object($res)) {
$items[] = new Order($data);
@@ -76,7 +76,7 @@ class OrderModel {
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
$res = $db->select("Order", "*", "$where ORDER BY name, filename");
$res = $db->select("Order", "*", "$where ORDER BY order_date, owner_id");
if($db->num_rows($res)) {
$data = $db->fetch_object($res);
$item = new Order($data);
+32
View File
@@ -1,5 +1,37 @@
<?php
class OrderFile extends mfBaseModel {
private $file;
public function getProperty($name) {
if($this->$name == null) {
if(!$this->id) {
return null;
}
if($name == "creator") {
$this->creator = new User($this->create_by);
return $this->creator;
}
if($name == "editor") {
$this->editor = new User($this->edit_by);
return $this->editor;
}
$classname = ucfirst($name);
$idfield = $name."_id";
$this->$name = new $classname($this->$idfield);
if($this->$name->id) {
return $this->$name;
} else {
return null;
}
}
return $this->$name;
}
}
@@ -0,0 +1,36 @@
<?php
class OrderFileController extends mfBaseController {
protected function init() {
$this->needlogin=true;
$me = new User();
$me->loadMe();
$this->me = $me;
$this->layout()->set("me",$me);
if(!$me->isAdmin()) {
$this->redirect("Dashboard");
}
}
protected function editAction() {
// internal redirect to File::editAction
}
protected function deleteAction() {
$id = $this->request->id;
$orderfile = new OrderFile($id);
if(!$orderfile->id || $orderfile->id != $id) {
$this->layout()->setFlash("Dokument nicht gefunden.", "error");
$this->redirect("Order");
}
$order_id = $orderfile->order_id;
$orderfile->file->delete();
$orderfile->delete();
$this->redirect("Order", "edit", ["id" => $order_id]);
}
}
+4 -5
View File
@@ -1,11 +1,10 @@
<?php
class OrderFileModel {
public $order_id;
public $file_id;
public $name;
public $description;
public $filename;
public $orig_filename;
public $subfolder;
public $create_by = null;
public $edit_by = null;
@@ -89,8 +88,8 @@ class OrderFileModel {
$where = self::getSqlFilter($filter);
$sql = "SELECT OrderFile.* FROM OrderFile
LEFT JOIN File ON (Order.file_id = File.id)
$where
LEFT JOIN File ON (OrderFile.file_id = File.id)
WHERE $where
ORDER BY order_id, name";
$res = $db->query($sql);
+67
View File
@@ -0,0 +1,67 @@
<?php
class OrderProduct extends mfBaseModel {
private $order;
private $product;
private $editor;
private $creator;
public function formatAmount() {
if(!$this->id) {
return 0;
}
$m = [];
if(preg_match('/^(\d*)\.(\d+)$/', $this->amount, $m)) {
$int = $m[1];
$dec = $m[2];
if(!$dec) {
return $int;
}
if(preg_match('/^0+$/', $dec)) {
return $int;
}
$dec = preg_replace('/0+$/', "", $dec);
return "$int.$dec";
}
return 0;
}
public function getProperty($name) {
if($this->$name == null) {
if($name == "creator") {
if($this->id) {
$this->creator = new User($this->create_by);
return $this->creator;
} else {
return null;
}
}
if($name == "editor") {
if($this->id) {
$this->editor = new User($this->edit_by);
return $this->editor;
} else {
return null;
}
}
$classname = ucfirst($name);
$idfield = $name."_id";
$this->$name = new $classname($this->$idfield);
if($this->$name->id) {
return $this->$name;
} else {
return null;
}
}
return $this->$name;
}
}
@@ -0,0 +1,130 @@
<?php
class OrderProductModel {
public $order_id;
public $product_id;
public $amount;
public $pos;
public $description;
public $price;
public $price_setup;
public $billing_delay;
public $billing_period;
public $note;
public $create_by = null;
public $edit_by = null;
public $create = null;
public $edit = null;
public static function create(Array $data) {
$model = new OrderProduct();
foreach($data as $field => $value) {
if(property_exists(get_called_class(), $field)) {
$model->$field = $value;
}
}
if(!array_key_exists("note", $data)) {
$model->note = "";
}
$me = new User();
$me->loadMe();
if($model->create_by === null) {
$model->create_by = $me->id;
}
if($model->edit_by === null) {
$model->edit_by = $me->id;
}
return $model;
}
public static function getOne($id) {
if(!is_numeric($id) || !$id) {
throw new Exception("Invalid number", 400);
}
$item = [];
$db = FronkDB::singleton();
$res = $db->select("OrderProduct", "*", "id=$id LIMIT 1");
if($db->num_rows($res)) {
$data = $db->fetch_object($res);
$item = new OrderProduct($data);
}
return $item;
}
public static function getAll() {
$items = [];
$db = FronkDB::singleton();
$res = $db->select("OrderProduct", "*", "1=1 ORDER BY order_id, pos, product_id, description");
if($db->num_rows($res)) {
while($data = $db->fetch_object($res)) {
$items[] = new OrderProduct($data);
}
}
return $items;
}
public static function getFirst() {
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
$res = $db->select("OrderProduct", "*", "$where ORDER BY order_id, pos, product_id, description");
if($db->num_rows($res)) {
$data = $db->fetch_object($res);
$item = new OrderProduct($data);
if($item->id) {
return $item;
} else {
return null;
}
}
return null;
}
public static function search($filter) {
$items = [];
$db = FronkDB::singleton();
$where = self::getSqlFilter($filter);
$res = $db->select("OrderProduct", "*", "$where ORDER BY order_id, pos, product_id, description");
if($db->num_rows($res)) {
while($data = $db->fetch_object($res)) {
$items[] = new OrderProduct($data);
}
}
return $items;
}
private function getSqlFilter($filter) {
$where = "1=1 ";
//var_dump($filter);exit;
if(array_key_exists("order_id", $filter)) {
$order_id = $filter['order_id'];
if(is_numeric($order_id)) {
$where .= " AND order_id=$order_id";
}
}
if(array_key_exists("product_id", $filter)) {
$product_id = $filter['product_id'];
if(is_numeric($product_id)) {
$where .= " AND order_id=$product_id";
}
}
//var_dump($filter, $where);exit;
return $where;
}
}
+41 -1
View File
@@ -165,7 +165,7 @@ class ProductController extends mfBaseController {
$this->redirect("Product", "Edit", ['id' => $new_id]);
}
protected function delete() {
protected function deleteAction() {
$id = $this->request->id;
$product = new Product($id);
@@ -178,4 +178,44 @@ class ProductController extends mfBaseController {
$product->delete();
$this->redirect("Product");
}
protected function apiAction() {
$do = $this->request->do;
$data = [];
switch($do) {
case "getProduct":
$return = $this->getProductApi();
break;
default:
$return = false;
}
if(!is_array($return) || !count($return)) {
$data = ["status" => "error"];
$this->returnJson($data);
}
$data['status'] = "OK";
$data['result'] = $return;
$this->returnJson($data);
}
private function getProductApi() {
$product_id = $this->request->product_id;
if(!is_numeric($product_id) || $product_id < 1) {
return false;
}
$form_id = false;
if($this->request->form_id) {
$form_id = $this->request->form_id;
}
$product = new Product($product_id);
if(!$product->id) {
return false;
}
return ["product" => $product->data, "form_id" => $form_id];
}
}