WIP Preorder Billing 2025-03-27

This commit is contained in:
Frank Schubert
2025-03-28 13:43:11 +01:00
parent b8db830214
commit 2fa0d31837
11 changed files with 189 additions and 65 deletions

View File

@@ -13,6 +13,7 @@ class ADBWohneinheitModel {
public $zusatz;
public $bezeichner;
public $nutzung;
public $enduser_setup_invoice_date;
public $rimo_ex_state;
public $rimo_op_state;
public $patch_cluster;

View File

@@ -941,7 +941,7 @@ class AddressdbApicontroller extends mfBaseApicontroller {
//$paid = $unit->enduser_setup_paid;
if(PreorderBilling::getFirst(["adb_wohneinheit_id" => $unit->id, "product_id" => $enduser_setup_product_id, "invoice_id" => false])) {
if($unit->enduser_setup_invoice_date || PreorderBilling::getFirst(["adb_wohneinheit_id" => $unit->id, "product_id" => $enduser_setup_product_id, "invoice_id" => false])) {
$prices_return["enduser_setup_price_net"] = 0;
$prices_return["enduser_setup_price_gross"] = 0;
$prices_return["enduser_setup_info"] = "paid";

View File

@@ -47,13 +47,6 @@ class PreorderBillingController extends mfBaseController {
$pagination['start'] = intval($this->request->s);
}
/*$my_campaigns = [];
$my_networks = $this->me->myNetworks(["netowner", "salespartner"]);
foreach($my_networks as $network) {
foreach(PreordercampaignModel::search(['network_id' => $network->id]) as $campaign) {
if(!array_key_exists($campaign->id, $my_campaigns)) $my_campaigns[] = $campaign;
}
}*/
$my_campaigns = PreordercampaignModel::search(["owner_id" => $this->me->address_id]);
//var_dump($my_network_ids,$my_campaign_ids);exit;
$this->layout()->set("my_campaigns", $my_campaigns);
@@ -275,6 +268,7 @@ class PreorderBillingController extends mfBaseController {
$order_date = $options['order_date'];
$today = $options['today'];
$bill_date = $options['bill_date'];
$latest_bill_date = $options['latest_bill_date'];
$earliest_bill_date = $options['earliest_bill_date'];
$latest_quarter_bill_date = $options["latest_quarter_bill_date"];
@@ -329,6 +323,16 @@ class PreorderBillingController extends mfBaseController {
$status_change_date = new DateTime("@".$preorder->create);
}
if($status_change_date < $earliest_bill_date) {
$this->log->debug(__METHOD__.": Not billing setups for preorder ".$preorder->id." because status change date ".$status_change_date->format("Y-m-d")." is before earliest_bill_date ".$earliest_bill_date->format("Y-m-d"));
return true;
}
if($status_change_date->format("Ymd") > $latest_bill_date->format("Ymd")) {
$this->log->debug(__METHOD__.": Skipping setup for preorder ".$preorder->id." because billing date (status change date) ".$status_change_date->format("Y-m-d")." is after latest_bill_date ".$latest_bill_date->format("Y-m-d"));
return true;
}
$billing_data = [
"netowner_id" => $netowner->id,
"preorder_id" => $preorder->id,
@@ -390,10 +394,11 @@ class PreorderBillingController extends mfBaseController {
$billing_data[$key] = $value;
}
$address = $preorder->adb_hausnummer->strasse->name." ".$preorder->adb_hausnummer->hausnummer." ".($preorder->adb_hausnummer->stiege ? "/".$preorder->adb_hausnummer->stiege : "").", ".$preorder->adb_hausnummer->plz->plz." ".$preorder->adb_hausnummer->ortschaft->name;
$billing_data["preorderbillingcustomer_id"] = $customer->id;
$billing_data["fibu_account_number"] = $customer->fibu_account_number;
$billing_data["product_name"] = "Herstellungsentgelt Glasfaser-Internetanschluss";
$billing_data["product_info"] = "Bestellung vom ".$order_date->format("d.m.Y");
$billing_data["product_info"] = $address;
} elseif($type == "operator_setup") {
$change_to_active = PreorderHistoryModel::getFirstStatusChangeTo($preorder->id, 500);
@@ -408,6 +413,11 @@ class PreorderBillingController extends mfBaseController {
return true;
}
if($status_change_date->format("Ymd") > $latest_bill_date->format("Ymd")) {
$this->log->debug(__METHOD__.": Skipping setup for preorder ".$preorder->id." because billing date (status change date) ".$status_change_date->format("Y-m-d")." is after latest_bill_date ".$latest_bill_date->format("Y-m-d"));
return true;
}
// Netzbetreiber Setup Gebühr
$billing_data["product_name"] = "Brereitstellungsentgelt ".$status_change_date->format("m/Y");
$billing_data["owner_id"] = $netoperator->id;
@@ -449,6 +459,7 @@ class PreorderBillingController extends mfBaseController {
$order_date = $options['order_date'];
$today = $options['today'];
$bill_date = $options['bill_date'];
$latest_bill_date = $options['latest_bill_date'];
$earliest_bill_date = $options['earliest_bill_date'];
$latest_quarter_bill_date = $options["latest_quarter_bill_date"];
@@ -470,7 +481,7 @@ class PreorderBillingController extends mfBaseController {
if($preorder->status->code >= 899) {
$this->log->debug(__METHOD__.": Preorder ".$preorder->id." / ".$preorder->oaid." is cancelled");
// TODO is cancelled, so determine if refund is necessary
// TODO: is cancelled, so determine if refund is necessary
return true;
}
@@ -502,6 +513,11 @@ class PreorderBillingController extends mfBaseController {
$earliest_bill_date = $status_change_date;
}
if($status_change_date->format("Ymd") > $latest_bill_date->format("Ymd")) {
$this->log->debug(__METHOD__.": Skipping setup for preorder ".$preorder->id." because billing date (status change date) ".$status_change_date->format("Y-m-d")." is after latest_bill_date ".$latest_bill_date->format("Y-m-d"));
return true;
}
$first_bill_date = clone $status_change_date;

View File

@@ -1,5 +1,9 @@
<?php
use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use chillerlan\QRCode\Output\QROutputInterface;
class PreorderBillingInvoice extends mfBaseModel {
protected $forcestr = ["company", "zip", "email", "phone"];
private $positions;
@@ -34,6 +38,8 @@ class PreorderBillingInvoice extends mfBaseModel {
$invoice_date = new DateTime("@1");
}
$conf = TT_PREORDER_BILLING[$this->netowner_id];
$filename = "";
$positions = $this->getProperty("positions");
@@ -48,13 +54,14 @@ class PreorderBillingInvoice extends mfBaseModel {
$pdf_vars = [
"invoice" => $this,
"vat" => $vat,
"qrcode" => $this->getSepaQRCode($this->netowner_id, $invoice_number, round($this->total_gross, 2)),
];
$me = new User();
$me->loadMe();
// Replace placeholders in header
$headerHtml = file_get_contents(BASEDIR . "/Layout/default/PreorderBillingInvoice/PDF_HEADER.html");
$headerHtml = file_get_contents(BASEDIR . "/Layout/default/PreorderBillingInvoice/PDF_HEADER-".$this->netowner_id.".html");
$headerHtml = str_replace("{{ basedir }}", BASEDIR, $headerHtml);
$headerHtml = str_replace("{{ addressLine_1 }}", $this->company ? $this->company : "", $headerHtml);
$headerHtml = str_replace("{{ addressLine_2 }}", $this->firstname . " " . $this->lastname, $headerHtml);
@@ -75,23 +82,59 @@ class PreorderBillingInvoice extends mfBaseModel {
// Replace placeholders in header
$footerHtml = file_get_contents(BASEDIR . "/Layout/default/PreorderBillingInvoice/PDF_FOOTER.html");
$footerHtml = str_replace("{{ bank_iban }}", "AT85 1200 0100 3986 5885", $footerHtml);
$footerHtml = str_replace("{{ bank_bic }}", "", $footerHtml);
$footerHtml = file_get_contents(BASEDIR . "/Layout/default/PreorderBillingInvoice/PDF_FOOTER-".$this->netowner_id.".html");
$footerHtml = str_replace("{{ bank_iban }}", $conf["bank-account-iban"], $footerHtml);
$footerHtml = str_replace("{{ bank_bic }}", $conf["bank-account-bic"], $footerHtml);
$footerFile = BASEDIR . "/var/temp/preorderbillinginvoice_footer-" . date("U") . "-" . rand(1000, 9999) . ".html";
file_put_contents($footerFile, $footerHtml);
$pdf = new PdfForm("PreorderBillingInvoice/PDF_MAIN", $pdf_vars);
$wkhtmltopdfArgs = "--margin-top 10mm --header-spacing 90 --header-html '$headerFile' --footer-html '$footerFile'";
$pdf = new PdfForm("PreorderBillingInvoice/PDF_MAIN-".$this->netowner_id, $pdf_vars);
$wkhtmltopdfArgs = "--margin-top 2mm --header-spacing 90 --header-html '$headerFile' --footer-html '$footerFile'";
$filename = $pdf->render($wkhtmltopdfArgs);
if($conf["invoice-pdf-bg-file"]) {
// run pdftk with $filename as input and $conf["invoice-pdf-bg-file"] as output
// to add background to pdf
$bg_file = $conf["invoice-pdf-bg-file"];
$temp_file_name = tempnam(TEMP_DIR, "invoice-pdftk").".pdf";
$pdftk_cmd = PDFTK_BIN_PATH." '$filename' background '$bg_file' output '$temp_file_name'";
$this->log->debug(__METHOD__." $pdftk_cmd");
shell_exec($pdftk_cmd);
$filename = $temp_file_name;
}
return $filename;
}
public function getSepaQRCode($netowner_id, $invoice_number, $amount) {
if(!$netowner_id) return "";
$conf = TT_PREORDER_BILLING[$netowner_id];
$IBAN = str_replace(" ", "", $conf["bank-account-iban"]);
$BIC = str_replace(" ", "", $conf["bank-account-bic"]);
$Owner = $conf["bank-account-owner"];
$epc = "BCD
001
1
SCT
$BIC
$Owner
$IBAN
EUR$amount
$invoice_number
RML Infrastruktur GmbH";
return (new QRCode)->render($epc);
}
public function getProperty($name) {

View File

@@ -168,6 +168,20 @@ class PreorderBillingInvoiceController extends mfBaseController {
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;
@@ -191,6 +205,8 @@ class PreorderBillingInvoiceController extends mfBaseController {
}
$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 = [];
@@ -397,8 +413,12 @@ class PreorderBillingInvoiceController extends mfBaseController {
unset($position->count);
if($position->product_id != 2) {
$invoice->head_text = "Entgelte für Netzgebiet $campaign_name";
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;