needlogin = true; $me = new User(); $me->loadMe(); $this->me = $me; $this->layout()->set("me", $me); if (!$me->is(["Admin"])) { $this->redirect("Dashboard"); } } protected function indexAction() { $this->layout()->setTemplate("Invoice/Index"); if ($this->request->resetFilter) { unset($_SESSION[MFAPPNAME . '-Invoice-filter']); } $filter = []; if (is_array($this->request->filter)) { $filter = $this->request->filter; $_SESSION[MFAPPNAME . '-Invoice-filter'] = $filter; } else { if (array_key_exists(MFAPPNAME . '-Invoice-filter', $_SESSION) && count($_SESSION[MFAPPNAME . '-Invoice-filter'])) { $filter = $_SESSION[MFAPPNAME . '-Invoice-filter']; } } $this->layout->set("filter", $filter); $filter = $this->getPreparedFilter($filter); // pagination defaults $pagination = []; $pagination['start'] = 0; $pagination['count'] = 50; $pagination['maxItems'] = 0; if (is_numeric($this->request->s)) { $pagination['start'] = intval($this->request->s); } //var_dump($filter);exit; $pagination['maxItems'] = InvoiceModel::count($filter); $billings = InvoiceModel::search($filter, $pagination); $this->layout()->set("invoices", $billings); $this->layout()->set("pagination", $pagination); } private function getPreparedFilter($filter) { $new_filter = []; if (array_key_exists("customer", $filter)) { if (array_key_exists("customer", $filter) && $filter["customer"]) { $kunde = $this->db()->escape($filter['customer']); if (!array_key_exists("add-where", $new_filter)) $new_filter["add-where"] = ""; $new_filter['add-where'] .= " AND (company like '%$kunde%' OR firstname like '%$kunde%' OR lastname like '%$kunde%' OR concat(firstname, ' ', lastname) like '%$kunde%' OR concat(lastname, ' ', firstname) like '%$kunde%')"; } } if (array_key_exists("address", $filter)) { if (array_key_exists("address", $filter) && $filter["address"]) { $search = $this->db()->escape($filter['address']); if (!array_key_exists("add-where", $new_filter)) $new_filter["add-where"] = ""; $new_filter['add-where'] .= " AND (street like '%$search%' OR zip like '%$search%' OR city like '%$search%' OR country like '%$search%')"; } } if (is_array($filter) && count($filter)) { foreach ($filter as $name => $value) { $new_filter[$name] = $value; } } return $new_filter; } protected function downloadInvoice() { $id = $this->request->id; if (!is_numeric($id) || !$id) { $this->layout()->setFlash("Rechnung nicht gefunden", "error"); $this->redirect("Invoice"); } $invoice = new Invoice($id); if (!$invoice->id) { $this->layout()->setFlash("Rechnung nicht gefunden", "error"); $this->redirect("Invoice"); } $vat = []; foreach ($invoice->positions as $p) { if (!array_key_exists($p->vatrate, $vat)) { $vat[$p->vatrate] = 0; } $vat[$p->vatrate] += $p->price_gross - $p->price; } $pdf_vars = ["invoice" => $invoice, "vat" => $vat]; // Replace placeholders in header $headerHtml = file_get_contents(BASEDIR . "/Layout/default/Invoice/PDF_HEADER.html"); $headerHtml = str_replace("{{ basedir }}", BASEDIR, $headerHtml); $headerHtml = str_replace("{{ addressLine_1 }}", $invoice->company ? $invoice->company : "", $headerHtml); $headerHtml = str_replace("{{ addressLine_2 }}", $invoice->firstname . " " . $invoice->lastname, $headerHtml); $headerHtml = str_replace("{{ addressLine_3 }}", nl2br($invoice->street), $headerHtml); $headerHtml = str_replace("{{ addressLine_4 }}", $invoice->zip . " " . $invoice->city, $headerHtml); $headerHtml = str_replace("{{ addressLine_5 }}", $invoice->country != "Österreich" ? $invoice->country : "", $headerHtml); $headerHtml = str_replace("{{ customerNumber }}", $invoice->customer_number, $headerHtml); $headerHtml = str_replace("{{ billingAccount }}", "testtest", $headerHtml); $headerHtml = str_replace("{{ invoiceNumber }}", $invoice->invoice_number, $headerHtml); $headerHtml = str_replace("{{ invoiceDate }}", date("d.m.Y", $invoice->invoice_date), $headerHtml); $headerHtml = str_replace("{{ vatHtml }}", $invoice->uid ? "Ihre UID:" . $invoice->uid . "" : "", $headerHtml); $headerHtml = str_replace("{{ qrCodeSrc }}", $this->getBankQRCode($invoice->invoice_number, $invoice->total_gross), $headerHtml); $headerFile = BASEDIR . "/var/temp/" . date("U") . "-" . rand(1000, 9999) . ".html"; file_put_contents($headerFile, $headerHtml); $pdf = new PdfForm("Invoice/PDF_MAIN", $pdf_vars); $wkhtmltopdfArgs = "--header-html $headerFile --footer-html " . BASEDIR . "/Layout/default/Invoice/PDF_FOOTER.html"; $pdf->download($invoice->invoice_number . ".pdf", $wkhtmltopdfArgs); } public function getBankQRCode($paymentReference, $amount) { $xinonIBAN = "DE89370400440532013000"; $xinonBIC = "COBADEFFXXX"; $epc = "BCD 001 1 SCT $xinonBIC Xinon GmbH $xinonIBAN EUR$amount XINO $paymentReference XINON GmbH"; return (new QRCode)->render($epc); } protected function runInvoicingAction() { $i = 0; $p = 0; // get pairs of owner_id and billingaddress_id, so each will be its own invoice foreach (BillingModel::getInvoiceBaseData(['invoice_id' => null]) as $base) { //var_dump($base); continue; $owner_id = $base["owner_id"]; $billingaddress_id = $base["billingaddress_id"]; $billing_type = $base["billing_type"]; $billing_delivery = $base["billing_delivery"]; $bill_positions = []; $credit_positions = []; $billing_rows = BillingModel::search(["owner_id" => $owner_id, "billingaddress_id" => $billingaddress_id, "billing_type" => $billing_type, "billing_delivery" => $billing_delivery, "invoice_id" => null]); if (!count($billing_rows)) { die("Keine nicht verrechneten Billing records für billingaddress_id"); } //var_dump($owner_id, $billingaddress_id, $bills);exit; $invoice_data = []; foreach ($billing_rows as $bill) { $vatrate = $bill->vatrate; $price = $bill->price; $price_total = $bill->price * $bill->amount; $price_gross = ($vatrate) ? $price_total + ($price_total / 100) * $vatrate : $price_total; $price_setup = $bill->price_setup; $price_setup_total = $bill->price_setup * $bill->amount; $price_setup_gross = ($vatrate) ? $price_setup_total + ($price_setup_total / 100) * $vatrate : $price_setup_total; $add_setup_position = ($price > 0 && $price_setup > 0); $is_setup_only = ($price < 0.00001 && $price_setup > 0); $position_data = []; $position_data["billing_id"] = $bill->id; $position_data["contract_id"] = $bill->contract_id; $position_data["start_date"] = $bill->start_date; $position_data["end_date"] = $bill->end_date; $position_data["matchcode"] = $bill->matchcode; $position_data["product_id"] = $bill->product_id; $position_data["product_name"] = $bill->product_name; $position_data["product_info"] = $bill->product_info; $position_data["amount"] = $bill->amount; $position_data["billing_period"] = $bill->billing_period; if ($is_setup_only) { $this->log->debug("Contract ID " . $bill->contract_id . " is setup only"); $position_data["price"] = $price_setup; $position_data["price_total"] = $price_setup_total; $position_data["price_gross"] = $price_setup_gross; $position_data["vatrate"] = $vatrate; $position_data["end_date"] = $position_data["start_date"]; } else { $position_data["price"] = $price; $position_data["price_total"] = $price_total; $position_data["price_gross"] = $price_gross; $position_data["vatrate"] = $vatrate; } $new_position = InvoicepositionModel::create($position_data); $bill_positions[] = $new_position; if ($add_setup_position) { $this->log->debug("Adding Setup Invoiceposition for Contract ID " . $bill->contract_id); $setup_data = $position_data; $setup_data["product_name"] = "Herstellungskosten " . $bill->product_name; $setup_data["product_info"] = ""; $setup_data["price"] = $price_setup; $setup_data["price_total"] = $price_setup * $bill->amount; $setup_data["price_gross"] = $price_setup_gross; $setup_data["vatrate"] = $vatrate; $setup_data["end_date"] = $setup_data["start_date"]; $setup_position = InvoicepositionModel::create($setup_data); $bill_positions[] = $setup_position; } /*if($bill->price >= 0 || $bill->price_setup >= 0) { $bill_positions[] = InvoicepositionModel::create($position_data); } else { $credit_positions[] = InvoicepositionModel::create($position_data);; }*/ $invoice_data["owner_id"] = $owner_id; $invoice_data["billingaddress_id"] = $billingaddress_id; $invoice_data["customer_number"] = $bill->customer_number; $invoice_data["company"] = $bill->company; $invoice_data["firstname"] = $bill->firstname; $invoice_data["lastname"] = $bill->lastname; $invoice_data["street"] = $bill->street; $invoice_data["zip"] = $bill->zip; $invoice_data["city"] = $bill->city; $invoice_data["country"] = $bill->country; $invoice_data["email"] = $bill->email; $invoice_data["uid"] = $bill->uid; $invoice_data["billing_type"] = $billing_type; $invoice_data["billing_delivery"] = $billing_delivery; $invoice_data["bank_account_bank"] = $bill->bank_account_bank; $invoice_data["bank_account_owner"] = $bill->bank_account_owner; $invoice_data["bank_account_iban"] = $bill->bank_account_iban; $invoice_data["bank_account_bic"] = $bill->bank_account_bic; $invoice_data["total"] = 0; $invoice_data["total_gross"] = 0; $invoice_data["total_vat"] = 0; } //var_dump($bill_positions, $credit_positions);exit; // create Invoice $invoice = InvoiceModel::create($invoice_data); $invoice->startTransaction(); try { if (!$invoice->save()) { $invoice->rollbackTransaction(); die("Error saving Invoice"); } $total_net = 0; $total_gross = 0; $total_vat = 0; foreach ($bill_positions as $position) { // on error: rollback transaction // add Invoice::id to Invoiceposition $position->invoice_id = $invoice->id; if (!$position->vatrate) { $total_net += $position->price_total; } else { $total_vat += ($position->price_total / 100) * $position->vatrate; $total_net += $position->price_total; $total_gross += $position->price_gross; } // save Invoiceposition if (!$position->save()) { $invoice->rollbackTransaction(); die("Error saving Invoiceposition"); } // ad Invoice::id to Bill $bill = new Billing($position->billing_id); if (!$bill->id) { $invoice->rollbackTransaction(); die("Bill for Invoiceposition not found"); } $bill->invoice_id = $invoice->id; if (!$bill->save()) { $invoice->rollbackTransaction(); die("error saving invoice_id to bill"); } $p++; } $invoice->total = $total_net; $invoice->total_gross = $total_gross; $invoice->total_vat = $total_vat; if (!$invoice->save()) { $invoice->rollbackTransaction(); die("Error saving totals in Invoice"); } // generate Invoice number $new_num = InvoiceModel::getNextInvoiceNUmber(); $invoice->invoice_number = $new_num; $invoice->invoice_date = date("U"); if (!$invoice->save()) { $invoice->rollbackTransaction(); die("Error saving Invoice number and date"); } // commit transaction $invoice->commitTransaction(); $i++; } catch (Exception $e) { if ($invoice) { $invoice->rollbackTransaction(); } die("Error saving Invoice!\n"); } // Create Invoice PDF // if billing_delivery == paper -> add to pdf collection // else -> send by email //var_dump($invoice); //exit; } $this->layout()->setFlash("$i Rechnungen mit $p Rechnungspositionen erstellt"); $this->redirect("Invoice"); } }