needlogin = true; $me = new User(); $me->loadMe(); $this->me = $me; $this->layout()->set("me", $me); if(!$me->can(["preorderbilling", "preorderbillingReadonly"]) && (!defined("MFBASE_BYPASS_LOGIN") || !MFBASE_BYPASS_LOGIN)) { $this->redirect("Dashboard"); } } protected function indexAction() : void { $this->layout()->setTemplate("PreorderBillingInvoice/Index"); if ($this->request->resetFilter) { unset($_SESSION[MFAPPNAME . '-PreorderBillingInvoice-filter']); } $filter = []; if (is_array($this->request->filter)) { $filter = $this->request->filter; $_SESSION[MFAPPNAME . '-PreorderBillingInvoice-filter'] = $filter; } else { if (array_key_exists(MFAPPNAME . '-PreorderBillingInvoice-filter', $_SESSION) && count($_SESSION[MFAPPNAME . '-PreorderBillingInvoice-filter'])) { $filter = $_SESSION[MFAPPNAME . '-PreorderBillingInvoice-filter']; } } $this->layout->set("filter", $filter); $filter = $this->getPreparedFilter($filter); // pagination defaults $pagination = []; $pagination['start'] = 0; $pagination['count'] = 25; $pagination['maxItems'] = 0; if (is_numeric($this->request->s)) { $pagination['start'] = intval($this->request->s); } $filter["netowner_id"] = $this->me->address_id; $pagination['maxItems'] = PreorderBillingInvoice::count($filter); $invoices = PreorderBillingInvoice::search($filter, $pagination); $this->layout()->set("invoices", $invoices); $this->layout()->set("pagination", $pagination); $now = new DateTime("now"); $email_jobs = InvoiceJobModel::search(["task" => "send-preorder-invoice-email", "to_date>=" => $now->format("Y-m-d")]); $this->layout()->set("email_jobs", $email_jobs); $netoperators = []; foreach(PreordercampaignModel::search(["owner_id" => $this->me->address_id]) as $campaign) { foreach($campaign->active_operators as $op) { if(!array_key_exists($op->operator_id, $netoperators)) { $nop = new Address($op->operator_id); if($nop->id) { $netoperators[$nop->id] = $nop; } } } foreach($campaign->passive_operators as $op) { if(!array_key_exists($op->operator_id, $netoperators)) { $nop = new Address($op->operator_id); if($nop->id) { $netoperators[$nop->id] = $nop; } } } } $this->layout()->set("netoperators", $netoperators); // get last BMD export dates $bmd_export_date_invoice = new mfConfig("preorder.invoice.bmd.export.invoice.ts.".$this->me->address_id); $bmd_export_date_persion = new mfConfig("preorder.invoice.bmd.export.person.ts.".$this->me->address_id); $bmd_export = [ "invoice" => $bmd_export_date_invoice->value(), "person" => $bmd_export_date_persion->value(), ]; $this->layout()->set("bmd_export", $bmd_export); } private function getPreparedFilter($filter) { $new_filter = []; if(array_key_exists("name", $filter)) { if (array_key_exists("name", $filter)) { if (array_key_exists("name", $filter) && $filter["name"]) { $kunde = $this->db()->escape(trim($filter['name'])); 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("start_date_from", $filter)) { if($filter["start_date_from"]) { try { $from = DateTime::createFromFormat("d.m.Y", $filter["start_date_from"]); } catch (Exception $e) {} $new_filter["start_date>="] = $from->format("Y-m-d"); } unset($filter["start_date_from"]); } if(array_key_exists("start_date_to", $filter)) { if($filter["start_date_to"]) { try { $to = DateTime::createFromFormat("d.m.Y", $filter["start_date_to"]); } catch (Exception $e) {} $new_filter["start_date<="] = $to->format("Y-m-d"); } unset($filter["start_date_to"]); } 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 PreorderBillingInvoice($id); if (!$invoice->id) { $this->layout()->setFlash("Rechnung nicht gefunden", "error"); $this->redirect("Invoice"); } $pdf = $invoice->pdf; $pdf = false; //var_dump($pdf, !$pdf);exit; //var_dump($pdf->name);exit; if(!$pdf || !$pdf->name) { $ifile = PreorderBillingInvoiceFile::createFromInvoice($invoice); if(!$ifile) { $this->layout()->setFlash("Fehler beim PDF erstellen"); $this->redirect("PreorderBillingInvoice"); } $pdf = $ifile->file; } $pdf_path = $pdf->getFullPath(); $filename = $pdf->filename; if(!file_exists($pdf_path)) { $this->layout()->setFlash("PDF-Datei nicht gefunden"); $this->redirect("Invoice"); } header('Content-Type: application/octet-stream'); header('Content-disposition: attachment; filename="'.$filename.'"'); header('Content-Transfer-Encoding: binary'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Content-Type: ' . mime_content_type($pdf_path)); header("Content-Length: " . filesize($pdf_path)); readfile($pdf_path); exit; } protected function downloadCsv() { $id = $this->request->id; if (!is_numeric($id) || !$id) { $this->layout()->setFlash("Rechnung nicht gefunden", "error"); $this->redirect("Invoice"); } $invoice = new PreorderBillingInvoice($id); if (!$invoice->id) { $this->layout()->setFlash("Rechnung nicht gefunden", "error"); $this->redirect("Invoice"); } $csv = $invoice->csv; $csv_path = $csv->getFullPath(); $filename = $csv->filename; if(!file_exists($csv_path)) { $this->layout()->setFlash("CSV-Datei nicht gefunden"); $this->redirect("Invoice"); } header('Content-Type: text/csv; charset=utf-8'); header('Content-disposition: attachment; filename="'.$filename.'"'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header("Content-Length: " . filesize($csv_path)); readfile($csv_path); exit; } protected function createJob() { $r = $this->request; //var_dump($r->get());exit; $task = $r->task; if($task != "send-preorder-invoice-email") { $this->layout()->setFlash("Ungültiger Task", "error"); $this->redirect("PreorderBillingInvoice"); } if(!$r->from_date) { $this->layout()->setFlash("Startdatum wird benötigt", "error"); $this->redirect("PreorderBillingInvoice"); } try { $from_date = DateTime::createFromFormat("d.m.Y", $r->from_date, new DateTimeZone("Europe/Vienna")); $from_date->setTime(0,0,0); $to_date = clone $from_date; $to_date->modify("+7 days"); $to_date->setTime(23,59,59); } catch(Exception $e) { $this->layout()->setFlash("Von- oder Bisdatum ungültig", "error"); $this->redirect("PreorderBillingInvoice"); } $job = InvoiceJobModel::create([ "task" => $task, "from_date" => $from_date->format("Y-m-d"), "to_date" => $to_date->format("Y-m-d"), ]); if(!$job->save()) { $this->layout()->setFlash("Fehler beim Speichern", "error"); $this->redirect("PreorderBillingInvoice"); } $this->layout()->setFlash("Task erfolgreich gespeichert", "success"); $this->redirect("PreorderBillingInvoice"); } protected function createAction() { $netowner_id = $this->me->address_id; $today = new DateTime(); $bill_month = clone $today; $bill_month->modify("-1 month"); $fmt = new IntlDateFormatter( MFLOCALE_TIME, IntlDateFormatter::NONE, IntlDateFormatter::NONE, "Europe/Vienna", IntlDateFormatter::GREGORIAN, 'MMMM' ); $bill_month_year_text = $fmt->format($bill_month)." ".$bill_month->format("Y"); $bill_quarter = ceil($bill_month->format("n") / 3); $billing_row_count = 0; $positions_count = 0; $bill_id_count = 0; //$products = PreorderProduct::getAll(true); $base_rows = PreorderBilling::getInvoiceBaseData(['invoice_id' => null, "netowner_id" => $netowner_id]); //var_dump($base_rows);exit; $invoice_count = 0; foreach($base_rows as $base) { $invoice_detail_data = []; $preorderbillingcustomer_id = $base["preorderbillingcustomer_id"]; $owner_id = $base["owner_id"]; $billingaddress_id = $base["billingaddress_id"]; $billing_delivery = $base["billing_delivery"]; $campaign_id = $base["campaign_id"]; $campaign = new Preordercampaign($campaign_id); if(!$campaign->id) { die("Kampagne $campaign_id nicht gefunden"); } $campaign_name = $campaign->name; $campaign_name = preg_replace('/^RML Liezen\s+-\s+/', '', $campaign_name); $cluster = array_shift($campaign->salesclusters); $cluster_name = $cluster->extref; $bill_positions = []; $credit_positions = []; $invoice_voicenumbers = []; $bill_filter = [ "netowner_id" => $netowner_id, "preorderbillingcustomer_id" => $preorderbillingcustomer_id, "owner_id" => $owner_id, "billingaddress_id" => $billingaddress_id, "preordercampaign_id" => $campaign_id, "billing_delivery" => $billing_delivery, "invoice_id" => null, ]; $billing_rows = PreorderBilling::search($bill_filter); if(!count($billing_rows)) { var_dump($bill_filter); die("Keine Billing rows"); continue; } $positions_to_sort = []; $sorted_positions = []; $invoice_positions = []; $invoice_vatrate = 20; //$price_total_sum = 0; foreach($billing_rows as $bill) { $billing_row_count++; $netoperator_id = false; if ($bill->owner_id) { $netoperator_id = $bill->owner_id; } $price = 0; $price_gross = 0; if ($bill->price > 0.000) { $price = $bill->price; } if ($bill->price_setup > 0.000) { $price = $bill->price_setup; } if ($bill->vatrate > 0 && $price) { $price_gross = $price + ($price / 100 * $bill->vatrate); } $start_date = new DateTime($bill->start_date); $end_date = new DateTime($bill->end_date); $year_month = $start_date->format("Ym"); if ($netoperator_id) { //if (!array_key_exists($netoperator_id, $invoice_detail_data)) $invoice_detail_data[$netoperator_id] = []; $detail_data = [ "owner_id" => $bill->owner_id, "company" => ($bill->company) ?: $bill->firstname . " " . $bill->lastname, "network_name" => $campaign_name, "oaid" => $bill->oaid, "extref" => trim($bill->extref), "order_date" => $bill->order_date, "start_date" => $start_date->format("Y-m-d"), "end_date" => $end_date->format("Y-m-d"), "article_number" => $bill->article_number, "product_name" => $bill->product_name, "amount" => $bill->amount, "billing_periodic" => $bill->billing_period, "price" => $price, "price_gross" => $price_gross, "vatrate" => $bill->vatrate, ]; $invoice_detail_data[] = $detail_data; } $position_data = []; $position_data["product_id"] = $bill->product_id; $position_data["product_type"] = $bill->product_type; $position_data["article_number"] = $bill->article_number; $position_data["product_name"] = $bill->product_name; $position_data["article_info"] = $bill->product_info; $position_data["total"] = round($price, 2); $position_data["total_gross"] = round($price_gross, 2); $position_data["vatrate"] = $bill->vatrate; $position_data["billing_id"] = $bill->id; $position_data["fibu_cost_account"] = $bill->fibu_cost_account; $position_data["fibu_revenue_account"] = $bill->fibu_revenue_account; if (!array_key_exists($bill->product_id, $invoice_positions)) { $invoice_positions[$bill->product_id] = []; } if (!array_key_exists($year_month, $invoice_positions[$bill->product_id])) { $invoice_positions[$bill->product_id][$year_month] = []; } $invoice_positions[$bill->product_id][$year_month][] = $position_data; } //var_dump($invoice_positions);exit; foreach($invoice_positions as $product_id => $year_months) { foreach($year_months as $year_month => $positions) { $new_pos_data = [ "count" => 0, "amount" => 0, "unit" => "Stk", "price" => 0, "price_total" => 0, "price_gross" => 0, "vatrate" => 20, "preorder_billings" => [], ]; foreach($positions as $position) { //var_dump($position);exit; $new_pos_data["count"]++; $new_pos_data["amount"]++; $new_pos_data["price"] = $position["total"]; $new_pos_data["price_total"] += $position["total"]; $new_pos_data["price_gross"] += $position["total_gross"]; $new_pos_data["vatrate"] = $position_data["vatrate"]; $new_pos_data["product_id"] = $position["product_id"]; $new_pos_data["product_type"] = $position["product_type"]; $new_pos_data["article_number"] = $position["article_number"]; $new_pos_data["article_name"] = $position["product_name"]; $new_pos_data["article_info"] = $position["article_info"]; $new_pos_data["fibu_cost_account"] = $position["fibu_cost_account"]; $new_pos_data["fibu_revenue_account"] = $position["fibu_revenue_account"]; $new_pos_data["preorder_billings"][] = $position["billing_id"]; $positions_count++; } if($product_id == 3) { $new_pos_data["amount"] = 1; $new_pos_data["unit"] = "Pau"; $new_pos_data["price"] = $new_pos_data["price_total"]; } $new_position = PreorderBillingInvoiceposition::create($new_pos_data); $new_position->preorder_billings = $new_pos_data["preorder_billings"]; $new_position->count = $new_pos_data["count"]; $new_position->fibu_cost_account = $new_pos_data["fibu_cost_account"]; $new_position->fibu_revenue_account = $new_pos_data["fibu_revenue_account"]; $sort_key = round(3 / $product_id)."-".$year_month; $positions_to_sort[$sort_key] = $new_position; } //var_dump($year_months, $new_pos_data); //var_dump($year_month, $product_id, $positions);exit; } ksort($positions_to_sort); $positions_to_sort = array_reverse($positions_to_sort); foreach($positions_to_sort as $key => $sort_pos) { $sorted_positions[] = $sort_pos; } //exit; //var_dump($sorted_positions);exit; //exit; $invoice_data = []; $invoice_data["netowner_id"] = $netowner_id; $invoice_data["preorderbillingcustomer_id"] = $bill->preorderbillingcustomer_id; $invoice_data["owner_id"] = $bill->owner_id; $invoice_data["billingaddress_id"] = $bill->billingaddress_id; $invoice_data["fibu_account_number"] = $bill->fibu_account_number; $invoice_data["fibu_tax_code"] = 1; $invoice_data["tax_text"] = null; $invoice_data["head_text"] = null; $invoice_data["uid"] = $bill->uid; $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["billing_type"] = "invoice"; $invoice_data["billing_delivery"] = "email"; $invoice_data["total"] = 0; $invoice_data["total_gross"] = 0; $invoice = PreorderBillingInvoice::create($invoice_data); $invoice->startTransaction(); try { if (!$invoice->save()) { var_dump($invoice); $invoice->rollbackTransaction(); die("Error saving Invoice"); } $total_net = 0; $total_gross = 0; $fibu_cost_account = ""; $fibu_revenue_account = ""; foreach($sorted_positions as $position) { //var_dump($position); $this->log->debug(__METHOD__.": count: ".$position->count); $billing_ids = $position->preorder_billings; $bill_id_count += count($billing_ids); unset($position->preorder_billings); unset($position->count); $fibu_cost_account = $position->fibu_cost_account; $fibu_revenue_account = $position->fibu_revenue_account; unset($position->fibu_cost_account); unset($position->fibu_revenue_account); if($position->product_type != "enduser_setup") { if(array_key_exists($netoperator_id, TT_PREORDER_BILLING[$netowner_id]["netoperators"]) && TT_PREORDER_BILLING[$netowner_id]["netoperators"][$netoperator_id]["billing-period"] == "quarterly") { $invoice->head_text = "Abrechnung Q$bill_quarter ".$bill_month->format("Y")."\n$campaign_name\nPOP-Cluster: $cluster_name"; } else { $invoice->head_text = "Abrechnung $bill_month_year_text\n$campaign_name\nPOP-Cluster: $cluster_name"; } } $total_net += $position->price_total; $total_gross += $position->price_gross; if (!$position->save()) { $invoice->rollbackTransaction(); die("Error saving Invoiceposition"); } $position->invoice_id = $invoice->id; if (!$position->save()) { $invoice->rollbackTransaction(); die("Error saving Invoiceposition"); } // add Invoice::id to Bill foreach($billing_ids as $bill_id) { $pbill = new PreorderBilling($bill_id); if (!$pbill->id) { $invoice->rollbackTransaction(); die("Bill for Invoiceposition not found"); } if($position->product_type == "enduser_setup") { if(!$pbill->adb_wohneinheit) { $invoice->rollbackTransaction(); die("Keine Wohneinheit für Preorder " . $pbill->preorder_id . " / bill " . $pbill->id); } $pbill->adb_wohneinheit->enduser_setup_invoice_date = $today->format("Y-m-d"); if(!$pbill->adb_wohneinheit->save()) { $invoice->rollbackTransaction(); die("Error saving enduser_setup_invoice_date"); } } $pbill->invoice_id = $invoice->id; if (!$pbill->save()) { $invoice->rollbackTransaction(); die("error saving invoice_id to bill"); } } } // generate Invoice number $new_num = PreorderBillingInvoice::getNextInvoiceNumber($netowner_id); $invoice->total = $total_net; $invoice->total_gross = $total_gross; $invoice->invoice_number = $new_num; $invoice->invoice_date = $today->format("Y-m-d"); $invoice->fibu_cost_account = $fibu_cost_account; $invoice->fibu_revenue_account = $fibu_revenue_account; // voicenumbers //var_dump($invoice_voicenumbers);exit; if (!$invoice->save()) { $invoice->rollbackTransaction(); die("Error saving Invoice number and date"); } } catch(Exception $e) { if($invoice) { $invoice->rollbackTransaction(); } die("Error saving Invoice!\n"); } // commit transaction $invoice->commitTransaction(); $invoice_count++; if(count($invoice_detail_data)) { // create CSV file //var_dump($invoice_detail_data);exit; $csv = "\u{FEFF}Netzbetreiber;Rechungsnummer;Rechnungsdateum;Netzgebiet;OAID;Extref;Bestelldatum;Periode von;Periode bis;Artikelnummer;Produkt;Anzahl;Preis Netto\n"; foreach ($invoice_detail_data as $detail) { //var_dump($detail); //exit; $csv .= '"'.str_replace(["\r","\n", '"'], [" "," ",'""'], $detail["company"]).'";'; $csv .= '"'.$invoice->invoice_number.'";'; $csv .= '"'.$invoice->invoice_date.'";'; $csv .= '"'.str_replace('"','""',$detail["network_name"]).'";'; $csv .= '"'.$detail["oaid"].'";'; $csv .= '"'.str_replace('"','""',$detail["extref"]).'";'; $csv .= '"'.$detail["order_date"].'";'; $csv .= '"'.$detail["start_date"].'";'; $csv .= '"'.$detail["end_date"].'";'; $csv .= '"'.$detail["article_number"].'";'; $csv .= '"'.$detail["product_name"].'";'; $csv .= round($detail["amount"], 3).';'; $csv .= round($detail["price"], 2)."\n"; } $subfolder = TT_PREORDER_BILLING[$invoice->netowner_id]["subfolder"]."/".$today->format("Y"); $invoice_path = MFUPLOAD_FILE_SAVE_PATH."/$subfolder"; if(!file_exists($invoice_path)) { mkdir($invoice_path, 0777, true); } $filename = $invoice->invoice_number.".csv"; $filepath = "$invoice_path/$filename"; file_put_contents($filepath, $csv); try { $file = FileModel::create([ "name" => $filename, "filename" => $filename, "subfolder" => $subfolder, "store_filename" => $filename, "orig_filename" => $filename, ]); if (!$file->save()) { $this->log->error(__METHOD__ . ": Error saving PDF file"); return false; } } catch(Exception $e) { $this->log->error(__METHOD__ . ": Error saving PDF file"); die("Fehler beim Erzeugen der Rechnungsdetailliste"); } $ifile = PreorderBillingInvoiceFile::create([ "invoice_id" => $invoice->id, "file_id" => $file->id, "name" => $filename, "description" => "" ]); if(!$ifile->save()) { $this->log->error(__METHOD__.": Error saving PDF Invoice Detail CSV"); die("Fehler beim Erzeugen der Rechnungsdetailliste"); } } } $this->log->debug(__METHOD__.": $billing_row_count billing rows | $positions_count positions count | $bill_id_count bill_id count"); $this->layout()->setFlash("$invoice_count Rechnungen erstellt", "success"); $this->redirect("PreorderBillingInvoice"); } public function _sendEmailInvoices($limit = false) { $sent = 0; $defer = 0; $invoices = PreorderBillingInvoice::search(["billing_delivery" => "email", "date_delivered" => false]); foreach($invoices as $invoice) { if($limit && $sent >= $limit) { return ["sent" => $sent, "defer" => $defer]; } /*$pdf = $invoice->pdf; $pdf = false; if(!$pdf || !$pdf->name) { $ifile = PreorderBillingInvoiceFile::createFromInvoice($invoice); if(!$ifile) { $this->layout()->setFlash("Fehler beim PDF erstellen"); $this->redirect("PreorderBillingInvoice"); } $pdf = $ifile->file; } $pdf_file = false; try { $pdf_file = $pdf->getFullPath(); } catch (Exception $e) { $this->log->error(__METHOD__.": File for Invoice ".$invoice->id." not found"); continue; } if(!file_exists($pdf_file)) { $this->log->error(__METHOD__.": Datei ".$pdf->filename." nicht gefunden"); continue; } if($invoice->total == 0) { $this->log->info(__METHOD__.": Skipping ".$invoice->invoice_number." because total is zero"); $invoice->date_delivered = date("U"); $invoice->save(); continue; } */ if(!$invoice->sendByEmail()) { $this->log->warning(__METHOD__.": Error sending ".$invoice->invoice_number." to ".$invoice->email); $invoice->date_delivered = date("U"); $invoice->save(); continue; } $invoice->date_delivered = date("U"); $invoice->save(); $sent++; } return ["sent" => $sent, "defer" => $defer]; } protected function bmdExportPerson() { $netowner_id = $this->me->address_id; $netowner_config = TT_PREORDER_BILLING[$netowner_id]; if(!$netowner_config) { $this->layout()->setFlash("Interner Fehler", "error"); $this->redirect("PreorderBillingInvoice"); } $last_export = new mfConfig("preorder.invoice.bmd.export.person.ts.".$this->me->address_id); $last_export_date = $last_export->value(); $csv = "\u{FEFF}Konto;Vorname;Nachname;Straße;Postleitzahl;Ort;Land;Telefon;Mail;UID\n"; if(!PreorderBillingCustomer::count(["edit>" => $last_export_date])) { $this->layout()->setFlash("Keine neuen Personendaten zum Exportieren vorhanden", "info"); $this->redirect("PreorderBillingInvoice"); } foreach(PreorderBillingCustomer::search(["edit>" => $last_export_date]) as $person) { $konto = $person->fibu_account_number; if($person->company) { $vorname = ""; $nachname = $person->company; } else { $vorname = $person->firstname; $nachname = $person->lastname; } $strasse = $person->street; $plz = $person->zip; $ort = $person->city; $land = $person->country; $telefon = $person->phone; $mail = $person->email; $uid = $person->uid; if($konto) { $csv .= "$konto;$vorname;$nachname;$strasse;$plz;$ort;$land;$telefon;$mail;$uid\n"; } } $subfolder = $netowner_config["subfolder"]; $today = new DateTime(); $csv_path = MFUPLOAD_FILE_SAVE_PATH."/$subfolder"; if(!file_exists($csv_path)) { mkdir($csv_path, 0777, true); } $filename = "thetool-bmd-person-export-".$today->format("Y-m-d_H-i-s").".csv"; $filepath = "$csv_path/$filename"; if(file_put_contents($filepath, $csv) === false) { $this->layout()->setFlash("Fehler beim Erstellen des BMD-Exports", "error"); $this->redirect("PreorderBillingInvoice"); } $file = FileModel::create([ "name" => $filename, "filename" => $filename, "subfolder" => $subfolder, "store_filename" => $filename, "orig_filename" => $filename, ]); $file->save(); // copy csv file to bmd export transfer directory $transfer_path = $netowner_config["bmd-export-transfer-path"]; $transfer_file = "$transfer_path/$filename"; $this->log->debug(__METHOD__.": Copying $filepath to $transfer_file"); if(!copy($filepath, $transfer_file)) { $this->layout()->setFlash("Fehler beim Kopieren des BMD-Exports", "error"); $this->redirect("PreorderBillingInvoice"); } $last_export->value(date("U")); $last_export->save(); $this->layout()->setFlash("Personenexport erfolgreich erstellt", "success"); $this->redirect("PreorderBillingInvoice"); } protected function bmdExport() { $type = $this->request->type; $netowner_id = $this->me->address_id; $netowner_config = TT_PREORDER_BILLING[$netowner_id]; if(!$netowner_config) { $this->layout()->setFlash("Interner Fehler", "error"); $this->redirect("PreorderBillingInvoice"); } if($type != "addresses" && $type != "invoice") { $this->layout()->setFlash("Ungültiger Export-Typ", "error"); $this->redirect("PreorderBillingInvoice"); } if($type == "addresses") { return $this->bmdExportPerson(); } $satzart = 0; $buchsymbol = "ABR"; $buchcode = "1"; $prozent = 20; $steuercode = 1; $csv = "\u{FEFF}satzart;konto;gkonto;belegnr;belegdatum;buchsymbol;buchcode;prozent;steuercode;betrag;steuer;text;kost;kotraeger;kobetrag\n"; $invoices = []; if(!PreorderBillingInvoice::count(["netowner_id" => $netowner_id, "bmd_export_date" => null])) { $this->layout()->setFlash("Keine neuen Rechnungen zum exportieren vorhanden", "info"); $this->redirect("PreorderBillingInvoice"); } foreach(PreorderBillingInvoice::search(["netowner_id" => $netowner_id, "bmd_export_date" => null]) as $invoice) { $invoice->bmd_export_date = date("U"); $invoices[] = $invoice; $kostentraeger = []; foreach($invoice->positions as $position) { if(!array_key_exists($position->article_number, $kostentraeger)) { $kostentraeger[$position->article_number] = 0; } $kostentraeger[$position->article_number] += $position->price_gross; } $invoice_date = new DateTime($invoice->invoice_date); $konto = $invoice->customer_number; $gkonto = $invoice->fibu_revenue_code; $belegnr = $invoice->invoice_number; $belegdatum = $invoice_date->format("d.m.Y"); $betrag = number_format($invoice->total_gross, 2, ",", ""); $steuer = number_format(($invoice->total_gross - $invoice->total) * -1, 2, ",", ""); $text = ($invoice->company ?: $invoice->firstname." ".$invoice->lastname)." $belegnr"; $text = str_replace(["\r","\n", '"'], [" "," ",'""'], $text); $kost = $invoice->fibu_cost_account; if(count($kostentraeger) < 2) { $csv_line = "$satzart;$konto;$gkonto;$belegnr;$belegdatum;$buchsymbol;$buchcode;$prozent;$steuercode;$betrag;$steuer;\"$text\";$kost"; } else { $csv_line = "$satzart;$konto;$gkonto;$belegnr;$belegdatum;$buchsymbol;$buchcode;$prozent;$steuercode;$betrag;$steuer;\"$text\";;"; foreach($kostentraeger as $kotraeger => $kobetrag) { $kobetrag_text = number_format($kobetrag, 2, ",", ""); $csv_line .= "\n1;;;;;;;;;;;;$kost;$kotraeger;$kobetrag_text"; } } $csv .= "$csv_line\n"; } /*echo $csv; exit;*/ $subfolder = $netowner_config["subfolder"]; $today = new DateTime(); $csv_path = MFUPLOAD_FILE_SAVE_PATH."/$subfolder"; if(!file_exists($csv_path)) { mkdir($csv_path, 0777, true); } $filename = "thetool-bmd-invoice-export-".$today->format("Y-m-d_H-i-s").".csv"; $filepath = "$csv_path/$filename"; if(file_put_contents($filepath, $csv) === false) { $this->layout()->setFlash("Fehler beim Erstellen des BMD-Exports", "error"); $this->redirect("PreorderBillingInvoice"); } $file = FileModel::create([ "name" => $filename, "filename" => $filename, "subfolder" => $subfolder, "store_filename" => $filename, "orig_filename" => $filename, ]); $file->save(); // copy csv file to bmd export transfer directory $transfer_path = $netowner_config["bmd-export-transfer-path"]; $transfer_file = "$transfer_path/$filename"; $this->log->debug(__METHOD__.": Copying $filepath to $transfer_file"); if(!copy($filepath, $transfer_file)) { $this->layout()->setFlash("Fehler beim Kopieren des BMD-Exports", "error"); $this->redirect("PreorderBillingInvoice"); } $bmd_export_date = new mfConfig("preorder.invoice.bmd.export.invoice.ts.".$this->me->address_id); $bmd_export_date->value(date("U")); $bmd_export_date->save(); foreach($invoices as $invoice) { $invoice->save(); } $this->layout()->setFlash("Rechnungsexport erfolgreich erstellt", "success"); $this->redirect("PreorderBillingInvoice"); } protected function apiAction() { $do = $this->request->do; $data = []; switch($do) { case "getActiveJobs": $return = $this->getActiveJobsApi(); 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 getActiveJobsApi() { $now = new DateTime("now"); $jobs = []; foreach(InvoiceJobModel::search(["to_date>=" => $now->format("Y-m-d")]) as $job) { if(!str_contains($job->task,"preorder")) continue; $j = $job->data; $j->id = $job->id; $jobs[] = $j; } return ["jobs" => $jobs]; } }