PreorderBilling

This commit is contained in:
Frank Schubert
2025-03-31 13:50:49 +02:00
parent 21655c5ff4
commit 17405c8c5d
17 changed files with 704 additions and 43 deletions
@@ -12,7 +12,7 @@ class PreorderBillingInvoiceController extends mfBaseController {
$this->me = $me;
$this->layout()->set("me", $me);
if(!$me->can(["preorderbilling", "preorderbillingReadonly"])) {
if(!$me->can(["preorderbilling", "preorderbillingReadonly"]) && (!defined("MFBASE_BYPASS_LOGIN") || !MFBASE_BYPASS_LOGIN)) {
$this->redirect("Dashboard");
}
}
@@ -54,6 +54,10 @@ class PreorderBillingInvoiceController extends mfBaseController {
$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);
}
private function getPreparedFilter($filter) {
@@ -165,6 +169,47 @@ class PreorderBillingInvoiceController extends mfBaseController {
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();
@@ -266,6 +311,7 @@ class PreorderBillingInvoiceController extends mfBaseController {
"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"),
@@ -286,11 +332,13 @@ class PreorderBillingInvoiceController extends mfBaseController {
$position_data["product_type"] = $bill->product_type;
$position_data["article_number"] = $bill->article_number;
$position_data["product_name"] = $bill->product_name;
$position_data["product_info"] = $bill->product_info;
$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] = [];
@@ -327,6 +375,9 @@ class PreorderBillingInvoiceController extends mfBaseController {
$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++;
@@ -340,6 +391,8 @@ class PreorderBillingInvoiceController extends mfBaseController {
$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;
@@ -365,14 +418,14 @@ class PreorderBillingInvoiceController extends mfBaseController {
//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_cost_account"] = TT_PREORDER_BILLING[$netowner_id]["fibu-cost-code"];
$invoice_data["fibu_revenue_account"] = TT_PREORDER_BILLING[$netowner_id]["fibu-revenue-code"];
$invoice_data["fibu_tax_code"] = 1;
$invoice_data["tax_text"] = null;
$invoice_data["head_text"] = null;
@@ -403,7 +456,8 @@ class PreorderBillingInvoiceController extends mfBaseController {
$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);
@@ -412,6 +466,11 @@ class PreorderBillingInvoiceController extends mfBaseController {
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") {
@@ -469,6 +528,8 @@ class PreorderBillingInvoiceController extends mfBaseController {
$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;
@@ -494,7 +555,7 @@ class PreorderBillingInvoiceController extends mfBaseController {
if(count($invoice_detail_data)) {
// create CSV file
//var_dump($invoice_detail_data);exit;
$csv = "\u{FEFF}Netzbetreiber;Rechungsnummer;Rechnungsdateum;Netzgebiet;OAID;Bestelldatum;Periode von;Periode bis;Artikelnummer;Produkt;Anzahl;Preis Netto\n";
$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;
@@ -504,6 +565,7 @@ class PreorderBillingInvoiceController extends mfBaseController {
$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"].'";';
@@ -559,4 +621,94 @@ class PreorderBillingInvoiceController extends mfBaseController {
$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 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];
}
}